From gitlab at gitlab.haskell.org Sat Oct 1 01:17:58 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 30 Sep 2022 21:17:58 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Scrub various partiality involving empty lists. Message-ID: <6337954648174_2c975742cc316012727b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 7ffb11a1 by Alexis King at 2022-09-30T21:17:32-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 2de0bcf0 by Bodigrim at 2022-09-30T21:17:35-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 19 changed files: - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Utils/Misc.hs - rts/Continuation.c - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs Changes: ===================================== compiler/GHC/Cmm/Node.hs ===================================== @@ -45,6 +45,7 @@ import GHC.Cmm.Dataflow.Block import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dataflow.Label +import Data.Foldable (toList) import Data.Functor.Classes (liftCompare) import Data.Maybe import Data.List (tails,sortBy) @@ -247,7 +248,7 @@ pprNode platform node = pp_node <+> pp_debug (cases, mbdef) = switchTargetsFallThrough ids ppCase (is,l) = hsep [ text "case" - , commafy $ map integer is + , commafy $ toList $ fmap integer is , text ": goto" , ppr l <> semi ] ===================================== compiler/GHC/Cmm/Switch.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Cmm.Switch ( createSwitchPlan, ) where -import GHC.Prelude +import GHC.Prelude hiding (head) import GHC.Utils.Outputable import GHC.Driver.Backend @@ -20,7 +20,7 @@ import GHC.Utils.Panic import GHC.Cmm.Dataflow.Label (Label) import Data.Maybe -import qualified Data.List.NonEmpty as NE +import Data.List.NonEmpty (NonEmpty (..), groupWith, head) import qualified Data.Map as M -- Note [Cmm Switches, the general plan] @@ -200,11 +200,11 @@ switchTargetsToList (SwitchTargets _ _ mbdef branches) -- | Groups cases with equal targets, suitable for pretty-printing to a -- c-like switch statement with fall-through semantics. -switchTargetsFallThrough :: SwitchTargets -> ([([Integer], Label)], Maybe Label) +switchTargetsFallThrough :: SwitchTargets -> ([(NonEmpty Integer, Label)], Maybe Label) switchTargetsFallThrough (SwitchTargets _ _ mbdef branches) = (groups, mbdef) where - groups = map (\xs -> (map fst (NE.toList xs), snd (NE.head xs))) $ - NE.groupWith snd $ + groups = fmap (\xs -> (fmap fst xs, snd (head xs))) $ + groupWith snd $ M.toList branches -- | Custom equality helper, needed for "GHC.Cmm.CommonBlockElim" ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -78,7 +78,7 @@ module GHC.CmmToAsm ) where -import GHC.Prelude +import GHC.Prelude hiding (head) import qualified GHC.CmmToAsm.X86 as X86 import qualified GHC.CmmToAsm.PPC as PPC @@ -140,7 +140,7 @@ import GHC.Data.Stream (Stream) import qualified GHC.Data.Stream as Stream import Data.List (sortBy) -import qualified Data.List.NonEmpty as NE +import Data.List.NonEmpty (groupAllWith, head) import Data.Maybe import Data.Ord ( comparing ) import Control.Monad @@ -776,8 +776,8 @@ makeImportsDoc config imports | needImportedSymbols config = vcat $ (pprGotDeclaration config :) $ - fmap ( pprImportedSymbol config . fst . NE.head) $ - NE.groupAllWith snd $ + fmap (pprImportedSymbol config . fst . head) $ + groupAllWith snd $ map doPpr $ imps | otherwise ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -59,6 +59,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as BS import Data.Char import Data.List (intersperse) +import Data.List.NonEmpty (NonEmpty (..)) import Data.Map (Map) import qualified Data.Map as Map import GHC.Float @@ -347,7 +348,7 @@ pprSwitch platform e ids rep = typeWidth (cmmExprType platform e) -- fall through case - caseify (ix:ixs, ident) = vcat (map do_fallthrough ixs) $$ final_branch ix + caseify (ix:|ixs, ident) = vcat (map do_fallthrough ixs) $$ final_branch ix where do_fallthrough ix = hsep [ text "case" , pprHexVal platform ix rep <> colon , @@ -357,8 +358,6 @@ pprSwitch platform e ids hsep [ text "case" , pprHexVal platform ix rep <> colon , text "goto" , (pprBlockId ident) <> semi ] - caseify (_ , _ ) = panic "pprSwitch: switch with no cases!" - def | Just l <- mbdef = text "default: goto" <+> pprBlockId l <> semi | otherwise = text "default: __builtin_unreachable();" ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -11,7 +11,7 @@ module GHC.CmmToLlvm ) where -import GHC.Prelude +import GHC.Prelude hiding ( head ) import GHC.Llvm import GHC.CmmToLlvm.Base @@ -37,6 +37,7 @@ import GHC.Utils.Logger import qualified GHC.Data.Stream as Stream import Control.Monad ( when, forM_ ) +import Data.List.NonEmpty ( head ) import Data.Maybe ( fromMaybe, catMaybes ) import System.IO @@ -68,7 +69,7 @@ llvmCodeGen logger cfg h cmm_stream "System LLVM version: " <> text (llvmVersionStr ver) $$ "We will try though..." let isS390X = platformArch (llvmCgPlatform cfg) == ArchS390X - let major_ver = head . llvmVersionList $ ver + let major_ver = head . llvmVersionNE $ ver when (isS390X && major_ver < 10 && doWarn) $ putMsg logger $ "Warning: For s390x the GHC calling convention is only supported since LLVM version 10." <+> "You are using LLVM version: " <> text (llvmVersionStr ver) ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -63,6 +63,8 @@ import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts import GHC.Core.Unfold +import Data.List.NonEmpty ( NonEmpty (..) ) + {- ************************************************************************ * * @@ -1201,7 +1203,7 @@ specCase env scrut' case_bndr [Alt con args rhs] | -- See Note [Floating dictionaries out of cases] interestingDict scrut' (idType case_bndr) , not (isDeadBinder case_bndr && null sc_args') - = do { (case_bndr_flt : sc_args_flt) <- mapM clone_me (case_bndr' : sc_args') + = do { case_bndr_flt :| sc_args_flt <- mapM clone_me (case_bndr' :| sc_args') ; let case_bndr_flt' = case_bndr_flt `addDictUnfolding` scrut' scrut_bind = mkDB (NonRec case_bndr_flt scrut') ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1200,12 +1200,9 @@ cpeApp top_env expr arg_ty' = cpSubstTy env arg_ty CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats ss' rt_ticks req_depth + -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - ss' - | null ss = [] - | otherwise = tail ss CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make ===================================== compiler/GHC/Data/BooleanFormula.hs ===================================== @@ -16,9 +16,10 @@ module GHC.Data.BooleanFormula ( pprBooleanFormula, pprBooleanFormulaNice ) where -import GHC.Prelude +import GHC.Prelude hiding ( init, last ) import Data.List ( nub, intersperse ) +import Data.List.NonEmpty ( NonEmpty (..), init, last ) import Data.Data import GHC.Utils.Monad @@ -227,7 +228,7 @@ pprBooleanFormulaNice = pprBooleanFormula' pprVar pprAnd pprOr 0 pprAnd p = cparen (p > 1) . pprAnd' pprAnd' [] = empty pprAnd' [x,y] = x <+> text "and" <+> y - pprAnd' xs@(_:_) = fsep (punctuate comma (init xs)) <> text ", and" <+> last xs + pprAnd' (x:xs) = fsep (punctuate comma (init (x:|xs))) <> text ", and" <+> last (x:|xs) pprOr p xs = cparen (p > 1) $ text "either" <+> sep (intersperse (text "or") xs) instance (OutputableBndr a) => Outputable (BooleanFormula a) where ===================================== compiler/GHC/Data/OrdList.hs ===================================== @@ -28,6 +28,8 @@ import GHC.Utils.Misc (strictMap) import GHC.Utils.Outputable import GHC.Utils.Panic +import Data.List.NonEmpty (NonEmpty(..)) +import qualified Data.List.NonEmpty as NE import qualified Data.Semigroup as Semigroup infixl 5 `appOL` @@ -37,7 +39,7 @@ infixr 5 `consOL` data OrdList a = None | One a - | Many [a] -- Invariant: non-empty + | Many (NonEmpty a) | Cons a (OrdList a) | Snoc (OrdList a) a | Two (OrdList a) -- Invariant: non-empty @@ -100,8 +102,12 @@ pattern ConsOL :: a -> OrdList a -> OrdList a pattern ConsOL x xs <- (viewCons -> VJust x xs) where ConsOL x xs = consOL x xs {-# COMPLETE NilOL, ConsOL #-} + viewCons :: OrdList a -> VMaybe a (OrdList a) -viewCons (One a) = VJust a NilOL +viewCons None = VNothing +viewCons (One a) = VJust a NilOL +viewCons (Many (a :| [])) = VJust a NilOL +viewCons (Many (a :| b : bs)) = VJust a (Many (b :| bs)) viewCons (Cons a as) = VJust a as viewCons (Snoc as a) = case viewCons as of VJust a' as' -> VJust a' (Snoc as' a) @@ -109,15 +115,18 @@ viewCons (Snoc as a) = case viewCons as of viewCons (Two as1 as2) = case viewCons as1 of VJust a' as1' -> VJust a' (Two as1' as2) VNothing -> viewCons as2 -viewCons _ = VNothing pattern SnocOL :: OrdList a -> a -> OrdList a pattern SnocOL xs x <- (viewSnoc -> VJust xs x) where SnocOL xs x = snocOL xs x {-# COMPLETE NilOL, SnocOL #-} + viewSnoc :: OrdList a -> VMaybe (OrdList a) a -viewSnoc (One a) = VJust NilOL a -viewSnoc (Many (reverse -> a:as)) = VJust (Many (reverse as)) a +viewSnoc None = VNothing +viewSnoc (One a) = VJust NilOL a +viewSnoc (Many as) = (`VJust` NE.last as) $ case NE.init as of + [] -> NilOL + b : bs -> Many (b :| bs) viewSnoc (Snoc as a) = VJust as a viewSnoc (Cons a as) = case viewSnoc as of VJust as' a' -> VJust (Cons a as') a' @@ -125,18 +134,17 @@ viewSnoc (Cons a as) = case viewSnoc as of viewSnoc (Two as1 as2) = case viewSnoc as2 of VJust as2' a' -> VJust (Two as1 as2') a' VNothing -> viewSnoc as1 -viewSnoc _ = VNothing headOL None = panic "headOL" headOL (One a) = a -headOL (Many as) = head as +headOL (Many as) = NE.head as headOL (Cons a _) = a headOL (Snoc as _) = headOL as headOL (Two as _) = headOL as lastOL None = panic "lastOL" lastOL (One a) = a -lastOL (Many as) = last as +lastOL (Many as) = NE.last as lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as @@ -164,7 +172,7 @@ fromOL a = go a [] go (Cons a b) acc = a : go b acc go (Snoc a b) acc = go a (b:acc) go (Two a b) acc = go a (go b acc) - go (Many xs) acc = xs ++ acc + go (Many xs) acc = NE.toList xs ++ acc fromOLReverse :: OrdList a -> [a] fromOLReverse a = go a [] @@ -175,7 +183,7 @@ fromOLReverse a = go a [] go (Cons a b) acc = go b (a : acc) go (Snoc a b) acc = b : go a acc go (Two a b) acc = go b (go a acc) - go (Many xs) acc = reverse xs ++ acc + go (Many xs) acc = reverse (NE.toList xs) ++ acc mapOL :: (a -> b) -> OrdList a -> OrdList b mapOL = fmap @@ -192,7 +200,9 @@ mapOL' f (Snoc xs x) = let !x1 = f x mapOL' f (Two b1 b2) = let !b1' = mapOL' f b1 !b2' = mapOL' f b2 in Two b1' b2' -mapOL' f (Many xs) = Many $! strictMap f xs +mapOL' f (Many (x :| xs)) = let !x1 = f x + !xs1 = strictMap f xs + in Many (x1 :| xs1) foldrOL :: (a->b->b) -> b -> OrdList a -> b foldrOL _ z None = z @@ -214,7 +224,7 @@ foldlOL k z (Many xs) = foldl' k z xs toOL :: [a] -> OrdList a toOL [] = None toOL [x] = One x -toOL xs = Many xs +toOL (x : xs) = Many (x :| xs) reverseOL :: OrdList a -> OrdList a reverseOL None = None @@ -222,7 +232,7 @@ reverseOL (One x) = One x reverseOL (Cons a b) = Snoc (reverseOL b) a reverseOL (Snoc a b) = Cons b (reverseOL a) reverseOL (Two a b) = Two (reverseOL b) (reverseOL a) -reverseOL (Many xs) = Many (reverse xs) +reverseOL (Many xs) = Many (NE.reverse xs) -- | Compare not only the values but also the structure of two lists strictlyEqOL :: Eq a => OrdList a -> OrdList a -> Bool ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -1779,9 +1779,9 @@ getGccSearchDirectory logger dflags key = do find :: String -> String -> String find r x = let lst = lines x val = filter (r `isPrefixOf`) lst - in if null val - then [] - else case break (=='=') (head val) of + in case val of + [] -> [] + x:_ -> case break (=='=') x of (_ , []) -> [] (_, (_:xs)) -> xs ===================================== compiler/GHC/Llvm/Types.hs ===================================== @@ -181,7 +181,7 @@ getLitType :: LlvmLit -> LlvmType getLitType (LMIntLit _ t) = t getLitType (LMFloatLit _ t) = t getLitType (LMVectorLit []) = panic "getLitType" -getLitType (LMVectorLit ls) = LMVector (length ls) (getLitType (head ls)) +getLitType (LMVectorLit ls@(l:_)) = LMVector (length ls) (getLitType l) getLitType (LMNullLit t) = t getLitType (LMUndefLit t) = t ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2513,10 +2513,10 @@ mkRecConstrOrUpdate _ (L _ (HsVar _ (L l c))) _lrec (fbinds,dd) anns | isRdrDataCon c = do let (fs, ps) = partitionEithers fbinds - if not (null ps) - then addFatalError $ mkPlainErrorMsgEnvelope (getLocA (head ps)) $ - PsErrOverloadedRecordDotInvalid - else return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns) + case ps of + p:_ -> addFatalError $ mkPlainErrorMsgEnvelope (getLocA p) $ + PsErrOverloadedRecordDotInvalid + _ -> return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns) mkRecConstrOrUpdate overloaded_update exp _ (fs,dd) anns | Just dd_loc <- dd = addFatalError $ mkPlainErrorMsgEnvelope dd_loc $ PsErrDotsInRecordUpdate @@ -2546,15 +2546,13 @@ mkRdrRecordUpd overloaded_on exp@(L loc _) fbinds anns = do [ L l lbl | L _ (HsFieldBind _ (L l lbl) _ _) <- fs' , isQual . rdrNameAmbiguousFieldOcc $ lbl ] - if not $ null qualifiedFields - then - addFatalError $ mkPlainErrorMsgEnvelope (getLocA (head qualifiedFields)) $ + case qualifiedFields of + qf:_ -> addFatalError $ mkPlainErrorMsgEnvelope (getLocA qf) $ PsErrOverloadedRecordUpdateNoQualifiedFields - else -- This is a RecordDotSyntax update. - return RecordUpd { - rupd_ext = anns - , rupd_expr = exp - , rupd_flds = Right (toProjUpdates fbinds) } + _ -> return RecordUpd -- This is a RecordDotSyntax update. + { rupd_ext = anns + , rupd_expr = exp + , rupd_flds = Right (toProjUpdates fbinds) } where toProjUpdates :: [Fbind (HsExpr GhcPs)] -> [LHsRecUpdProj GhcPs] toProjUpdates = map (\case { Right p -> p; Left f -> recFieldToProjUpdate f }) ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -178,6 +178,8 @@ import qualified GHC.Data.BooleanFormula as BF import Data.Functor.Classes ( liftEq ) import Data.List ( sortBy, sort ) +import Data.List.NonEmpty ( NonEmpty (..) ) +import qualified Data.List.NonEmpty as NE import Data.Ord import Data.Data ( Data ) import qualified Data.Set as S @@ -2223,10 +2225,8 @@ type Plan = TcM PlanResult -- | Try the plans in order. If one fails (by raising an exn), try the next. -- If one succeeds, take it. -runPlans :: [Plan] -> TcM PlanResult -runPlans [] = panic "runPlans" -runPlans [p] = p -runPlans (p:ps) = tryTcDiscardingErrs (runPlans ps) p +runPlans :: NonEmpty Plan -> Plan +runPlans = foldr1 (flip tryTcDiscardingErrs) -- | Typecheck (and 'lift') a stmt entered by the user in GHCi into the -- GHCi 'environment'. @@ -2298,30 +2298,31 @@ tcUserStmt (L loc (BodyStmt _ expr _ _)) -- See Note [GHCi Plans] - it_plans = [ + it_plans = -- Plan A do { stuff@([it_id], _) <- tcGhciStmts [bind_stmt, print_it] ; it_ty <- zonkTcType (idType it_id) - ; when (isUnitTy $ it_ty) failM - ; return stuff }, + ; when (isUnitTy it_ty) failM + ; return stuff } :| -- Plan B; a naked bind statement - tcGhciStmts [bind_stmt], + [ tcGhciStmts [bind_stmt] -- Plan C; check that the let-binding is typeable all by itself. -- If not, fail; if so, try to print it. -- The two-step process avoids getting two errors: one from -- the expression itself, and one from the 'print it' part -- This two-step story is very clunky, alas - do { _ <- checkNoErrs (tcGhciStmts [let_stmt]) + , do { _ <- checkNoErrs (tcGhciStmts [let_stmt]) --- checkNoErrs defeats the error recovery of let-bindings ; tcGhciStmts [let_stmt, print_it] } ] -- Plans where we don't bind "it" - no_it_plans = [ - tcGhciStmts [no_it_a] , - tcGhciStmts [no_it_b] , - tcGhciStmts [no_it_c] ] + no_it_plans = + tcGhciStmts [no_it_a] :| + tcGhciStmts [no_it_b] : + tcGhciStmts [no_it_c] : + [] ; generate_it <- goptM Opt_NoIt @@ -2413,13 +2414,13 @@ tcUserStmt rdr_stmt@(L loc _) ; let print_result_plan | opt_pr_flag -- The flag says "print result" , [v] <- collectLStmtBinders CollNoDictBinders gi_stmt -- One binder - = [mk_print_result_plan gi_stmt v] - | otherwise = [] + = Just $ mk_print_result_plan gi_stmt v + | otherwise = Nothing -- The plans are: -- [stmt; print v] if one binder and not v::() -- [stmt] otherwise - ; plan <- runPlans (print_result_plan ++ [tcGhciStmts [gi_stmt]]) + ; plan <- runPlans $ maybe id (NE.<|) print_result_plan $ NE.singleton $ tcGhciStmts [gi_stmt] ; return (plan, fix_env) } where mk_print_result_plan stmt v ===================================== compiler/GHC/Types/Name/Reader.hs ===================================== @@ -825,12 +825,12 @@ pprGlobalRdrEnv locals_only env remove_locals gres | locals_only = filter isLocalGRE gres | otherwise = gres pp [] = empty - pp gres = hang (ppr occ + pp gres@(gre:_) = hang (ppr occ <+> parens (text "unique" <+> ppr (getUnique occ)) <> colon) 2 (vcat (map ppr gres)) where - occ = nameOccName (greMangledName (head gres)) + occ = nameOccName (greMangledName gre) lookupGlobalRdrEnv :: GlobalRdrEnv -> OccName -> [GlobalRdrElt] lookupGlobalRdrEnv env occ_name = case lookupOccEnv env occ_name of ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -699,8 +699,8 @@ getUnitDbRefs cfg = do let base_conf_refs = case e_pkg_path of Left _ -> system_conf_refs Right path - | not (null path) && isSearchPathSeparator (last path) - -> map PkgDbPath (splitSearchPath (init path)) ++ system_conf_refs + | Just (xs, x) <- snocView path, isSearchPathSeparator x + -> map PkgDbPath (splitSearchPath xs) ++ system_conf_refs | otherwise -> map PkgDbPath (splitSearchPath path) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -124,7 +124,7 @@ module GHC.Utils.Misc ( HasDebugCallStack, ) where -import GHC.Prelude +import GHC.Prelude hiding ( last ) import GHC.Utils.Exception import GHC.Utils.Panic.Plain @@ -133,7 +133,7 @@ import GHC.Utils.Fingerprint import Data.Data import qualified Data.List as List -import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.List.NonEmpty ( NonEmpty(..), last ) import GHC.Exts import GHC.Stack (HasCallStack) @@ -750,7 +750,7 @@ last2 = List.foldl' (\(_,x2) x -> (x2,x)) (partialError,partialError) lastMaybe :: [a] -> Maybe a lastMaybe [] = Nothing -lastMaybe xs = Just $ last xs +lastMaybe (x:xs) = Just $ last (x:|xs) -- | @onJust x m f@ applies f to the value inside the Just or returns the default. onJust :: b -> Maybe a -> (a->b) -> b @@ -1293,9 +1293,9 @@ withAtomicRename targetFile f = do -- string is returned in the first component (and the second one is just -- empty). splitLongestPrefix :: String -> (Char -> Bool) -> (String,String) -splitLongestPrefix str pred - | null r_pre = (str, []) - | otherwise = (reverse (tail r_pre), reverse r_suf) +splitLongestPrefix str pred = case r_pre of + [] -> (str, []) + _:r_pre' -> (reverse r_pre', reverse r_suf) -- 'tail' drops the char satisfying 'pred' where (r_suf, r_pre) = break pred (reverse str) ===================================== rts/Continuation.c ===================================== @@ -472,12 +472,14 @@ StgClosure *captureContinuationAndAbort(Capability *cap, StgTSO *tso, StgPromptT stack = pop_stack_chunk(cap, tso); for (StgWord i = 0; i < full_chunks; i++) { - memcpy(cont_stack, stack->sp, stack->stack_size * sizeof(StgWord)); - cont_stack += stack->stack_size; + const size_t chunk_words = stack->stack + stack->stack_size - stack->sp - sizeofW(StgUnderflowFrame); + memcpy(cont_stack, stack->sp, chunk_words * sizeof(StgWord)); + cont_stack += chunk_words; stack = pop_stack_chunk(cap, tso); } memcpy(cont_stack, stack->sp, last_chunk_words * sizeof(StgWord)); + cont_stack += last_chunk_words; stack->sp += last_chunk_words; } ===================================== testsuite/tests/rts/continuations/all.T ===================================== @@ -2,3 +2,4 @@ test('cont_simple_shift', [extra_files(['ContIO.hs'])], multimod_compile_and_run test('cont_exn_masking', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_exn_masking', '']) test('cont_missing_prompt_err', [extra_files(['ContIO.hs']), exit_code(1)], multimod_compile_and_run, ['cont_missing_prompt_err', '']) test('cont_nondet_handler', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_nondet_handler', '']) +test('cont_stack_overflow', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_stack_overflow', '-with-rtsopts "-ki1k -kc2k -kb256"']) ===================================== testsuite/tests/rts/continuations/cont_stack_overflow.hs ===================================== @@ -0,0 +1,32 @@ +-- This test is run with RTS options that instruct GHC to use a small stack +-- chunk size (2k), which ensures this test exercises multi-chunk continuation +-- captures and restores. + +import Control.Monad (unless) +import ContIO + +data Answer + = Done Int + | Yield (IO Int -> IO Answer) + +getAnswer :: Answer -> Int +getAnswer (Done n) = n +getAnswer (Yield _) = error "getAnswer" + +main :: IO () +main = do + tag <- newPromptTag + Yield k <- prompt tag $ + Done <$> buildBigCont tag 6000 + n <- getAnswer <$> k (getAnswer <$> k (pure 0)) + unless (n == 36006000) $ + error $ "produced wrong value: " ++ show n + +buildBigCont :: PromptTag Answer + -> Int + -> IO Int +buildBigCont tag size + | size <= 0 = control0 tag (\k -> pure (Yield k)) + | otherwise = do + n <- buildBigCont tag (size - 1) + pure $! n + size View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6b36624262c1956f7fd2ba8b50b5fe14cd9e83e9...2de0bcf0672eda4fc8f701ae53bfecc8524bde48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6b36624262c1956f7fd2ba8b50b5fe14cd9e83e9...2de0bcf0672eda4fc8f701ae53bfecc8524bde48 You're receiving 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 Oct 1 04:37:57 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Oct 2022 00:37:57 -0400 Subject: [Git][ghc/ghc][master] Fix a bug in continuation capture across multiple stack chunks Message-ID: <6337c425b9579_2c975742cc31601293015@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 3 changed files: - rts/Continuation.c - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs Changes: ===================================== rts/Continuation.c ===================================== @@ -472,12 +472,14 @@ StgClosure *captureContinuationAndAbort(Capability *cap, StgTSO *tso, StgPromptT stack = pop_stack_chunk(cap, tso); for (StgWord i = 0; i < full_chunks; i++) { - memcpy(cont_stack, stack->sp, stack->stack_size * sizeof(StgWord)); - cont_stack += stack->stack_size; + const size_t chunk_words = stack->stack + stack->stack_size - stack->sp - sizeofW(StgUnderflowFrame); + memcpy(cont_stack, stack->sp, chunk_words * sizeof(StgWord)); + cont_stack += chunk_words; stack = pop_stack_chunk(cap, tso); } memcpy(cont_stack, stack->sp, last_chunk_words * sizeof(StgWord)); + cont_stack += last_chunk_words; stack->sp += last_chunk_words; } ===================================== testsuite/tests/rts/continuations/all.T ===================================== @@ -2,3 +2,4 @@ test('cont_simple_shift', [extra_files(['ContIO.hs'])], multimod_compile_and_run test('cont_exn_masking', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_exn_masking', '']) test('cont_missing_prompt_err', [extra_files(['ContIO.hs']), exit_code(1)], multimod_compile_and_run, ['cont_missing_prompt_err', '']) test('cont_nondet_handler', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_nondet_handler', '']) +test('cont_stack_overflow', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_stack_overflow', '-with-rtsopts "-ki1k -kc2k -kb256"']) ===================================== testsuite/tests/rts/continuations/cont_stack_overflow.hs ===================================== @@ -0,0 +1,32 @@ +-- This test is run with RTS options that instruct GHC to use a small stack +-- chunk size (2k), which ensures this test exercises multi-chunk continuation +-- captures and restores. + +import Control.Monad (unless) +import ContIO + +data Answer + = Done Int + | Yield (IO Int -> IO Answer) + +getAnswer :: Answer -> Int +getAnswer (Done n) = n +getAnswer (Yield _) = error "getAnswer" + +main :: IO () +main = do + tag <- newPromptTag + Yield k <- prompt tag $ + Done <$> buildBigCont tag 6000 + n <- getAnswer <$> k (getAnswer <$> k (pure 0)) + unless (n == 36006000) $ + error $ "produced wrong value: " ++ show n + +buildBigCont :: PromptTag Answer + -> Int + -> IO Int +buildBigCont tag size + | size <= 0 = control0 tag (\k -> pure (Yield k)) + | otherwise = do + n <- buildBigCont tag (size - 1) + pure $! n + size View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/95ead839fd39e0aa781dca9b1268b243c29ccaeb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/95ead839fd39e0aa781dca9b1268b243c29ccaeb You're receiving 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 Oct 1 04:38:37 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Oct 2022 00:38:37 -0400 Subject: [Git][ghc/ghc][master] Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc Message-ID: <6337c44d6903b_2c975742bd2a1c1296635@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 1 changed file: - compiler/GHC/Data/OrdList.hs Changes: ===================================== compiler/GHC/Data/OrdList.hs ===================================== @@ -28,6 +28,8 @@ import GHC.Utils.Misc (strictMap) import GHC.Utils.Outputable import GHC.Utils.Panic +import Data.List.NonEmpty (NonEmpty(..)) +import qualified Data.List.NonEmpty as NE import qualified Data.Semigroup as Semigroup infixl 5 `appOL` @@ -37,7 +39,7 @@ infixr 5 `consOL` data OrdList a = None | One a - | Many [a] -- Invariant: non-empty + | Many (NonEmpty a) | Cons a (OrdList a) | Snoc (OrdList a) a | Two (OrdList a) -- Invariant: non-empty @@ -100,8 +102,12 @@ pattern ConsOL :: a -> OrdList a -> OrdList a pattern ConsOL x xs <- (viewCons -> VJust x xs) where ConsOL x xs = consOL x xs {-# COMPLETE NilOL, ConsOL #-} + viewCons :: OrdList a -> VMaybe a (OrdList a) -viewCons (One a) = VJust a NilOL +viewCons None = VNothing +viewCons (One a) = VJust a NilOL +viewCons (Many (a :| [])) = VJust a NilOL +viewCons (Many (a :| b : bs)) = VJust a (Many (b :| bs)) viewCons (Cons a as) = VJust a as viewCons (Snoc as a) = case viewCons as of VJust a' as' -> VJust a' (Snoc as' a) @@ -109,15 +115,18 @@ viewCons (Snoc as a) = case viewCons as of viewCons (Two as1 as2) = case viewCons as1 of VJust a' as1' -> VJust a' (Two as1' as2) VNothing -> viewCons as2 -viewCons _ = VNothing pattern SnocOL :: OrdList a -> a -> OrdList a pattern SnocOL xs x <- (viewSnoc -> VJust xs x) where SnocOL xs x = snocOL xs x {-# COMPLETE NilOL, SnocOL #-} + viewSnoc :: OrdList a -> VMaybe (OrdList a) a -viewSnoc (One a) = VJust NilOL a -viewSnoc (Many (reverse -> a:as)) = VJust (Many (reverse as)) a +viewSnoc None = VNothing +viewSnoc (One a) = VJust NilOL a +viewSnoc (Many as) = (`VJust` NE.last as) $ case NE.init as of + [] -> NilOL + b : bs -> Many (b :| bs) viewSnoc (Snoc as a) = VJust as a viewSnoc (Cons a as) = case viewSnoc as of VJust as' a' -> VJust (Cons a as') a' @@ -125,18 +134,17 @@ viewSnoc (Cons a as) = case viewSnoc as of viewSnoc (Two as1 as2) = case viewSnoc as2 of VJust as2' a' -> VJust (Two as1 as2') a' VNothing -> viewSnoc as1 -viewSnoc _ = VNothing headOL None = panic "headOL" headOL (One a) = a -headOL (Many as) = head as +headOL (Many as) = NE.head as headOL (Cons a _) = a headOL (Snoc as _) = headOL as headOL (Two as _) = headOL as lastOL None = panic "lastOL" lastOL (One a) = a -lastOL (Many as) = last as +lastOL (Many as) = NE.last as lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as @@ -164,7 +172,7 @@ fromOL a = go a [] go (Cons a b) acc = a : go b acc go (Snoc a b) acc = go a (b:acc) go (Two a b) acc = go a (go b acc) - go (Many xs) acc = xs ++ acc + go (Many xs) acc = NE.toList xs ++ acc fromOLReverse :: OrdList a -> [a] fromOLReverse a = go a [] @@ -175,7 +183,7 @@ fromOLReverse a = go a [] go (Cons a b) acc = go b (a : acc) go (Snoc a b) acc = b : go a acc go (Two a b) acc = go b (go a acc) - go (Many xs) acc = reverse xs ++ acc + go (Many xs) acc = reverse (NE.toList xs) ++ acc mapOL :: (a -> b) -> OrdList a -> OrdList b mapOL = fmap @@ -192,7 +200,9 @@ mapOL' f (Snoc xs x) = let !x1 = f x mapOL' f (Two b1 b2) = let !b1' = mapOL' f b1 !b2' = mapOL' f b2 in Two b1' b2' -mapOL' f (Many xs) = Many $! strictMap f xs +mapOL' f (Many (x :| xs)) = let !x1 = f x + !xs1 = strictMap f xs + in Many (x1 :| xs1) foldrOL :: (a->b->b) -> b -> OrdList a -> b foldrOL _ z None = z @@ -214,7 +224,7 @@ foldlOL k z (Many xs) = foldl' k z xs toOL :: [a] -> OrdList a toOL [] = None toOL [x] = One x -toOL xs = Many xs +toOL (x : xs) = Many (x :| xs) reverseOL :: OrdList a -> OrdList a reverseOL None = None @@ -222,7 +232,7 @@ reverseOL (One x) = One x reverseOL (Cons a b) = Snoc (reverseOL b) a reverseOL (Snoc a b) = Cons b (reverseOL a) reverseOL (Two a b) = Two (reverseOL b) (reverseOL a) -reverseOL (Many xs) = Many (reverse xs) +reverseOL (Many xs) = Many (NE.reverse xs) -- | Compare not only the values but also the structure of two lists strictlyEqOL :: Eq a => OrdList a -> OrdList a -> Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2209665273135644f1b52470ea2cb53169f2ef91 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2209665273135644f1b52470ea2cb53169f2ef91 You're receiving 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 Oct 1 09:22:51 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Sat, 01 Oct 2022 05:22:51 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22227 Message-ID: <633806ebd2d05_2c975742bcfe5c1307264@gitlab.mail> Sebastian Graf pushed new branch wip/T22227 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22227 You're receiving 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 Oct 1 11:22:59 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Sat, 01 Oct 2022 07:22:59 -0400 Subject: [Git][ghc/ghc][wip/T22227] Loopification in OccurAnal Message-ID: <6338231380a0b_2c97572ed3bc781323781@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: 63c2f0df by Sebastian Graf at 2022-10-01T13:22:51+02:00 Loopification in OccurAnal - - - - - 5 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - + testsuite/tests/simplCore/should_compile/T22227.hs - + testsuite/tests/simplCore/should_compile/T22227.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/sigs/T5075.hs Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Utils.Trace import GHC.Builtin.Names( runRWKey ) import GHC.Unit.Module( Module ) -import Data.List (mapAccumL, mapAccumR) +import Data.List (mapAccumL, mapAccumR, find) {- ************************************************************************ @@ -856,15 +856,31 @@ occAnalRec !_ lvl (AcyclicSCC (ND { nd_bndr = bndr, nd_rhs = rhs -- See Note [Recursive bindings: the grand plan] -- See Note [Loop breaking] occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails body_uds binds) - | not (any (`usedIn` body_uds) bndrs) -- NB: look at body_uds, not total_uds + | null used_bndrs = WithUsageDetails body_uds binds -- See Note [Dead code] + | [loop_entry] <- used_bndrs + , let orig_occ = lookupDetails body_uds loop_entry + , NoTailCallInfo <- tailCallInfo orig_occ +--- , case orig_occ of OneOcc{occ_in_lam=NotInsideLam}->False; _ -> True + , let unadj_uds = foldr (andUDs . nd_uds) emptyDetails details_s + , decideJoinPointHood lvl unadj_uds bndrs + , AlwaysTailCalled arity <- tailCallInfo $ lookupDetails unadj_uds loop_entry + , Just loop_nds <- find ((== loop_entry) . nd_bndr) details_s + , (!lam_bndrs,_) <- collectNBinders arity (nd_rhs loop_nds) + , let !loop_body_uds = mkOneOcc loop_entry IsInteresting arity + , WithUsageDetails new_rhs_uds loop_binds <- occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails loop_body_uds []) + , (body_uds',loop_entry') <- tagNonRecBinder lvl body_uds loop_entry + , let new_bind = NonRec loop_entry' (mkLams lam_bndrs (mkLets loop_binds (mkVarApps (Var loop_entry') lam_bndrs))) + = WithUsageDetails (markAllNonTail new_rhs_uds `andUDs` body_uds') (new_bind : binds) + | otherwise -- At this point we always build a single Rec = -- pprTrace "occAnalRec" (ppr loop_breaker_nodes) WithUsageDetails final_uds (Rec pairs : binds) where bndrs = map nd_bndr details_s + used_bndrs = filter (`usedIn` body_uds) bndrs -- NB: look at body_uds, not total_uds all_simple = all nd_simple details_s ------------------------------ ===================================== testsuite/tests/simplCore/should_compile/T22227.hs ===================================== @@ -0,0 +1,39 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +module Unboxed (test) where + +import GHC.Exts +import GHC.IO + +data Step s a = Yield a s | Done + +uninitialised = undefined + +test :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +test off n oldArr = runRW# $ \s0 -> + case newArray# n uninitialised s0 + of { (# s1, newArr #) -> + let + step' i + | isTrue# (i >=# n) = Done + | otherwise = + let (# D# x #) = indexArray# oldArr (off +# i) in + if isTrue# (x >## 10.0##) + then Yield (D# x) (I# (i +# 1#)) + else step' (i +# 1#) + loop i j s2 = + case step' i of + Yield x (I# s') -> + case writeArray# newArr j (x + 1) s2 + of { s3 -> + loop s' (j +# 1#) s3 + } + Done -> + case unsafeFreezeArray# newArr s2 + of { (# s3, out #) -> + (# 0#, j, out #) + } + in + loop 0# 0# s1 + } ===================================== testsuite/tests/simplCore/should_compile/T22227.stderr ===================================== @@ -0,0 +1,326 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 213, types: 211, coercions: 4, joins: 5/5} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl_rUP :: Addr# +[GblId, Unf=OtherCon []] +lvl_rUP = "undefined"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl1_rUQ :: [Char] +[GblId] +lvl1_rUQ = unpackCString# lvl_rUP + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule4 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl2_rUR :: [Char] +[GblId] +lvl2_rUR = unpackCString# Unboxed.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$trModule2 = "Unboxed"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl3_rUS :: [Char] +[GblId] +lvl3_rUS = unpackCString# Unboxed.$trModule2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl4_rUT :: Addr# +[GblId, Unf=OtherCon []] +lvl4_rUT = "T22227.hs"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl5_rUU :: [Char] +[GblId] +lvl5_rUU = unpackCString# lvl4_rUT + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl6_rUV :: Int +[GblId, Unf=OtherCon []] +lvl6_rUV = GHC.Types.I# 11# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl7_rUW :: Int +[GblId, Unf=OtherCon []] +lvl7_rUW = GHC.Types.I# 17# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl8_rUX :: Int +[GblId, Unf=OtherCon []] +lvl8_rUX = GHC.Types.I# 26# + +-- RHS size: {terms: 8, types: 0, coercions: 0, joins: 0/0} +lvl9_rUY :: GHC.Stack.Types.SrcLoc +[GblId, Unf=OtherCon []] +lvl9_rUY + = GHC.Stack.Types.SrcLoc + lvl2_rUR lvl3_rUS lvl5_rUU lvl6_rUV lvl7_rUW lvl6_rUV lvl8_rUX + +-- RHS size: {terms: 4, types: 0, coercions: 0, joins: 0/0} +lvl10_rUZ :: GHC.Stack.Types.CallStack +[GblId, Unf=OtherCon []] +lvl10_rUZ + = GHC.Stack.Types.PushCallStack + lvl1_rUQ lvl9_rUY GHC.Stack.Types.EmptyCallStack + +-- RHS size: {terms: 3, types: 3, coercions: 4, joins: 0/0} +uninitialised :: forall {a}. a +[GblId, Str=b, Cpr=b] +uninitialised + = \ (@a_aCz) -> + undefined + @LiftedRep + @a_aCz + (lvl10_rUZ + `cast` (Sym (GHC.Classes.N:IP[0] + <"callStack">_N _N) + :: GHC.Stack.Types.CallStack + ~R# (?callStack::GHC.Stack.Types.CallStack))) + +-- RHS size: {terms: 90, types: 151, coercions: 0, joins: 5/5} +test + :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +[GblId, + Arity=3, + Str=, + Cpr=1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0 0] 137 0}] +test + = \ (off_axL :: Int#) + (n_axM :: Int#) + (oldArr_axN :: Array# Double) -> + runRW# + @('TupleRep '[ 'IntRep, 'IntRep, UnliftedRep]) + @(# Int#, Int#, Array# Double #) + (\ (s_sSR [OS=OneShot] :: State# RealWorld) -> + case newArray# + @'Lifted @Double @RealWorld n_axM (uninitialised @Double) s_sSR + of + { (# ipv_sSS, ipv1_sST #) -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L,L)))] + :: Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (j_ay1 [OS=OneShot] :: Int#) + (s2_ay2 [OS=OneShot] :: State# RealWorld) + = case unsafeFreezeArray# + @'Lifted @RealWorld @Double ipv1_sST s2_ay2 + of + { (# ipv2_sT8, ipv3_sT9 #) -> + (# 0#, j_ay1, ipv3_sT9 #) + } } in + joinrec { + loop_sTq [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,L)))] + :: Int# + -> Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + loop_sTq (i_ay0 :: Int#) + (j_ay1 :: Int#) + (s2_ay2 :: State# RealWorld) + = join { + exit1_X4 [Dmd=LC(S,C(1,!P(L,L,L)))] + :: Int# -> Double# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit1_X4 (i1_X1 [OS=OneShot] :: Int#) + (x_aPv [OS=OneShot] :: Double#) + = case writeArray# + @'Lifted + @RealWorld + @Double + ipv1_sST + j_ay1 + (GHC.Types.D# (+## x_aPv 1.0##)) + s2_ay2 + of s3_aAH + { __DEFAULT -> + jump loop_sTq (+# i1_X1 1#) (+# j_ay1 1#) s3_aAH + } } in + join { + $j_sTM [Dmd=L!P(L,L,L)] :: (# Int#, Int#, Array# Double #) + [LclId[JoinId(0)(Nothing)]] + $j_sTM = jump exit_X0 j_ay1 s2_ay2 } in + joinrec { + step'_sTs [Occ=LoopBreaker, Dmd=SC(S,!P(L,L,L))] + :: Int# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(1)(Nothing)], Arity=1, Str=, Unf=OtherCon []] + step'_sTs (i1_X1 :: Int#) + = case >=# i1_X1 n_axM of { + __DEFAULT -> + case indexArray# @'Lifted @Double oldArr_axN (+# off_axL i1_X1) of + { (# ipv2_sSW #) -> + case ipv2_sSW of { D# x_aPv -> + case >## x_aPv 10.0## of { + __DEFAULT -> jump step'_sTs (+# i1_X1 1#); + 1# -> jump exit1_X4 i1_X1 x_aPv + } + } + }; + 1# -> jump $j_sTM + }; } in + jump step'_sTs i_ay0; } in + jump loop_sTq 0# 0# ipv_sSS + }) + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule3 = GHC.Types.TrNameS Unboxed.$trModule4 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule1 = GHC.Types.TrNameS Unboxed.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule + = GHC.Types.Module Unboxed.$trModule3 Unboxed.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep_rV0 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep_rV0 = GHC.Types.KindRepVar 1# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep1_rV1 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep1_rV1 = GHC.Types.KindRepVar 0# + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$tcStep2 = "Step"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep1 = GHC.Types.TrNameS Unboxed.$tcStep2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep + = GHC.Types.TyCon + 9345441458829744813##64 + 15928240119707513573##64 + Unboxed.$trModule + Unboxed.$tcStep1 + 0# + GHC.Types.krep$*->*->* + +-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +$krep2_rV2 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep2_rV2 + = GHC.Types.: + @GHC.Types.KindRep $krep_rV0 (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep3_rV3 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep3_rV3 = GHC.Types.: @GHC.Types.KindRep $krep1_rV1 $krep2_rV2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Done1 + = GHC.Types.KindRepTyConApp Unboxed.$tcStep $krep3_rV3 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Done3 = "'Done"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done2 = GHC.Types.TrNameS Unboxed.$tc'Done3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done + = GHC.Types.TyCon + 12965714903249458155##64 + 720712123234526269##64 + Unboxed.$trModule + Unboxed.$tc'Done2 + 2# + Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep4_rV4 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep4_rV4 = GHC.Types.KindRepFun $krep1_rV1 Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Yield1 = GHC.Types.KindRepFun $krep_rV0 $krep4_rV4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Yield3 = "'Yield"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield2 = GHC.Types.TrNameS Unboxed.$tc'Yield3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield + = GHC.Types.TyCon + 16456917800457442198##64 + 7357499335137316903##64 + Unboxed.$trModule + Unboxed.$tc'Yield2 + 2# + Unboxed.$tc'Yield1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -428,5 +428,7 @@ test('T21763', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) -test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# step should be loopified and turned into a join point +test('T22227', [grep_errmsg(r'jump \S*step') ], compile, ['-O -ddump-simpl']) ===================================== testsuite/tests/stranal/sigs/T5075.hs ===================================== @@ -17,10 +17,10 @@ g x y = go x True -> Just x False -> go (x*2) --- Here, go is not a join point, but still should be WW'd for Just. --- Unfortunately, CPR can't see that (+?) returns Just, so h won't get the CPR --- property. It probably could by only considering the @Just@ case of the --- inlined (+?). +-- Here, go is not a join point (call-site loopification doesn't trigger because +-- it is marked NOINLINE), but still should be WW'd for Just. Unfortunately, +-- CPR can't see that (+?) returns Just, so h won't get the CPR property. It +-- probably could by only considering the @Just@ case of the inlined (+?). h :: Int -> Maybe Int h x = go x +? go (x+1) where @@ -29,3 +29,4 @@ h x = go x +? go (x+1) go z | z > 10 = Just (x + z) | otherwise = go (z*2) + {-# NOINLINE go #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63c2f0df143bbee2804327f055d8e3fba7509307 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63c2f0df143bbee2804327f055d8e3fba7509307 You're receiving 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 Oct 1 11:57:25 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Sat, 01 Oct 2022 07:57:25 -0400 Subject: [Git][ghc/ghc][wip/T22227] 2 commits: Loopification in OccurAnal (#22227, #14068) Message-ID: <63382b2579ff2_2c97572ed3bc78133031f@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: 313531a1 by Sebastian Graf at 2022-10-01T13:56:34+02:00 Loopification in OccurAnal (#22227, #14068) - - - - - 86ef6fa3 by Sebastian Graf at 2022-10-01T13:56:45+02:00 DmdAnal: Look through DataConWrappers (#22241) - - - - - 10 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - testsuite/tests/linear/should_compile/LinearLetRec.hs - + testsuite/tests/simplCore/should_compile/T22227.hs - + testsuite/tests/simplCore/should_compile/T22227.stderr - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/T5075.hs - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -932,6 +932,9 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Utils.Trace import GHC.Builtin.Names( runRWKey ) import GHC.Unit.Module( Module ) -import Data.List (mapAccumL, mapAccumR) +import Data.List (mapAccumL, mapAccumR, find) {- ************************************************************************ @@ -856,15 +856,31 @@ occAnalRec !_ lvl (AcyclicSCC (ND { nd_bndr = bndr, nd_rhs = rhs -- See Note [Recursive bindings: the grand plan] -- See Note [Loop breaking] occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails body_uds binds) - | not (any (`usedIn` body_uds) bndrs) -- NB: look at body_uds, not total_uds + | null used_bndrs = WithUsageDetails body_uds binds -- See Note [Dead code] + | [loop_entry] <- used_bndrs + , let orig_occ = lookupDetails body_uds loop_entry + , NoTailCallInfo <- tailCallInfo orig_occ +--- , case orig_occ of OneOcc{occ_in_lam=NotInsideLam}->False; _ -> True + , let unadj_uds = foldr (andUDs . nd_uds) emptyDetails details_s + , decideJoinPointHood lvl unadj_uds bndrs + , AlwaysTailCalled arity <- tailCallInfo $ lookupDetails unadj_uds loop_entry + , Just loop_nds <- find ((== loop_entry) . nd_bndr) details_s + , (!lam_bndrs,_) <- collectNBinders arity (nd_rhs loop_nds) + , let !loop_body_uds = mkOneOcc loop_entry IsInteresting arity + , WithUsageDetails new_rhs_uds loop_binds <- occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails loop_body_uds []) + , (body_uds',loop_entry') <- tagNonRecBinder lvl body_uds loop_entry + , let new_bind = NonRec loop_entry' (mkLams lam_bndrs (mkLets loop_binds (mkVarApps (Var loop_entry') lam_bndrs))) + = WithUsageDetails (markAllNonTail new_rhs_uds `andUDs` body_uds') (new_bind : binds) + | otherwise -- At this point we always build a single Rec = -- pprTrace "occAnalRec" (ppr loop_breaker_nodes) WithUsageDetails final_uds (Rec pairs : binds) where bndrs = map nd_bndr details_s + used_bndrs = filter (`usedIn` body_uds) bndrs -- NB: look at body_uds, not total_uds all_simple = all nd_simple details_s ------------------------------ ===================================== testsuite/tests/linear/should_compile/LinearLetRec.hs ===================================== @@ -8,4 +8,13 @@ extendOrigNameCache _ _ = Name initNameCache :: Int -> [Name] -> NameCache initNameCache us names - = NameCache us (foldl extendOrigNameCache Name names) + = NameCache us (go Name names) + where + -- go will become a join point once $WNameCache inlines. That join point + -- has a nullary exit join point with a problematic linearity. + -- The NOINLINE makes sure that call-site loopification doesn't turn go into + -- a joinrec before $WNameCache inlines + go acc [] = acc + -- head names `seq` ... so that `go` doesn't float to top-level + go acc (n:ns) = head names `seq` go (extendOrigNameCache acc n) ns + {-# NOINLINE go #-} -- see above comment ===================================== testsuite/tests/simplCore/should_compile/T22227.hs ===================================== @@ -0,0 +1,39 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +module Unboxed (test) where + +import GHC.Exts +import GHC.IO + +data Step s a = Yield a s | Done + +uninitialised = undefined + +test :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +test off n oldArr = runRW# $ \s0 -> + case newArray# n uninitialised s0 + of { (# s1, newArr #) -> + let + step' i + | isTrue# (i >=# n) = Done + | otherwise = + let (# D# x #) = indexArray# oldArr (off +# i) in + if isTrue# (x >## 10.0##) + then Yield (D# x) (I# (i +# 1#)) + else step' (i +# 1#) + loop i j s2 = + case step' i of + Yield x (I# s') -> + case writeArray# newArr j (x + 1) s2 + of { s3 -> + loop s' (j +# 1#) s3 + } + Done -> + case unsafeFreezeArray# newArr s2 + of { (# s3, out #) -> + (# 0#, j, out #) + } + in + loop 0# 0# s1 + } ===================================== testsuite/tests/simplCore/should_compile/T22227.stderr ===================================== @@ -0,0 +1,326 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 213, types: 211, coercions: 4, joins: 5/5} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl_rUP :: Addr# +[GblId, Unf=OtherCon []] +lvl_rUP = "undefined"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl1_rUQ :: [Char] +[GblId] +lvl1_rUQ = unpackCString# lvl_rUP + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule4 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl2_rUR :: [Char] +[GblId] +lvl2_rUR = unpackCString# Unboxed.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$trModule2 = "Unboxed"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl3_rUS :: [Char] +[GblId] +lvl3_rUS = unpackCString# Unboxed.$trModule2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl4_rUT :: Addr# +[GblId, Unf=OtherCon []] +lvl4_rUT = "T22227.hs"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl5_rUU :: [Char] +[GblId] +lvl5_rUU = unpackCString# lvl4_rUT + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl6_rUV :: Int +[GblId, Unf=OtherCon []] +lvl6_rUV = GHC.Types.I# 11# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl7_rUW :: Int +[GblId, Unf=OtherCon []] +lvl7_rUW = GHC.Types.I# 17# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl8_rUX :: Int +[GblId, Unf=OtherCon []] +lvl8_rUX = GHC.Types.I# 26# + +-- RHS size: {terms: 8, types: 0, coercions: 0, joins: 0/0} +lvl9_rUY :: GHC.Stack.Types.SrcLoc +[GblId, Unf=OtherCon []] +lvl9_rUY + = GHC.Stack.Types.SrcLoc + lvl2_rUR lvl3_rUS lvl5_rUU lvl6_rUV lvl7_rUW lvl6_rUV lvl8_rUX + +-- RHS size: {terms: 4, types: 0, coercions: 0, joins: 0/0} +lvl10_rUZ :: GHC.Stack.Types.CallStack +[GblId, Unf=OtherCon []] +lvl10_rUZ + = GHC.Stack.Types.PushCallStack + lvl1_rUQ lvl9_rUY GHC.Stack.Types.EmptyCallStack + +-- RHS size: {terms: 3, types: 3, coercions: 4, joins: 0/0} +uninitialised :: forall {a}. a +[GblId, Str=b, Cpr=b] +uninitialised + = \ (@a_aCz) -> + undefined + @LiftedRep + @a_aCz + (lvl10_rUZ + `cast` (Sym (GHC.Classes.N:IP[0] + <"callStack">_N _N) + :: GHC.Stack.Types.CallStack + ~R# (?callStack::GHC.Stack.Types.CallStack))) + +-- RHS size: {terms: 90, types: 151, coercions: 0, joins: 5/5} +test + :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +[GblId, + Arity=3, + Str=, + Cpr=1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0 0] 137 0}] +test + = \ (off_axL :: Int#) + (n_axM :: Int#) + (oldArr_axN :: Array# Double) -> + runRW# + @('TupleRep '[ 'IntRep, 'IntRep, UnliftedRep]) + @(# Int#, Int#, Array# Double #) + (\ (s_sSR [OS=OneShot] :: State# RealWorld) -> + case newArray# + @'Lifted @Double @RealWorld n_axM (uninitialised @Double) s_sSR + of + { (# ipv_sSS, ipv1_sST #) -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L,L)))] + :: Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (j_ay1 [OS=OneShot] :: Int#) + (s2_ay2 [OS=OneShot] :: State# RealWorld) + = case unsafeFreezeArray# + @'Lifted @RealWorld @Double ipv1_sST s2_ay2 + of + { (# ipv2_sT8, ipv3_sT9 #) -> + (# 0#, j_ay1, ipv3_sT9 #) + } } in + joinrec { + loop_sTq [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,L)))] + :: Int# + -> Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + loop_sTq (i_ay0 :: Int#) + (j_ay1 :: Int#) + (s2_ay2 :: State# RealWorld) + = join { + exit1_X4 [Dmd=LC(S,C(1,!P(L,L,L)))] + :: Int# -> Double# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit1_X4 (i1_X1 [OS=OneShot] :: Int#) + (x_aPv [OS=OneShot] :: Double#) + = case writeArray# + @'Lifted + @RealWorld + @Double + ipv1_sST + j_ay1 + (GHC.Types.D# (+## x_aPv 1.0##)) + s2_ay2 + of s3_aAH + { __DEFAULT -> + jump loop_sTq (+# i1_X1 1#) (+# j_ay1 1#) s3_aAH + } } in + join { + $j_sTM [Dmd=L!P(L,L,L)] :: (# Int#, Int#, Array# Double #) + [LclId[JoinId(0)(Nothing)]] + $j_sTM = jump exit_X0 j_ay1 s2_ay2 } in + joinrec { + step'_sTs [Occ=LoopBreaker, Dmd=SC(S,!P(L,L,L))] + :: Int# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(1)(Nothing)], Arity=1, Str=, Unf=OtherCon []] + step'_sTs (i1_X1 :: Int#) + = case >=# i1_X1 n_axM of { + __DEFAULT -> + case indexArray# @'Lifted @Double oldArr_axN (+# off_axL i1_X1) of + { (# ipv2_sSW #) -> + case ipv2_sSW of { D# x_aPv -> + case >## x_aPv 10.0## of { + __DEFAULT -> jump step'_sTs (+# i1_X1 1#); + 1# -> jump exit1_X4 i1_X1 x_aPv + } + } + }; + 1# -> jump $j_sTM + }; } in + jump step'_sTs i_ay0; } in + jump loop_sTq 0# 0# ipv_sSS + }) + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule3 = GHC.Types.TrNameS Unboxed.$trModule4 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule1 = GHC.Types.TrNameS Unboxed.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule + = GHC.Types.Module Unboxed.$trModule3 Unboxed.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep_rV0 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep_rV0 = GHC.Types.KindRepVar 1# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep1_rV1 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep1_rV1 = GHC.Types.KindRepVar 0# + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$tcStep2 = "Step"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep1 = GHC.Types.TrNameS Unboxed.$tcStep2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep + = GHC.Types.TyCon + 9345441458829744813##64 + 15928240119707513573##64 + Unboxed.$trModule + Unboxed.$tcStep1 + 0# + GHC.Types.krep$*->*->* + +-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +$krep2_rV2 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep2_rV2 + = GHC.Types.: + @GHC.Types.KindRep $krep_rV0 (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep3_rV3 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep3_rV3 = GHC.Types.: @GHC.Types.KindRep $krep1_rV1 $krep2_rV2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Done1 + = GHC.Types.KindRepTyConApp Unboxed.$tcStep $krep3_rV3 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Done3 = "'Done"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done2 = GHC.Types.TrNameS Unboxed.$tc'Done3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done + = GHC.Types.TyCon + 12965714903249458155##64 + 720712123234526269##64 + Unboxed.$trModule + Unboxed.$tc'Done2 + 2# + Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep4_rV4 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep4_rV4 = GHC.Types.KindRepFun $krep1_rV1 Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Yield1 = GHC.Types.KindRepFun $krep_rV0 $krep4_rV4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Yield3 = "'Yield"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield2 = GHC.Types.TrNameS Unboxed.$tc'Yield3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield + = GHC.Types.TyCon + 16456917800457442198##64 + 7357499335137316903##64 + Unboxed.$trModule + Unboxed.$tc'Yield2 + 2# + Unboxed.$tc'Yield1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -428,5 +428,7 @@ test('T21763', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) -test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# step should be loopified and turned into a join point +test('T22227', [grep_errmsg(r'jump \S*step') ], compile, ['-O -ddump-simpl']) ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,12 @@ +module T22241 where + +data D = D !Int + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,15 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> + + + +==================== Cpr signatures ==================== +T22241.f: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> + + ===================================== testsuite/tests/stranal/sigs/T5075.hs ===================================== @@ -17,10 +17,10 @@ g x y = go x True -> Just x False -> go (x*2) --- Here, go is not a join point, but still should be WW'd for Just. --- Unfortunately, CPR can't see that (+?) returns Just, so h won't get the CPR --- property. It probably could by only considering the @Just@ case of the --- inlined (+?). +-- Here, go is not a join point (call-site loopification doesn't trigger because +-- it is marked NOINLINE), but still should be WW'd for Just. Unfortunately, +-- CPR can't see that (+?) returns Just, so h won't get the CPR property. It +-- probably could by only considering the @Just@ case of the inlined (+?). h :: Int -> Maybe Int h x = go x +? go (x+1) where @@ -29,3 +29,4 @@ h x = go x +? go (x+1) go z | z > 10 = Just (x + z) | otherwise = go (z*2) + {-# NOINLINE go #-} ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -36,3 +36,4 @@ test('T21119', normal, compile, ['']) test('T21717', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63c2f0df143bbee2804327f055d8e3fba7509307...86ef6fa321608b146b28e37cdf0db82635573355 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63c2f0df143bbee2804327f055d8e3fba7509307...86ef6fa321608b146b28e37cdf0db82635573355 You're receiving 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 Oct 1 17:16:46 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Sat, 01 Oct 2022 13:16:46 -0400 Subject: [Git][ghc/ghc][wip/ghc-fat-interface] 20 commits: Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) Message-ID: <633875fe3dc23_2c975742bd2a1c13412e@gitlab.mail> Matthew Pickering pushed to branch wip/ghc-fat-interface at Glasgow Haskell Compiler / GHC Commits: aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 55bc9d04 by Matthew Pickering at 2022-10-01T18:15:41+01:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - 45dbb86e by Matthew Pickering at 2022-10-01T18:16:20+01:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 813e95d3 by Matthew Pickering at 2022-10-01T18:16:22+01:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - 30 changed files: - .gitlab/ci.sh - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/Stats.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.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/a106484bc29672138539381c112e17301b41e9fc...813e95d3477e16b1537f8941d4e007b2339c4da4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a106484bc29672138539381c112e17301b41e9fc...813e95d3477e16b1537f8941d4e007b2339c4da4 You're receiving 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 Oct 2 08:19:09 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Sun, 02 Oct 2022 04:19:09 -0400 Subject: [Git][ghc/ghc][wip/T22227] 2 commits: Loopification in OccurAnal (#22227, #14068) Message-ID: <6339497de7247_2c97572ed3bc7813726b@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: 1813c9ba by Sebastian Graf at 2022-10-02T10:18:57+02:00 Loopification in OccurAnal (#22227, #14068) - - - - - 6ec3df64 by Sebastian Graf at 2022-10-02T10:18:57+02:00 DmdAnal: Look through DataConWrappers (#22241) - - - - - 10 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - testsuite/tests/linear/should_compile/LinearLetRec.hs - + testsuite/tests/simplCore/should_compile/T22227.hs - + testsuite/tests/simplCore/should_compile/T22227.stderr - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/T5075.hs - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -932,6 +932,9 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Utils.Trace import GHC.Builtin.Names( runRWKey ) import GHC.Unit.Module( Module ) -import Data.List (mapAccumL, mapAccumR) +import Data.List (mapAccumL, mapAccumR, find) {- ************************************************************************ @@ -856,15 +856,30 @@ occAnalRec !_ lvl (AcyclicSCC (ND { nd_bndr = bndr, nd_rhs = rhs -- See Note [Recursive bindings: the grand plan] -- See Note [Loop breaking] occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails body_uds binds) - | not (any (`usedIn` body_uds) bndrs) -- NB: look at body_uds, not total_uds + | null used_bndrs = WithUsageDetails body_uds binds -- See Note [Dead code] + | [loop_entry] <- used_bndrs + , not (isJoinId loop_entry) + , NoTailCallInfo <- tailCallInfo $ lookupDetails body_uds loop_entry -- otherwise turn it into a joinrec rightaway + , let unadj_uds = foldr (andUDs . nd_uds) emptyDetails details_s + , decideJoinPointHood lvl unadj_uds bndrs + , AlwaysTailCalled arity <- tailCallInfo $ lookupDetails unadj_uds loop_entry + , Just loop_nds <- find ((== loop_entry) . nd_bndr) details_s + , (!lam_bndrs,_) <- collectNBinders arity (nd_rhs loop_nds) + , let !loop_body_uds = mkOneOcc loop_entry IsInteresting arity + , WithUsageDetails new_rhs_uds loop_binds <- occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails loop_body_uds []) + , (body_uds',loop_entry') <- tagNonRecBinder lvl body_uds loop_entry + , let new_bind = NonRec loop_entry' (mkLams lam_bndrs (mkLets loop_binds (mkVarApps (Var loop_entry') lam_bndrs))) + = WithUsageDetails (markAllNonTail new_rhs_uds `andUDs` body_uds') (new_bind : binds) + | otherwise -- At this point we always build a single Rec = -- pprTrace "occAnalRec" (ppr loop_breaker_nodes) WithUsageDetails final_uds (Rec pairs : binds) where bndrs = map nd_bndr details_s + used_bndrs = filter (`usedIn` body_uds) bndrs -- NB: look at body_uds, not total_uds all_simple = all nd_simple details_s ------------------------------ ===================================== testsuite/tests/linear/should_compile/LinearLetRec.hs ===================================== @@ -8,4 +8,13 @@ extendOrigNameCache _ _ = Name initNameCache :: Int -> [Name] -> NameCache initNameCache us names - = NameCache us (foldl extendOrigNameCache Name names) + = NameCache us (go Name names) + where + -- go will become a join point once $WNameCache inlines. That join point + -- has a nullary exit join point with a problematic linearity. + -- The NOINLINE makes sure that call-site loopification doesn't turn go into + -- a joinrec before $WNameCache inlines + go acc [] = acc + -- head names `seq` ... so that `go` doesn't float to top-level + go acc (n:ns) = head names `seq` go (extendOrigNameCache acc n) ns + {-# NOINLINE go #-} -- see above comment ===================================== testsuite/tests/simplCore/should_compile/T22227.hs ===================================== @@ -0,0 +1,39 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +module Unboxed (test) where + +import GHC.Exts +import GHC.IO + +data Step s a = Yield a s | Done + +uninitialised = undefined + +test :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +test off n oldArr = runRW# $ \s0 -> + case newArray# n uninitialised s0 + of { (# s1, newArr #) -> + let + step' i + | isTrue# (i >=# n) = Done + | otherwise = + let (# D# x #) = indexArray# oldArr (off +# i) in + if isTrue# (x >## 10.0##) + then Yield (D# x) (I# (i +# 1#)) + else step' (i +# 1#) + loop i j s2 = + case step' i of + Yield x (I# s') -> + case writeArray# newArr j (x + 1) s2 + of { s3 -> + loop s' (j +# 1#) s3 + } + Done -> + case unsafeFreezeArray# newArr s2 + of { (# s3, out #) -> + (# 0#, j, out #) + } + in + loop 0# 0# s1 + } ===================================== testsuite/tests/simplCore/should_compile/T22227.stderr ===================================== @@ -0,0 +1,326 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 213, types: 211, coercions: 4, joins: 5/5} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl_rUP :: Addr# +[GblId, Unf=OtherCon []] +lvl_rUP = "undefined"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl1_rUQ :: [Char] +[GblId] +lvl1_rUQ = unpackCString# lvl_rUP + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule4 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl2_rUR :: [Char] +[GblId] +lvl2_rUR = unpackCString# Unboxed.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$trModule2 = "Unboxed"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl3_rUS :: [Char] +[GblId] +lvl3_rUS = unpackCString# Unboxed.$trModule2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl4_rUT :: Addr# +[GblId, Unf=OtherCon []] +lvl4_rUT = "T22227.hs"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl5_rUU :: [Char] +[GblId] +lvl5_rUU = unpackCString# lvl4_rUT + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl6_rUV :: Int +[GblId, Unf=OtherCon []] +lvl6_rUV = GHC.Types.I# 11# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl7_rUW :: Int +[GblId, Unf=OtherCon []] +lvl7_rUW = GHC.Types.I# 17# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl8_rUX :: Int +[GblId, Unf=OtherCon []] +lvl8_rUX = GHC.Types.I# 26# + +-- RHS size: {terms: 8, types: 0, coercions: 0, joins: 0/0} +lvl9_rUY :: GHC.Stack.Types.SrcLoc +[GblId, Unf=OtherCon []] +lvl9_rUY + = GHC.Stack.Types.SrcLoc + lvl2_rUR lvl3_rUS lvl5_rUU lvl6_rUV lvl7_rUW lvl6_rUV lvl8_rUX + +-- RHS size: {terms: 4, types: 0, coercions: 0, joins: 0/0} +lvl10_rUZ :: GHC.Stack.Types.CallStack +[GblId, Unf=OtherCon []] +lvl10_rUZ + = GHC.Stack.Types.PushCallStack + lvl1_rUQ lvl9_rUY GHC.Stack.Types.EmptyCallStack + +-- RHS size: {terms: 3, types: 3, coercions: 4, joins: 0/0} +uninitialised :: forall {a}. a +[GblId, Str=b, Cpr=b] +uninitialised + = \ (@a_aCz) -> + undefined + @LiftedRep + @a_aCz + (lvl10_rUZ + `cast` (Sym (GHC.Classes.N:IP[0] + <"callStack">_N _N) + :: GHC.Stack.Types.CallStack + ~R# (?callStack::GHC.Stack.Types.CallStack))) + +-- RHS size: {terms: 90, types: 151, coercions: 0, joins: 5/5} +test + :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +[GblId, + Arity=3, + Str=, + Cpr=1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0 0] 137 0}] +test + = \ (off_axL :: Int#) + (n_axM :: Int#) + (oldArr_axN :: Array# Double) -> + runRW# + @('TupleRep '[ 'IntRep, 'IntRep, UnliftedRep]) + @(# Int#, Int#, Array# Double #) + (\ (s_sSR [OS=OneShot] :: State# RealWorld) -> + case newArray# + @'Lifted @Double @RealWorld n_axM (uninitialised @Double) s_sSR + of + { (# ipv_sSS, ipv1_sST #) -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L,L)))] + :: Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (j_ay1 [OS=OneShot] :: Int#) + (s2_ay2 [OS=OneShot] :: State# RealWorld) + = case unsafeFreezeArray# + @'Lifted @RealWorld @Double ipv1_sST s2_ay2 + of + { (# ipv2_sT8, ipv3_sT9 #) -> + (# 0#, j_ay1, ipv3_sT9 #) + } } in + joinrec { + loop_sTq [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,L)))] + :: Int# + -> Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + loop_sTq (i_ay0 :: Int#) + (j_ay1 :: Int#) + (s2_ay2 :: State# RealWorld) + = join { + exit1_X4 [Dmd=LC(S,C(1,!P(L,L,L)))] + :: Int# -> Double# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit1_X4 (i1_X1 [OS=OneShot] :: Int#) + (x_aPv [OS=OneShot] :: Double#) + = case writeArray# + @'Lifted + @RealWorld + @Double + ipv1_sST + j_ay1 + (GHC.Types.D# (+## x_aPv 1.0##)) + s2_ay2 + of s3_aAH + { __DEFAULT -> + jump loop_sTq (+# i1_X1 1#) (+# j_ay1 1#) s3_aAH + } } in + join { + $j_sTM [Dmd=L!P(L,L,L)] :: (# Int#, Int#, Array# Double #) + [LclId[JoinId(0)(Nothing)]] + $j_sTM = jump exit_X0 j_ay1 s2_ay2 } in + joinrec { + step'_sTs [Occ=LoopBreaker, Dmd=SC(S,!P(L,L,L))] + :: Int# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(1)(Nothing)], Arity=1, Str=, Unf=OtherCon []] + step'_sTs (i1_X1 :: Int#) + = case >=# i1_X1 n_axM of { + __DEFAULT -> + case indexArray# @'Lifted @Double oldArr_axN (+# off_axL i1_X1) of + { (# ipv2_sSW #) -> + case ipv2_sSW of { D# x_aPv -> + case >## x_aPv 10.0## of { + __DEFAULT -> jump step'_sTs (+# i1_X1 1#); + 1# -> jump exit1_X4 i1_X1 x_aPv + } + } + }; + 1# -> jump $j_sTM + }; } in + jump step'_sTs i_ay0; } in + jump loop_sTq 0# 0# ipv_sSS + }) + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule3 = GHC.Types.TrNameS Unboxed.$trModule4 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule1 = GHC.Types.TrNameS Unboxed.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule + = GHC.Types.Module Unboxed.$trModule3 Unboxed.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep_rV0 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep_rV0 = GHC.Types.KindRepVar 1# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep1_rV1 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep1_rV1 = GHC.Types.KindRepVar 0# + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$tcStep2 = "Step"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep1 = GHC.Types.TrNameS Unboxed.$tcStep2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep + = GHC.Types.TyCon + 9345441458829744813##64 + 15928240119707513573##64 + Unboxed.$trModule + Unboxed.$tcStep1 + 0# + GHC.Types.krep$*->*->* + +-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +$krep2_rV2 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep2_rV2 + = GHC.Types.: + @GHC.Types.KindRep $krep_rV0 (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep3_rV3 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep3_rV3 = GHC.Types.: @GHC.Types.KindRep $krep1_rV1 $krep2_rV2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Done1 + = GHC.Types.KindRepTyConApp Unboxed.$tcStep $krep3_rV3 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Done3 = "'Done"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done2 = GHC.Types.TrNameS Unboxed.$tc'Done3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done + = GHC.Types.TyCon + 12965714903249458155##64 + 720712123234526269##64 + Unboxed.$trModule + Unboxed.$tc'Done2 + 2# + Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep4_rV4 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep4_rV4 = GHC.Types.KindRepFun $krep1_rV1 Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Yield1 = GHC.Types.KindRepFun $krep_rV0 $krep4_rV4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Yield3 = "'Yield"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield2 = GHC.Types.TrNameS Unboxed.$tc'Yield3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield + = GHC.Types.TyCon + 16456917800457442198##64 + 7357499335137316903##64 + Unboxed.$trModule + Unboxed.$tc'Yield2 + 2# + Unboxed.$tc'Yield1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -428,5 +428,7 @@ test('T21763', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) -test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# step should be loopified and turned into a join point +test('T22227', [grep_errmsg(r'jump \S*step') ], compile, ['-O -ddump-simpl']) ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,12 @@ +module T22241 where + +data D = D !Int + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,15 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> + + + +==================== Cpr signatures ==================== +T22241.f: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> + + ===================================== testsuite/tests/stranal/sigs/T5075.hs ===================================== @@ -17,10 +17,10 @@ g x y = go x True -> Just x False -> go (x*2) --- Here, go is not a join point, but still should be WW'd for Just. --- Unfortunately, CPR can't see that (+?) returns Just, so h won't get the CPR --- property. It probably could by only considering the @Just@ case of the --- inlined (+?). +-- Here, go is not a join point (call-site loopification doesn't trigger because +-- it is marked NOINLINE), but still should be WW'd for Just. Unfortunately, +-- CPR can't see that (+?) returns Just, so h won't get the CPR property. It +-- probably could by only considering the @Just@ case of the inlined (+?). h :: Int -> Maybe Int h x = go x +? go (x+1) where @@ -29,3 +29,4 @@ h x = go x +? go (x+1) go z | z > 10 = Just (x + z) | otherwise = go (z*2) + {-# NOINLINE go #-} ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -36,3 +36,4 @@ test('T21119', normal, compile, ['']) test('T21717', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86ef6fa321608b146b28e37cdf0db82635573355...6ec3df64a0baaf8f161435138448b83ed1d69ebf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86ef6fa321608b146b28e37cdf0db82635573355...6ec3df64a0baaf8f161435138448b83ed1d69ebf You're receiving 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 Oct 2 09:51:41 2022 From: gitlab at gitlab.haskell.org (=?UTF-8?B?SMOpY2F0ZSBNb29ubGlnaHQgKEBLbGVpZHVrb3Mp?=) Date: Sun, 02 Oct 2022 05:51:41 -0400 Subject: [Git][ghc/ghc][wip/pattern-synonym-docs] 6 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <63395f2da7499_2c97575141413832a2@gitlab.mail> Hécate Moonlight pushed to branch wip/pattern-synonym-docs at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 39d4b87e by Brandon Chinn at 2022-10-02T09:51:29+00:00 Fix docs for pattern synonyms - - - - - 63163e21 by Brandon Chinn at 2022-10-02T09:51:29+00:00 Clarify INLINE support for patterns were added in GHC 9.2 - - - - - 29 changed files: - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Utils/Misc.hs - docs/users_guide/exts/pattern_synonyms.rst - rts/Continuation.c - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs - testsuite/tests/simplCore/should_compile/spec-inline.stderr - + testsuite/tests/stranal/sigs/T21754.hs - + testsuite/tests/stranal/sigs/T21754.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Cmm/Node.hs ===================================== @@ -45,6 +45,7 @@ import GHC.Cmm.Dataflow.Block import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dataflow.Label +import Data.Foldable (toList) import Data.Functor.Classes (liftCompare) import Data.Maybe import Data.List (tails,sortBy) @@ -247,7 +248,7 @@ pprNode platform node = pp_node <+> pp_debug (cases, mbdef) = switchTargetsFallThrough ids ppCase (is,l) = hsep [ text "case" - , commafy $ map integer is + , commafy $ toList $ fmap integer is , text ": goto" , ppr l <> semi ] ===================================== compiler/GHC/Cmm/Switch.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Cmm.Switch ( createSwitchPlan, ) where -import GHC.Prelude +import GHC.Prelude hiding (head) import GHC.Utils.Outputable import GHC.Driver.Backend @@ -20,7 +20,7 @@ import GHC.Utils.Panic import GHC.Cmm.Dataflow.Label (Label) import Data.Maybe -import qualified Data.List.NonEmpty as NE +import Data.List.NonEmpty (NonEmpty (..), groupWith, head) import qualified Data.Map as M -- Note [Cmm Switches, the general plan] @@ -200,11 +200,11 @@ switchTargetsToList (SwitchTargets _ _ mbdef branches) -- | Groups cases with equal targets, suitable for pretty-printing to a -- c-like switch statement with fall-through semantics. -switchTargetsFallThrough :: SwitchTargets -> ([([Integer], Label)], Maybe Label) +switchTargetsFallThrough :: SwitchTargets -> ([(NonEmpty Integer, Label)], Maybe Label) switchTargetsFallThrough (SwitchTargets _ _ mbdef branches) = (groups, mbdef) where - groups = map (\xs -> (map fst (NE.toList xs), snd (NE.head xs))) $ - NE.groupWith snd $ + groups = fmap (\xs -> (fmap fst xs, snd (head xs))) $ + groupWith snd $ M.toList branches -- | Custom equality helper, needed for "GHC.Cmm.CommonBlockElim" ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -78,7 +78,7 @@ module GHC.CmmToAsm ) where -import GHC.Prelude +import GHC.Prelude hiding (head) import qualified GHC.CmmToAsm.X86 as X86 import qualified GHC.CmmToAsm.PPC as PPC @@ -140,7 +140,7 @@ import GHC.Data.Stream (Stream) import qualified GHC.Data.Stream as Stream import Data.List (sortBy) -import qualified Data.List.NonEmpty as NE +import Data.List.NonEmpty (groupAllWith, head) import Data.Maybe import Data.Ord ( comparing ) import Control.Monad @@ -776,8 +776,8 @@ makeImportsDoc config imports | needImportedSymbols config = vcat $ (pprGotDeclaration config :) $ - fmap ( pprImportedSymbol config . fst . NE.head) $ - NE.groupAllWith snd $ + fmap (pprImportedSymbol config . fst . head) $ + groupAllWith snd $ map doPpr $ imps | otherwise ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -59,6 +59,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as BS import Data.Char import Data.List (intersperse) +import Data.List.NonEmpty (NonEmpty (..)) import Data.Map (Map) import qualified Data.Map as Map import GHC.Float @@ -347,7 +348,7 @@ pprSwitch platform e ids rep = typeWidth (cmmExprType platform e) -- fall through case - caseify (ix:ixs, ident) = vcat (map do_fallthrough ixs) $$ final_branch ix + caseify (ix:|ixs, ident) = vcat (map do_fallthrough ixs) $$ final_branch ix where do_fallthrough ix = hsep [ text "case" , pprHexVal platform ix rep <> colon , @@ -357,8 +358,6 @@ pprSwitch platform e ids hsep [ text "case" , pprHexVal platform ix rep <> colon , text "goto" , (pprBlockId ident) <> semi ] - caseify (_ , _ ) = panic "pprSwitch: switch with no cases!" - def | Just l <- mbdef = text "default: goto" <+> pprBlockId l <> semi | otherwise = text "default: __builtin_unreachable();" ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -11,7 +11,7 @@ module GHC.CmmToLlvm ) where -import GHC.Prelude +import GHC.Prelude hiding ( head ) import GHC.Llvm import GHC.CmmToLlvm.Base @@ -37,6 +37,7 @@ import GHC.Utils.Logger import qualified GHC.Data.Stream as Stream import Control.Monad ( when, forM_ ) +import Data.List.NonEmpty ( head ) import Data.Maybe ( fromMaybe, catMaybes ) import System.IO @@ -68,7 +69,7 @@ llvmCodeGen logger cfg h cmm_stream "System LLVM version: " <> text (llvmVersionStr ver) $$ "We will try though..." let isS390X = platformArch (llvmCgPlatform cfg) == ArchS390X - let major_ver = head . llvmVersionList $ ver + let major_ver = head . llvmVersionNE $ ver when (isS390X && major_ver < 10 && doWarn) $ putMsg logger $ "Warning: For s390x the GHC calling convention is only supported since LLVM version 10." <+> "You are using LLVM version: " <> text (llvmVersionStr ver) ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -59,9 +59,18 @@ _ = pprTrace -- Tired of commenting out the import all the time -- | Options for the demand analysis data DmdAnalOpts = DmdAnalOpts - { dmd_strict_dicts :: !Bool -- ^ Use strict dictionaries - , dmd_unbox_width :: !Int -- ^ Use strict dictionaries + { dmd_strict_dicts :: !Bool + -- ^ Value of `-fdicts-strict` (on by default). + -- When set, all functons are implicitly strict in dictionary args. + , dmd_do_boxity :: !Bool + -- ^ Governs whether the analysis should update boxity signatures. + -- See Note [Don't change boxity without worker/wrapper]. + , dmd_unbox_width :: !Int + -- ^ Value of `-fdmd-unbox-width`. + -- See Note [Unboxed demand on function bodies returning small products] , dmd_max_worker_args :: !Int + -- ^ Value of `-fmax-worker-args`. + -- Don't unbox anything if we end up with more than this many args. } -- This is a strict alternative to (,) @@ -146,6 +155,40 @@ unforced thunks in demand or strictness information; and it is the most memory-intensive part of the compilation process, so this added seqBinds makes a big difference in peak memory usage. +Note [Don't change boxity without worker/wrapper] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider (T21754) + f n = n+1 + {-# NOINLINE f #-} +With `-fno-worker-wrapper`, we should not give `f` a boxity signature that says +that it unboxes its argument! Client modules would never be able to cancel away +the box for n. Likewise we shouldn't give `f` the CPR property. + +Similarly, in the last run of DmdAnal before codegen (which does not have a +worker/wrapper phase) we should not change boxity in any way. Remember: an +earlier result of the demand analyser, complete with worker/wrapper, has aleady +given a demand signature (with boxity info) to the function. +(The "last run" is mainly there to attach demanded-once info to let-bindings.) + +In general, we should not run Note [Boxity analysis] unless worker/wrapper +follows to exploit the boxity and make sure that calling modules can observe the +reported boxity. + +Hence DmdAnal is configured by a flag `dmd_do_boxity` that is True only +if worker/wrapper follows after DmdAnal. If it is not set, and the signature +is not subject to Note [Boxity for bottoming functions], DmdAnal tries +to transfer over the previous boxity to the new demand signature, in +`setIdDmdAndBoxSig`. + +Why isn't CprAnal configured with a similar flag? Because if we aren't going to +do worker/wrapper we don't run CPR analysis at all. (see GHC.Core.Opt.Pipeline) + +It might be surprising that we only try to preserve *arg* boxity, not boxity on +FVs. But FV demands won't make it into interface files anyway, so it's a waste +of energy. +Besides, W/W zaps the `DmdEnv` portion of a signature, so we don't know the old +boxity to begin with; see Note [Zapping DmdEnv after Demand Analyzer]. + Note [Analysing top-level bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a CoreProgram like @@ -257,6 +300,16 @@ setBindIdDemandInfo top_lvl id dmd = setIdDemandInfo id $ case top_lvl of TopLevel | not (isInterestingTopLevelFn id) -> topDmd _ -> dmd +-- | Update the demand signature, but be careful not to change boxity info if +-- `dmd_do_boxity` is True or if the signature is bottom. +-- See Note [Don't change boxity without worker/wrapper] +-- and Note [Boxity for bottoming functions]. +setIdDmdAndBoxSig :: DmdAnalOpts -> Id -> DmdSig -> Id +setIdDmdAndBoxSig opts id sig = setIdDmdSig id $ + if dmd_do_boxity opts || isBottomingSig sig + then sig + else transferArgBoxityDmdSig (idDmdSig id) sig + -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). -- This function handles the up variant. @@ -1018,7 +1071,8 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) - final_id = id `setIdDmdSig` sig + opts = ae_opts env + final_id = setIdDmdAndBoxSig opts id sig !final_env = extendAnalEnv top_lvl env final_id sig -- See Note [Aggregated demand for cardinality] @@ -1858,8 +1912,9 @@ dmdFix :: TopLevelFlag dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where + opts = ae_opts env -- See Note [Initialising strictness] - initial_pairs | ae_virgin env = [(setIdDmdSig id botSig, rhs) | (id, rhs) <- orig_pairs ] + initial_pairs | ae_virgin env = [(setIdDmdAndBoxSig opts id botSig, rhs) | (id, rhs) <- orig_pairs ] | otherwise = orig_pairs -- If fixed-point iteration does not yield a result we use this instead ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -150,7 +150,7 @@ getCoreToDo dflags rule_base extra_vars maybe_rule_check phase = runMaybe rule_check (CoreDoRuleCheck phase) maybe_strictness_before (Phase phase) - | phase `elem` strictnessBefore dflags = CoreDoDemand + | phase `elem` strictnessBefore dflags = CoreDoDemand False maybe_strictness_before _ = CoreDoNothing @@ -171,8 +171,8 @@ getCoreToDo dflags rule_base extra_vars simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter (initGentleSimplMode dflags) rule_base - dmd_cpr_ww = if ww_on then [CoreDoDemand,CoreDoCpr,CoreDoWorkerWrapper] - else [CoreDoDemand,CoreDoCpr] + dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] + else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] demand_analyser = (CoreDoPasses ( @@ -340,7 +340,7 @@ getCoreToDo dflags rule_base extra_vars -- has run at all. See Note [Final Demand Analyser run] in GHC.Core.Opt.DmdAnal -- It is EXTREMELY IMPORTANT to run this pass, otherwise execution -- can become /exponentially/ more expensive. See #11731, #12996. - runWhen (strictness || late_dmd_anal) CoreDoDemand, + runWhen (strictness || late_dmd_anal) (CoreDoDemand False), maybe_rule_check FinalPhase, @@ -491,8 +491,8 @@ doCorePass pass guts = do CoreDoExitify -> {-# SCC "Exitify" #-} updateBinds exitifyProgram - CoreDoDemand -> {-# SCC "DmdAnal" #-} - updateBindsM (liftIO . dmdAnal logger dflags fam_envs (mg_rules guts)) + CoreDoDemand before_ww -> {-# SCC "DmdAnal" #-} + updateBindsM (liftIO . dmdAnal logger before_ww dflags fam_envs (mg_rules guts)) CoreDoCpr -> {-# SCC "CprAnal" #-} updateBindsM (liftIO . cprAnalProgram logger fam_envs) @@ -557,10 +557,11 @@ ruleCheckPass current_phase pat guts = do rule_fn (mg_binds guts)) return guts -dmdAnal :: Logger -> DynFlags -> FamInstEnvs -> [CoreRule] -> CoreProgram -> IO CoreProgram -dmdAnal logger dflags fam_envs rules binds = do +dmdAnal :: Logger -> Bool -> DynFlags -> FamInstEnvs -> [CoreRule] -> CoreProgram -> IO CoreProgram +dmdAnal logger before_ww dflags fam_envs rules binds = do let !opts = DmdAnalOpts { dmd_strict_dicts = gopt Opt_DictsStrict dflags + , dmd_do_boxity = before_ww -- only run Boxity Analysis immediately preceding WW , dmd_unbox_width = dmdUnboxWidth dflags , dmd_max_worker_args = maxWorkerArgs dflags } ===================================== compiler/GHC/Core/Opt/Pipeline/Types.hs ===================================== @@ -45,7 +45,8 @@ data CoreToDo -- These are diff core-to-core passes, | CoreDoStaticArgs | CoreDoCallArity | CoreDoExitify - | CoreDoDemand + | CoreDoDemand Bool -- Bool: Do worker/wrapper afterwards? + -- See Note [Don't change boxity without worker/wrapper] | CoreDoCpr | CoreDoWorkerWrapper | CoreDoSpecialising @@ -74,7 +75,8 @@ instance Outputable CoreToDo where ppr CoreDoStaticArgs = text "Static argument" ppr CoreDoCallArity = text "Called arity analysis" ppr CoreDoExitify = text "Exitification transformation" - ppr CoreDoDemand = text "Demand analysis" + ppr (CoreDoDemand True) = text "Demand analysis (including Boxity)" + ppr (CoreDoDemand False) = text "Demand analysis" ppr CoreDoCpr = text "Constructed Product Result analysis" ppr CoreDoWorkerWrapper = text "Worker Wrapper binds" ppr CoreDoSpecialising = text "Specialise" ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -63,6 +63,8 @@ import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts import GHC.Core.Unfold +import Data.List.NonEmpty ( NonEmpty (..) ) + {- ************************************************************************ * * @@ -1201,7 +1203,7 @@ specCase env scrut' case_bndr [Alt con args rhs] | -- See Note [Floating dictionaries out of cases] interestingDict scrut' (idType case_bndr) , not (isDeadBinder case_bndr && null sc_args') - = do { (case_bndr_flt : sc_args_flt) <- mapM clone_me (case_bndr' : sc_args') + = do { case_bndr_flt :| sc_args_flt <- mapM clone_me (case_bndr' :| sc_args') ; let case_bndr_flt' = case_bndr_flt `addDictUnfolding` scrut' scrut_bind = mkDB (NonRec case_bndr_flt scrut') ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1200,12 +1200,9 @@ cpeApp top_env expr arg_ty' = cpSubstTy env arg_ty CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats ss' rt_ticks req_depth + -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth where co' = cpSubstCo env co - ss' - | null ss = [] - | otherwise = tail ss CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make ===================================== compiler/GHC/Data/BooleanFormula.hs ===================================== @@ -16,9 +16,10 @@ module GHC.Data.BooleanFormula ( pprBooleanFormula, pprBooleanFormulaNice ) where -import GHC.Prelude +import GHC.Prelude hiding ( init, last ) import Data.List ( nub, intersperse ) +import Data.List.NonEmpty ( NonEmpty (..), init, last ) import Data.Data import GHC.Utils.Monad @@ -227,7 +228,7 @@ pprBooleanFormulaNice = pprBooleanFormula' pprVar pprAnd pprOr 0 pprAnd p = cparen (p > 1) . pprAnd' pprAnd' [] = empty pprAnd' [x,y] = x <+> text "and" <+> y - pprAnd' xs@(_:_) = fsep (punctuate comma (init xs)) <> text ", and" <+> last xs + pprAnd' (x:xs) = fsep (punctuate comma (init (x:|xs))) <> text ", and" <+> last (x:|xs) pprOr p xs = cparen (p > 1) $ text "either" <+> sep (intersperse (text "or") xs) instance (OutputableBndr a) => Outputable (BooleanFormula a) where ===================================== compiler/GHC/Data/OrdList.hs ===================================== @@ -28,6 +28,8 @@ import GHC.Utils.Misc (strictMap) import GHC.Utils.Outputable import GHC.Utils.Panic +import Data.List.NonEmpty (NonEmpty(..)) +import qualified Data.List.NonEmpty as NE import qualified Data.Semigroup as Semigroup infixl 5 `appOL` @@ -37,7 +39,7 @@ infixr 5 `consOL` data OrdList a = None | One a - | Many [a] -- Invariant: non-empty + | Many (NonEmpty a) | Cons a (OrdList a) | Snoc (OrdList a) a | Two (OrdList a) -- Invariant: non-empty @@ -100,8 +102,12 @@ pattern ConsOL :: a -> OrdList a -> OrdList a pattern ConsOL x xs <- (viewCons -> VJust x xs) where ConsOL x xs = consOL x xs {-# COMPLETE NilOL, ConsOL #-} + viewCons :: OrdList a -> VMaybe a (OrdList a) -viewCons (One a) = VJust a NilOL +viewCons None = VNothing +viewCons (One a) = VJust a NilOL +viewCons (Many (a :| [])) = VJust a NilOL +viewCons (Many (a :| b : bs)) = VJust a (Many (b :| bs)) viewCons (Cons a as) = VJust a as viewCons (Snoc as a) = case viewCons as of VJust a' as' -> VJust a' (Snoc as' a) @@ -109,15 +115,18 @@ viewCons (Snoc as a) = case viewCons as of viewCons (Two as1 as2) = case viewCons as1 of VJust a' as1' -> VJust a' (Two as1' as2) VNothing -> viewCons as2 -viewCons _ = VNothing pattern SnocOL :: OrdList a -> a -> OrdList a pattern SnocOL xs x <- (viewSnoc -> VJust xs x) where SnocOL xs x = snocOL xs x {-# COMPLETE NilOL, SnocOL #-} + viewSnoc :: OrdList a -> VMaybe (OrdList a) a -viewSnoc (One a) = VJust NilOL a -viewSnoc (Many (reverse -> a:as)) = VJust (Many (reverse as)) a +viewSnoc None = VNothing +viewSnoc (One a) = VJust NilOL a +viewSnoc (Many as) = (`VJust` NE.last as) $ case NE.init as of + [] -> NilOL + b : bs -> Many (b :| bs) viewSnoc (Snoc as a) = VJust as a viewSnoc (Cons a as) = case viewSnoc as of VJust as' a' -> VJust (Cons a as') a' @@ -125,18 +134,17 @@ viewSnoc (Cons a as) = case viewSnoc as of viewSnoc (Two as1 as2) = case viewSnoc as2 of VJust as2' a' -> VJust (Two as1 as2') a' VNothing -> viewSnoc as1 -viewSnoc _ = VNothing headOL None = panic "headOL" headOL (One a) = a -headOL (Many as) = head as +headOL (Many as) = NE.head as headOL (Cons a _) = a headOL (Snoc as _) = headOL as headOL (Two as _) = headOL as lastOL None = panic "lastOL" lastOL (One a) = a -lastOL (Many as) = last as +lastOL (Many as) = NE.last as lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as @@ -164,7 +172,7 @@ fromOL a = go a [] go (Cons a b) acc = a : go b acc go (Snoc a b) acc = go a (b:acc) go (Two a b) acc = go a (go b acc) - go (Many xs) acc = xs ++ acc + go (Many xs) acc = NE.toList xs ++ acc fromOLReverse :: OrdList a -> [a] fromOLReverse a = go a [] @@ -175,7 +183,7 @@ fromOLReverse a = go a [] go (Cons a b) acc = go b (a : acc) go (Snoc a b) acc = b : go a acc go (Two a b) acc = go b (go a acc) - go (Many xs) acc = reverse xs ++ acc + go (Many xs) acc = reverse (NE.toList xs) ++ acc mapOL :: (a -> b) -> OrdList a -> OrdList b mapOL = fmap @@ -192,7 +200,9 @@ mapOL' f (Snoc xs x) = let !x1 = f x mapOL' f (Two b1 b2) = let !b1' = mapOL' f b1 !b2' = mapOL' f b2 in Two b1' b2' -mapOL' f (Many xs) = Many $! strictMap f xs +mapOL' f (Many (x :| xs)) = let !x1 = f x + !xs1 = strictMap f xs + in Many (x1 :| xs1) foldrOL :: (a->b->b) -> b -> OrdList a -> b foldrOL _ z None = z @@ -214,7 +224,7 @@ foldlOL k z (Many xs) = foldl' k z xs toOL :: [a] -> OrdList a toOL [] = None toOL [x] = One x -toOL xs = Many xs +toOL (x : xs) = Many (x :| xs) reverseOL :: OrdList a -> OrdList a reverseOL None = None @@ -222,7 +232,7 @@ reverseOL (One x) = One x reverseOL (Cons a b) = Snoc (reverseOL b) a reverseOL (Snoc a b) = Cons b (reverseOL a) reverseOL (Two a b) = Two (reverseOL b) (reverseOL a) -reverseOL (Many xs) = Many (reverse xs) +reverseOL (Many xs) = Many (NE.reverse xs) -- | Compare not only the values but also the structure of two lists strictlyEqOL :: Eq a => OrdList a -> OrdList a -> Bool ===================================== compiler/GHC/Driver/Config/Core/Lint.hs ===================================== @@ -83,7 +83,7 @@ coreDumpFlag CoreLiberateCase = Just Opt_D_verbose_core2core coreDumpFlag CoreDoStaticArgs = Just Opt_D_verbose_core2core coreDumpFlag CoreDoCallArity = Just Opt_D_dump_call_arity coreDumpFlag CoreDoExitify = Just Opt_D_dump_exitify -coreDumpFlag CoreDoDemand = Just Opt_D_dump_stranal +coreDumpFlag (CoreDoDemand {}) = Just Opt_D_dump_stranal coreDumpFlag CoreDoCpr = Just Opt_D_dump_cpranal coreDumpFlag CoreDoWorkerWrapper = Just Opt_D_dump_worker_wrapper coreDumpFlag CoreDoSpecialising = Just Opt_D_dump_spec ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -1779,9 +1779,9 @@ getGccSearchDirectory logger dflags key = do find :: String -> String -> String find r x = let lst = lines x val = filter (r `isPrefixOf`) lst - in if null val - then [] - else case break (=='=') (head val) of + in case val of + [] -> [] + x:_ -> case break (=='=') x of (_ , []) -> [] (_, (_:xs)) -> xs ===================================== compiler/GHC/Llvm/Types.hs ===================================== @@ -181,7 +181,7 @@ getLitType :: LlvmLit -> LlvmType getLitType (LMIntLit _ t) = t getLitType (LMFloatLit _ t) = t getLitType (LMVectorLit []) = panic "getLitType" -getLitType (LMVectorLit ls) = LMVector (length ls) (getLitType (head ls)) +getLitType (LMVectorLit ls@(l:_)) = LMVector (length ls) (getLitType l) getLitType (LMNullLit t) = t getLitType (LMUndefLit t) = t ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -2513,10 +2513,10 @@ mkRecConstrOrUpdate _ (L _ (HsVar _ (L l c))) _lrec (fbinds,dd) anns | isRdrDataCon c = do let (fs, ps) = partitionEithers fbinds - if not (null ps) - then addFatalError $ mkPlainErrorMsgEnvelope (getLocA (head ps)) $ - PsErrOverloadedRecordDotInvalid - else return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns) + case ps of + p:_ -> addFatalError $ mkPlainErrorMsgEnvelope (getLocA p) $ + PsErrOverloadedRecordDotInvalid + _ -> return (mkRdrRecordCon (L l c) (mk_rec_fields fs dd) anns) mkRecConstrOrUpdate overloaded_update exp _ (fs,dd) anns | Just dd_loc <- dd = addFatalError $ mkPlainErrorMsgEnvelope dd_loc $ PsErrDotsInRecordUpdate @@ -2546,15 +2546,13 @@ mkRdrRecordUpd overloaded_on exp@(L loc _) fbinds anns = do [ L l lbl | L _ (HsFieldBind _ (L l lbl) _ _) <- fs' , isQual . rdrNameAmbiguousFieldOcc $ lbl ] - if not $ null qualifiedFields - then - addFatalError $ mkPlainErrorMsgEnvelope (getLocA (head qualifiedFields)) $ + case qualifiedFields of + qf:_ -> addFatalError $ mkPlainErrorMsgEnvelope (getLocA qf) $ PsErrOverloadedRecordUpdateNoQualifiedFields - else -- This is a RecordDotSyntax update. - return RecordUpd { - rupd_ext = anns - , rupd_expr = exp - , rupd_flds = Right (toProjUpdates fbinds) } + _ -> return RecordUpd -- This is a RecordDotSyntax update. + { rupd_ext = anns + , rupd_expr = exp + , rupd_flds = Right (toProjUpdates fbinds) } where toProjUpdates :: [Fbind (HsExpr GhcPs)] -> [LHsRecUpdProj GhcPs] toProjUpdates = map (\case { Right p -> p; Left f -> recFieldToProjUpdate f }) ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -178,6 +178,8 @@ import qualified GHC.Data.BooleanFormula as BF import Data.Functor.Classes ( liftEq ) import Data.List ( sortBy, sort ) +import Data.List.NonEmpty ( NonEmpty (..) ) +import qualified Data.List.NonEmpty as NE import Data.Ord import Data.Data ( Data ) import qualified Data.Set as S @@ -2223,10 +2225,8 @@ type Plan = TcM PlanResult -- | Try the plans in order. If one fails (by raising an exn), try the next. -- If one succeeds, take it. -runPlans :: [Plan] -> TcM PlanResult -runPlans [] = panic "runPlans" -runPlans [p] = p -runPlans (p:ps) = tryTcDiscardingErrs (runPlans ps) p +runPlans :: NonEmpty Plan -> Plan +runPlans = foldr1 (flip tryTcDiscardingErrs) -- | Typecheck (and 'lift') a stmt entered by the user in GHCi into the -- GHCi 'environment'. @@ -2298,30 +2298,31 @@ tcUserStmt (L loc (BodyStmt _ expr _ _)) -- See Note [GHCi Plans] - it_plans = [ + it_plans = -- Plan A do { stuff@([it_id], _) <- tcGhciStmts [bind_stmt, print_it] ; it_ty <- zonkTcType (idType it_id) - ; when (isUnitTy $ it_ty) failM - ; return stuff }, + ; when (isUnitTy it_ty) failM + ; return stuff } :| -- Plan B; a naked bind statement - tcGhciStmts [bind_stmt], + [ tcGhciStmts [bind_stmt] -- Plan C; check that the let-binding is typeable all by itself. -- If not, fail; if so, try to print it. -- The two-step process avoids getting two errors: one from -- the expression itself, and one from the 'print it' part -- This two-step story is very clunky, alas - do { _ <- checkNoErrs (tcGhciStmts [let_stmt]) + , do { _ <- checkNoErrs (tcGhciStmts [let_stmt]) --- checkNoErrs defeats the error recovery of let-bindings ; tcGhciStmts [let_stmt, print_it] } ] -- Plans where we don't bind "it" - no_it_plans = [ - tcGhciStmts [no_it_a] , - tcGhciStmts [no_it_b] , - tcGhciStmts [no_it_c] ] + no_it_plans = + tcGhciStmts [no_it_a] :| + tcGhciStmts [no_it_b] : + tcGhciStmts [no_it_c] : + [] ; generate_it <- goptM Opt_NoIt @@ -2413,13 +2414,13 @@ tcUserStmt rdr_stmt@(L loc _) ; let print_result_plan | opt_pr_flag -- The flag says "print result" , [v] <- collectLStmtBinders CollNoDictBinders gi_stmt -- One binder - = [mk_print_result_plan gi_stmt v] - | otherwise = [] + = Just $ mk_print_result_plan gi_stmt v + | otherwise = Nothing -- The plans are: -- [stmt; print v] if one binder and not v::() -- [stmt] otherwise - ; plan <- runPlans (print_result_plan ++ [tcGhciStmts [gi_stmt]]) + ; plan <- runPlans $ maybe id (NE.<|) print_result_plan $ NE.singleton $ tcGhciStmts [gi_stmt] ; return (plan, fix_env) } where mk_print_result_plan stmt v ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -64,7 +64,8 @@ module GHC.Types.Demand ( -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, splitDmdSig, dmdSigDmdEnv, hasDemandEnvSig, - nopSig, botSig, isNopSig, isDeadEndSig, isDeadEndAppSig, trimBoxityDmdSig, + nopSig, botSig, isNopSig, isBottomingSig, isDeadEndSig, isDeadEndAppSig, + trimBoxityDmdSig, transferArgBoxityDmdSig, -- ** Handling arity adjustments prependArgsDmdSig, etaConvertDmdSig, @@ -2147,6 +2148,13 @@ isNopSig (DmdSig ty) = isNopDmdType ty isDeadEndSig :: DmdSig -> Bool isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +-- | True if the signature diverges or throws an imprecise exception in a saturated call. +-- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. +-- See Note [Dead ends] +-- and Note [Precise vs imprecise exceptions]. +isBottomingSig :: DmdSig -> Bool +isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv + -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds @@ -2179,6 +2187,38 @@ trimBoxityDmdType (DmdType fvs ds res) = trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType +-- | Transfers the boxity of the left arg to the demand structure of the right +-- arg. This only makes sense if applied to new and old demands of the same +-- value. +transferBoxity :: Demand -> Demand -> Demand +transferBoxity from to = go_dmd from to + where + go_dmd (from_n :* from_sd) to_dmd@(to_n :* to_sd) + | isAbs from_n || isAbs to_n = to_dmd + | otherwise = case (from_sd, to_sd) of + (Poly from_b _, Poly _ to_c) -> + to_n :* Poly from_b to_c + (_, Prod _ to_ds) + | Just (from_b, from_ds) <- viewProd (length to_ds) from_sd + -> to_n :* mkProd from_b (strictZipWith go_dmd from_ds to_ds) + (Prod from_b from_ds, _) + | Just (_, to_ds) <- viewProd (length from_ds) to_sd + -> to_n :* mkProd from_b (strictZipWith go_dmd from_ds to_ds) + _ -> trimBoxity to_dmd + +transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType +transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) + | equalLength from_ds to_ds + = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ + DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + (zipWith transferBoxity from_ds to_ds) + to_res + | otherwise + = trimBoxityDmdType to + +transferArgBoxityDmdSig :: DmdSig -> DmdSig -> DmdSig +transferArgBoxityDmdSig = coerce transferArgBoxityDmdType + prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument ===================================== compiler/GHC/Types/Name/Reader.hs ===================================== @@ -825,12 +825,12 @@ pprGlobalRdrEnv locals_only env remove_locals gres | locals_only = filter isLocalGRE gres | otherwise = gres pp [] = empty - pp gres = hang (ppr occ + pp gres@(gre:_) = hang (ppr occ <+> parens (text "unique" <+> ppr (getUnique occ)) <> colon) 2 (vcat (map ppr gres)) where - occ = nameOccName (greMangledName (head gres)) + occ = nameOccName (greMangledName gre) lookupGlobalRdrEnv :: GlobalRdrEnv -> OccName -> [GlobalRdrElt] lookupGlobalRdrEnv env occ_name = case lookupOccEnv env occ_name of ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -699,8 +699,8 @@ getUnitDbRefs cfg = do let base_conf_refs = case e_pkg_path of Left _ -> system_conf_refs Right path - | not (null path) && isSearchPathSeparator (last path) - -> map PkgDbPath (splitSearchPath (init path)) ++ system_conf_refs + | Just (xs, x) <- snocView path, isSearchPathSeparator x + -> map PkgDbPath (splitSearchPath xs) ++ system_conf_refs | otherwise -> map PkgDbPath (splitSearchPath path) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -124,7 +124,7 @@ module GHC.Utils.Misc ( HasDebugCallStack, ) where -import GHC.Prelude +import GHC.Prelude hiding ( last ) import GHC.Utils.Exception import GHC.Utils.Panic.Plain @@ -133,7 +133,7 @@ import GHC.Utils.Fingerprint import Data.Data import qualified Data.List as List -import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.List.NonEmpty ( NonEmpty(..), last ) import GHC.Exts import GHC.Stack (HasCallStack) @@ -750,7 +750,7 @@ last2 = List.foldl' (\(_,x2) x -> (x2,x)) (partialError,partialError) lastMaybe :: [a] -> Maybe a lastMaybe [] = Nothing -lastMaybe xs = Just $ last xs +lastMaybe (x:xs) = Just $ last (x:|xs) -- | @onJust x m f@ applies f to the value inside the Just or returns the default. onJust :: b -> Maybe a -> (a->b) -> b @@ -1293,9 +1293,9 @@ withAtomicRename targetFile f = do -- string is returned in the first component (and the second one is just -- empty). splitLongestPrefix :: String -> (Char -> Bool) -> (String,String) -splitLongestPrefix str pred - | null r_pre = (str, []) - | otherwise = (reverse (tail r_pre), reverse r_suf) +splitLongestPrefix str pred = case r_pre of + [] -> (str, []) + _:r_pre' -> (reverse r_pre', reverse r_suf) -- 'tail' drops the char satisfying 'pred' where (r_suf, r_pre) = break pred (reverse str) ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} ===================================== rts/Continuation.c ===================================== @@ -472,12 +472,14 @@ StgClosure *captureContinuationAndAbort(Capability *cap, StgTSO *tso, StgPromptT stack = pop_stack_chunk(cap, tso); for (StgWord i = 0; i < full_chunks; i++) { - memcpy(cont_stack, stack->sp, stack->stack_size * sizeof(StgWord)); - cont_stack += stack->stack_size; + const size_t chunk_words = stack->stack + stack->stack_size - stack->sp - sizeofW(StgUnderflowFrame); + memcpy(cont_stack, stack->sp, chunk_words * sizeof(StgWord)); + cont_stack += chunk_words; stack = pop_stack_chunk(cap, tso); } memcpy(cont_stack, stack->sp, last_chunk_words * sizeof(StgWord)); + cont_stack += last_chunk_words; stack->sp += last_chunk_words; } ===================================== testsuite/tests/rts/continuations/all.T ===================================== @@ -2,3 +2,4 @@ test('cont_simple_shift', [extra_files(['ContIO.hs'])], multimod_compile_and_run test('cont_exn_masking', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_exn_masking', '']) test('cont_missing_prompt_err', [extra_files(['ContIO.hs']), exit_code(1)], multimod_compile_and_run, ['cont_missing_prompt_err', '']) test('cont_nondet_handler', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_nondet_handler', '']) +test('cont_stack_overflow', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_stack_overflow', '-with-rtsopts "-ki1k -kc2k -kb256"']) ===================================== testsuite/tests/rts/continuations/cont_stack_overflow.hs ===================================== @@ -0,0 +1,32 @@ +-- This test is run with RTS options that instruct GHC to use a small stack +-- chunk size (2k), which ensures this test exercises multi-chunk continuation +-- captures and restores. + +import Control.Monad (unless) +import ContIO + +data Answer + = Done Int + | Yield (IO Int -> IO Answer) + +getAnswer :: Answer -> Int +getAnswer (Done n) = n +getAnswer (Yield _) = error "getAnswer" + +main :: IO () +main = do + tag <- newPromptTag + Yield k <- prompt tag $ + Done <$> buildBigCont tag 6000 + n <- getAnswer <$> k (getAnswer <$> k (pure 0)) + unless (n == 36006000) $ + error $ "produced wrong value: " ++ show n + +buildBigCont :: PromptTag Answer + -> Int + -> IO Int +buildBigCont tag size + | size <= 0 = control0 tag (\k -> pure (Yield k)) + | otherwise = do + n <- buildBigCont tag (size - 1) + pure $! n + size ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -143,7 +143,7 @@ Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 foo :: Int -> Int [GblId, Arity=1, - Str=<1!P(L)>, + Str=<1L>, Cpr=1, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, ===================================== testsuite/tests/stranal/sigs/T21754.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -fno-worker-wrapper #-} + +module Test where + +f :: Int -> Int +f n = n+1 +{-# NOINLINE f #-} ===================================== testsuite/tests/stranal/sigs/T21754.stderr ===================================== @@ -0,0 +1,10 @@ + +==================== Strictness signatures ==================== +Test.f: <1L> + + + +==================== Strictness signatures ==================== +Test.f: <1L> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -34,5 +34,6 @@ test('T20746b', normal, compile, ['']) test('T21081', normal, compile, ['']) test('T21119', normal, compile, ['']) test('T21717', normal, compile, ['']) +test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a704ff0311447c49a393c0ec8cbd528ced348d01...63163e2105b25f8c834c9e520716f2e808f21d6b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a704ff0311447c49a393c0ec8cbd528ced348d01...63163e2105b25f8c834c9e520716f2e808f21d6b You're receiving 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 Oct 2 12:56:11 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Sun, 02 Oct 2022 08:56:11 -0400 Subject: [Git][ghc/ghc][wip/andreask/deep_discounts] 171 commits: compiler: Eliminate two uses of foldr in favor of foldl' Message-ID: <63398a6bb5826_2c975742bcfe7013957f1@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/deep_discounts at Glasgow Haskell Compiler / GHC Commits: c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - 0bea29ae by Andreas Klebinger at 2022-09-12T17:27:00+02:00 Prototype for deep inlining discounts. This is very much not finished but the basic idea is the allow for reasonably accurate estimates how much smaller a inlined function will be if applied to a certain argument. See #21938 for a proper description of the idea. - - - - - b6210c40 by Andreas Klebinger at 2022-09-12T17:27:00+02:00 Start bag/env rework - - - - - 3d896b84 by Andreas Klebinger at 2022-09-12T17:27:00+02:00 VarEnv based discounts mostly done - - - - - 451ed8c3 by Andreas Klebinger at 2022-09-12T17:27:00+02:00 Fix Lam shadowing and other WIP work - - - - - 6a57e1b4 by Andreas Klebinger at 2022-09-12T17:27:00+02:00 Optimize UnVarSet slightly - - - - - ca46a15e by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Some tyClassCon handling, ConDiscount type, shadowing fixes - - - - - 1b7a4f87 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 wip - - - - - 0861ab3f by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Make linter happier - - - - - 9180c5cc by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Fix default discounts - - - - - d842041b by Andreas Klebinger at 2022-09-12T17:27:01+02:00 min discount of 10 if the arg is a value - - - - - 78f27ea6 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Add a depth discount to nested argInfo/argGuidance - - - - - cd9d2468 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Make ppr prettier, fix docs maybe - - - - - 934db140 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 A bit of cleanup - - - - - a180ecd4 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Fix docs - - - - - 743a70c1 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 Refactor note - - - - - 5a440f20 by Andreas Klebinger at 2022-09-12T17:27:01+02:00 wip - use guidance to compute arg summary - - - - - 91871f0a by Andreas Klebinger at 2022-10-02T14:51:17+02:00 Move some functions around to avoid a module loop - - - - - 9e0ae25b by Andreas Klebinger at 2022-10-02T14:51:39+02:00 Special case the collectArgs function used by the inliner - - - - - bac008ae by Andreas Klebinger at 2022-10-02T14:54:34+02:00 Some small optimizations here and there. Doesn't change the inlining logic. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - − bindisttest/ghc.mk - boot - compiler/CodeGen.Platform.h - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/CFG.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/715daf11e4395668c4ab78afc0dfc94752fdd487...bac008ae520815bc7cabd42240ca78565d0a52e0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/715daf11e4395668c4ab78afc0dfc94752fdd487...bac008ae520815bc7cabd42240ca78565d0a52e0 You're receiving 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 Oct 2 14:24:00 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Sun, 02 Oct 2022 10:24:00 -0400 Subject: [Git][ghc/ghc][wip/andreask/deep_discounts] 2 commits: Prototype for deep inlining discounts. Message-ID: <63399f0067033_2c9757514141404425@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/deep_discounts at Glasgow Haskell Compiler / GHC Commits: 9198be09 by Andreas Klebinger at 2022-10-02T15:13:53+02:00 Prototype for deep inlining discounts. This is very much not finished but the basic idea is the allow for reasonably accurate estimates how much smaller a inlined function will be if applied to a certain argument. See #21938 for a proper description of the idea. Optimize UnVarSet slightly min discount of 10 if the arg is a value Add a depth discount to nested argInfo/argGuidance Move some functions around to avoid a module loop - - - - - 4cbe93cf by Andreas Klebinger at 2022-10-02T16:09:37+02:00 Remove one flag - - - - - 17 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - + compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Seq.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Data/Graph/UnVar.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Utils/Outputable.hs - compiler/ghc.cabal.in - docs/users_guide/hints.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -55,6 +55,7 @@ module GHC.Core ( -- * Unfolding data types Unfolding(..), UnfoldingGuidance(..), UnfoldingSource(..), + ArgDiscount(..), ConMap, ConDiscount(..), -- ** Constructing 'Unfolding's noUnfolding, bootUnfolding, evaldUnfolding, mkOtherCon, @@ -62,12 +63,13 @@ module GHC.Core ( -- ** Predicates and deconstruction on 'Unfolding' unfoldingTemplate, expandUnfolding_maybe, - maybeUnfoldingTemplate, otherCons, + maybeUnfoldingTemplate, maybeUnfoldingGuidance, otherCons, isValueUnfolding, isEvaldUnfolding, isCheapUnfolding, isExpandableUnfolding, isConLikeUnfolding, isCompulsoryUnfolding, isStableUnfolding, isInlineUnfolding, isBootUnfolding, hasCoreUnfolding, hasSomeUnfolding, - canUnfold, neverUnfoldGuidance, isStableSource, + canUnfold, neverUnfoldGuidance, argGuidance, isStableSource, + discountDepth, -- * Annotated expression data types AnnExpr, AnnExpr'(..), AnnBind(..), AnnAlt(..), @@ -120,6 +122,7 @@ import GHC.Utils.Panic.Plain import Data.Data hiding (TyCon) import Data.Int import Data.Word +import GHC.Types.Unique.FM infixl 4 `mkApps`, `mkTyApps`, `mkVarApps`, `App`, `mkCoApps` -- Left associative, so that we can say (f `mkTyApps` xs `mkVarApps` ys) @@ -1367,6 +1370,44 @@ data UnfoldingSource -- Inline absolutely always, however boring the context. +-- Argument use is modeled as a tree +type ConMap a = UniqFM DataCon a + +data ConDiscount = ConDiscount { cd_con :: !DataCon + , cd_discount :: !Int + , cd_arg_discounts :: [ArgDiscount] + } + deriving (Eq) + +instance Outputable ConDiscount where + ppr (ConDiscount c d as) = ppr c <> text ":" <> ppr d <> (ppr as) + +data ArgDiscount + -- Argument is used, either sequed with a single alternative + -- used as argument to a interesting function or in other ways + -- which could make this argument worthwhile to inline. + = SomeArgUse { ad_seq_discount :: !Int } + -- Argument is used to discriminate between case alternatives. + -- We give specific constructors a discount based on the alternative + -- they will select, and provide a generic discount if we know the arg + -- is a value but not what value exactly. + -- Only of the the two discounts might be applied for the same argument. + | DiscSeq { ad_seq_discount :: !Int -- ^ Discount if no specific constructor discount matches + , ad_con_discount :: !(ConMap ConDiscount) -- ^ Discounts for specific constructors + } + -- A discount for the use of a function. + | FunDisc { ad_seq_discount :: !Int, ad_fun :: !Name} + | NoSeqUse + deriving Eq + +instance Outputable ArgDiscount where + ppr (SomeArgUse n)= text "seq:" <> ppr n + ppr (NoSeqUse)= text "lazy use" + ppr (FunDisc d f ) = text "fun-"<>ppr f<>text ":"<> ppr d + ppr (DiscSeq d_seq m) + | isNullUFM m = text "disc:"<> ppr d_seq + | otherwise = sep (punctuate comma ((text "some_con:"<> ppr d_seq) : map ppr (nonDetEltsUFM m))) + -- (text "some_con:"<> ppr d_seq) <> text "||" <> braces (pprUFM m ppr) -- | 'UnfoldingGuidance' says when unfolding should take place data UnfoldingGuidance @@ -1384,13 +1425,13 @@ data UnfoldingGuidance | UnfIfGoodArgs { -- Arose from a normal Id; the info here is the -- result of a simple analysis of the RHS - ug_args :: [Int], -- Discount if the argument is evaluated. + ug_args :: [ArgDiscount], -- Discount if the argument is evaluated. -- (i.e., a simplification will definitely -- be possible). One elt of the list per *value* arg. - ug_size :: Int, -- The "size" of the unfolding. + ug_size :: !Int, -- The "size" of the unfolding. - ug_res :: Int -- Scrutinee discount: the discount to subtract if the thing is in + ug_res :: !Int -- Scrutinee discount: the discount to subtract if the thing is in } -- a context (case (thing args) of ...), -- (where there are the right number of arguments.) @@ -1494,6 +1535,10 @@ maybeUnfoldingTemplate (DFunUnfolding { df_bndrs = bndrs, df_con = con, df_args maybeUnfoldingTemplate _ = Nothing +maybeUnfoldingGuidance :: Unfolding -> Maybe UnfoldingGuidance +maybeUnfoldingGuidance CoreUnfolding { uf_guidance = guidance } = Just guidance +maybeUnfoldingGuidance _ = Nothing + -- | The constructors that the unfolding could never be: -- returns @[]@ if no information is available otherCons :: Unfolding -> [AltCon] @@ -1582,6 +1627,30 @@ neverUnfoldGuidance :: UnfoldingGuidance -> Bool neverUnfoldGuidance UnfNever = True neverUnfoldGuidance _ = False +-- Returns a list of available argument discounts if any. +argGuidance :: UnfoldingGuidance -> [ArgDiscount] +argGuidance UnfIfGoodArgs { ug_args = arg_guides } = arg_guides +argGuidance _ = [] + +discountDepth :: ArgDiscount -> Int +discountDepth dc = case dc of + NoSeqUse -> 0 + FunDisc{} -> 1 + SomeArgUse{} -> 1 + DiscSeq { ad_con_discount = con_dc} -> + let max_con_depth = + nonDetStrictFoldUFM + (\(e :: ConDiscount) max_depth -> + max max_depth + (maximum (1:(map discountDepth (cd_arg_discounts e))))) + 0 + con_dc + in max 1 max_con_depth + + + + + hasCoreUnfolding :: Unfolding -> Bool -- An unfolding "has Core" if it contains a Core expression, which -- may mention free variables. See Note [Fragile unfoldings] @@ -1953,6 +2022,10 @@ bindersOf (Rec pairs) = [binder | (binder, _) <- pairs] bindersOfBinds :: [Bind b] -> [b] bindersOfBinds binds = foldr ((++) . bindersOf) [] binds +{-# INLINE foldBindersOf #-} +foldBindersOf :: (a -> b -> a) -> Bind b -> a -> a +foldBindersOf f b r = foldl' f r (bindersOf b) + rhssOfBind :: Bind b -> [Expr b] rhssOfBind (NonRec _ rhs) = [rhs] rhssOfBind (Rec pairs) = [rhs | (_,rhs) <- pairs] ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -22,6 +22,7 @@ module GHC.Core.Opt.Simplify.Env ( zapSubstEnv, setSubstEnv, bumpCaseDepth, getInScope, setInScopeFromE, setInScopeFromF, setInScopeSet, modifyInScope, addNewInScopeIds, + addNewInScopeId, addNewInScopeBndr, getSimplRules, enterRecGroupRHSs, -- * Substitution results @@ -561,6 +562,20 @@ setInScopeFromE rhs_env here_env = rhs_env { seInScope = seInScope here_env } setInScopeFromF :: SimplEnv -> SimplFloats -> SimplEnv setInScopeFromF env floats = env { seInScope = sfInScope floats } +addNewInScopeId :: SimplEnv -> CoreBndr -> SimplEnv +addNewInScopeId env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) v +-- See Note [Bangs in the Simplifier] + = let !in_scope1 = in_scope `extendInScopeSet` v + !id_subst1 = id_subst `delVarEnv` v + in + env { seInScope = in_scope1, + seIdSubst = id_subst1 } + -- Why delete? Consider + -- let x = a*b in (x, \x -> x+3) + -- We add [x |-> a*b] to the substitution, but we must + -- _delete_ it from the substitution when going inside + -- the (\x -> ...)! + addNewInScopeIds :: SimplEnv -> [CoreBndr] -> SimplEnv -- The new Ids are guaranteed to be freshly allocated addNewInScopeIds env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) vs @@ -576,6 +591,21 @@ addNewInScopeIds env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) v -- _delete_ it from the substitution when going inside -- the (\x -> ...)! +addNewInScopeBndr :: SimplEnv -> CoreBind -> SimplEnv +addNewInScopeBndr env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) b +-- See Note [Bangs in the Simplifier] + = let vs = bindersOf b + !in_scope1 = in_scope `extendInScopeSetList` vs + !id_subst1 = id_subst `delVarEnvList` vs + in + env { seInScope = in_scope1, + seIdSubst = id_subst1 } + -- Why delete? Consider + -- let x = a*b in (x, \x -> x+3) + -- We add [x |-> a*b] to the substitution, but we must + -- _delete_ it from the substitution when going inside + -- the (\x -> ...)! + modifyInScope :: SimplEnv -> CoreBndr -> SimplEnv -- The variable should already be in scope, but -- replace the existing version with this new one ===================================== compiler/GHC/Core/Opt/Simplify/Inline.hs ===================================== @@ -0,0 +1,690 @@ +-- {-# OPTIONS_GHC -ddump-simpl -ddump-to-file -ddump-stg-final -dsuppress-coercions -dsuppress-coercion-types #-} + +module GHC.Core.Opt.Simplify.Inline +where + +import GHC.Prelude + +import GHC.Core +import GHC.Core.Unfold +import GHC.Core.TyCon (isClassTyCon) + +import GHC.Types.Name +import GHC.Types.Id +import GHC.Types.Basic + +import GHC.Utils.Misc +import GHC.Utils.Outputable + +import Data.List ( isPrefixOf ) +import GHC.Utils.Logger +import GHC.Driver.Flags +import GHC.Types.Unique.FM +import GHC.Core.Opt.Simplify.Env +import GHC.Types.Literal +import GHC.Core.DataCon +import GHC.Types.Var +import GHC.Core.Opt.Simplify.Utils +import GHC.Utils.Panic.Plain (assert) +import GHC.Utils.Trace +import GHC.Types.Tickish + +callSiteInline :: Logger + -> UnfoldingOpts + -> Int -- Case depth + -> Id -- The Id + -> Bool -- True <=> unfolding is active + -> Bool -- True if there are no arguments at all (incl type args) + -> [ArgSummary] -- One for each value arg; True if it is interesting + -> CallCtxt -- True <=> continuation is interesting + -> Maybe CoreExpr -- Unfolding, if any +callSiteInline logger !opts !case_depth id active_unfolding lone_variable arg_infos cont_info + = case idUnfolding id of + -- idUnfolding checks for loop-breakers, returning NoUnfolding + -- Things with an INLINE pragma may have an unfolding *and* + -- be a loop breaker (maybe the knot is not yet untied) + CoreUnfolding { uf_tmpl = unf_template + , uf_is_work_free = is_wf + , uf_guidance = guidance, uf_expandable = is_exp } + | active_unfolding -> tryUnfolding logger opts case_depth id lone_variable + arg_infos cont_info unf_template + is_wf is_exp guidance + | otherwise -> traceInline logger opts id "Inactive unfolding:" (ppr id) Nothing + NoUnfolding -> Nothing + BootUnfolding -> Nothing + OtherCon {} -> Nothing + DFunUnfolding {} -> Nothing -- Never unfold a DFun + +-- | Report the inlining of an identifier's RHS to the user, if requested. +traceInline :: Logger -> UnfoldingOpts -> Id -> String -> SDoc -> a -> a +traceInline logger !opts inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. + | enable = logTraceMsg logger str doc result + | otherwise = result + where + enable + | logHasDumpFlag logger Opt_D_dump_verbose_inlinings + = True + | Just prefix <- unfoldingReportPrefix opts + = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] + +{- Note [Avoid inlining into deeply nested cases] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider a function f like this: + + f arg1 arg2 = + case ... + ... -> g arg1 + ... -> g arg2 + +This function is small. So should be safe to inline. +However sometimes this doesn't quite work out like that. +Consider this code: + +f1 arg1 arg2 ... = ... + case _foo of + alt1 -> ... f2 arg1 ... + alt2 -> ... f2 arg2 ... + +f2 arg1 arg2 ... = ... + case _foo of + alt1 -> ... f3 arg1 ... + alt2 -> ... f3 arg2 ... + +f3 arg1 arg2 ... = ... + +... repeats up to n times. And then f1 is +applied to some arguments: + +foo = ... f1 ... + +Initially f2..fn are not interesting to inline so we don't. +However we see that f1 is applied to interesting args. +So it's an obvious choice to inline those: + +foo = + ... + case _foo of + alt1 -> ... f2 ... + alt2 -> ... f2 ... + +As a result we go and inline f2 both mentions of f2 in turn are now applied to interesting +arguments and f2 is small: + +foo = + ... + case _foo of + alt1 -> ... case _foo of + alt1 -> ... f3 ... + alt2 -> ... f3 ... + + alt2 -> ... case _foo of + alt1 -> ... f3 ... + alt2 -> ... f3 ... + +The same thing happens for each binding up to f_n, duplicating the amount of inlining +done in each step. Until at some point we are either done or run out of simplifier +ticks/RAM. This pattern happened #18730. + +To combat this we introduce one more heuristic when weighing inlining decision. +We keep track of a "case-depth". Which increases each time we look inside a case +expression with more than one alternative. + +We then apply a penalty to inlinings based on the case-depth at which they would +be inlined. Bounding the number of inlinings in such a scenario. + +The heuristic can be tuned in two ways: + +* We can ignore the first n levels of case nestings for inlining decisions using + -funfolding-case-threshold. +* The penalty grows linear with the depth. It's computed as size*(depth-threshold)/scaling. + Scaling can be set with -funfolding-case-scaling. + +Some guidance on setting these defaults: + +* A low treshold (<= 2) is needed to prevent exponential cases from spiraling out of + control. We picked 2 for no particular reason. +* Scaling the penalty by any more than 30 means the reproducer from + T18730 won't compile even with reasonably small values of n. Instead + it will run out of runs/ticks. This means to positively affect the reproducer + a scaling <= 30 is required. +* A scaling of >= 15 still causes a few very large regressions on some nofib benchmarks. + (+80% for gc/fulsom, +90% for real/ben-raytrace, +20% for spectral/fibheaps) +* A scaling of >= 25 showed no regressions on nofib. However it showed a number of + (small) regression for compiler perf benchmarks. + +The end result is that we are settling for a scaling of 30, with a threshold of 2. +This gives us minimal compiler perf regressions. No nofib runtime regressions and +will still avoid this pattern sometimes. This is a "safe" default, where we err on +the side of compiler blowup instead of risking runtime regressions. + +For cases where the default falls short the flag can be changed to allow more/less inlining as +needed on a per-module basis. + +-} + +tryUnfolding :: Logger -> UnfoldingOpts -> Int -> Id -> Bool -> [ArgSummary] -> CallCtxt + -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance + -> Maybe CoreExpr +tryUnfolding logger opts !case_depth id lone_variable + arg_infos cont_info unf_template + is_wf is_exp guidance + = case guidance of + UnfNever -> traceInline logger opts id str (text "UnfNever") Nothing + + UnfWhen { ug_arity = uf_arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } + | enough_args && (boring_ok || some_benefit || unfoldingVeryAggressive opts) + -- See Note [INLINE for small functions] (3) + -> traceInline logger opts id str (mk_doc some_benefit empty True) (Just unf_template) + | otherwise + -> traceInline logger opts id str (mk_doc some_benefit empty False) Nothing + where + some_benefit = calc_some_benefit uf_arity + enough_args = (n_val_args >= uf_arity) || (unsat_ok && n_val_args > 0) + + UnfIfGoodArgs { ug_args = arg_discounts, ug_res = res_discount, ug_size = size } + | unfoldingVeryAggressive opts + -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) + | is_wf && some_benefit && small_enough + -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) + | otherwise + -> traceInline logger opts id str (mk_doc some_benefit extra_doc False) Nothing + where + !some_benefit = calc_some_benefit (length arg_discounts) + extra_doc = vcat [ text "case depth =" <+> int case_depth + , text "depth based penalty =" <+> int depth_penalty + , text "discounted size =" <+> int adjusted_size ] + -- See Note [Avoid inlining into deeply nested cases] + depth_treshold = unfoldingCaseThreshold opts + depth_scaling = unfoldingCaseScaling opts + depth_penalty | case_depth <= depth_treshold = 0 + | otherwise = (size * (case_depth - depth_treshold)) `div` depth_scaling + !adjusted_size = size + depth_penalty - discount + !small_enough = adjusted_size <= unfoldingUseThreshold opts + discount = computeDiscount arg_discounts res_discount arg_infos cont_info + + where + mk_doc some_benefit extra_doc yes_or_no + = vcat [ text "arg infos" <+> ppr arg_infos + , text "interesting continuation" <+> ppr cont_info + , text "some_benefit" <+> ppr some_benefit + , text "is exp:" <+> ppr is_exp + , text "is work-free:" <+> ppr is_wf + , text "guidance" <+> ppr guidance + , extra_doc + , text "ANSWER =" <+> if yes_or_no then text "YES" else text "NO"] + + ctx = log_default_dump_context (logFlags logger) + str = "Considering inlining: " ++ showSDocOneLine ctx (ppr id) + n_val_args = length arg_infos + + -- some_benefit is used when the RHS is small enough + -- and the call has enough (or too many) value + -- arguments (ie n_val_args >= arity). But there must + -- be *something* interesting about some argument, or the + -- result context, to make it worth inlining + calc_some_benefit :: Arity -> Bool -- The Arity is the number of args + -- expected by the unfolding + calc_some_benefit uf_arity + | not saturated = interesting_args -- Under-saturated + -- Note [Unsaturated applications] + | otherwise = interesting_args -- Saturated or over-saturated + || interesting_call + where + saturated = n_val_args >= uf_arity + over_saturated = n_val_args > uf_arity + interesting_args = any nonTrivArg arg_infos + -- NB: (any nonTriv arg_infos) looks at the + -- over-saturated args too which is "wrong"; + -- but if over-saturated we inline anyway. + + interesting_call + | over_saturated + = True + | otherwise + = case cont_info of + CaseCtxt -> not (lone_variable && is_exp) -- Note [Lone variables] + ValAppCtxt -> True -- Note [Cast then apply] + RuleArgCtxt -> uf_arity > 0 -- See Note [RHS of lets] + DiscArgCtxt -> uf_arity > 0 -- Note [Inlining in ArgCtxt] + RhsCtxt NonRecursive + -> uf_arity > 0 -- See Note [RHS of lets] + _other -> False -- See Note [Nested functions] + + +{- Note [RHS of lets] +~~~~~~~~~~~~~~~~~~~~~ +When the call is the argument of a function with a RULE, or the RHS of a let, +we are a little bit keener to inline (in tryUnfolding). For example + f y = (y,y,y) + g y = let x = f y in ...(case x of (a,b,c) -> ...) ... +We'd inline 'f' if the call was in a case context, and it kind-of-is, +only we can't see it. Also + x = f v +could be expensive whereas + x = case v of (a,b) -> a +is patently cheap and may allow more eta expansion. + +So, in `interesting_call` in `tryUnfolding`, we treat the RHS of a +/non-recursive/ let as not-totally-boring. A /recursive/ let isn't +going be inlined so there is much less point. Hence the (only reason +for the) RecFlag in RhsCtxt + +Note [Unsaturated applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When a call is not saturated, we *still* inline if one of the +arguments has interesting structure. That's sometimes very important. +A good example is the Ord instance for Bool in Base: + + Rec { + $fOrdBool =GHC.Classes.D:Ord + @ Bool + ... + $cmin_ajX + + $cmin_ajX [Occ=LoopBreaker] :: Bool -> Bool -> Bool + $cmin_ajX = GHC.Classes.$dmmin @ Bool $fOrdBool + } + +But the defn of GHC.Classes.$dmmin is: + + $dmmin :: forall a. GHC.Classes.Ord a => a -> a -> a + {- Arity: 3, HasNoCafRefs, Strictness: SLL, + Unfolding: (\ @ a $dOrd :: GHC.Classes.Ord a x :: a y :: a -> + case @ a GHC.Classes.<= @ a $dOrd x y of wild { + GHC.Types.False -> y GHC.Types.True -> x }) -} + +We *really* want to inline $dmmin, even though it has arity 3, in +order to unravel the recursion. + + +Note [Things to watch] +~~~~~~~~~~~~~~~~~~~~~~ +* { y = I# 3; x = y `cast` co; ...case (x `cast` co) of ... } + Assume x is exported, so not inlined unconditionally. + Then we want x to inline unconditionally; no reason for it + not to, and doing so avoids an indirection. + +* { x = I# 3; ....f x.... } + Make sure that x does not inline unconditionally! + Lest we get extra allocation. + +Note [Inlining an InlineRule] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +An InlineRules is used for + (a) programmer INLINE pragmas + (b) inlinings from worker/wrapper + +For (a) the RHS may be large, and our contract is that we *only* inline +when the function is applied to all the arguments on the LHS of the +source-code defn. (The uf_arity in the rule.) + +However for worker/wrapper it may be worth inlining even if the +arity is not satisfied (as we do in the CoreUnfolding case) so we don't +require saturation. + +Note [Nested functions] +~~~~~~~~~~~~~~~~~~~~~~~ +At one time we treated a call of a non-top-level function as +"interesting" (regardless of how boring the context) in the hope +that inlining it would eliminate the binding, and its allocation. +Specifically, in the default case of interesting_call we had + _other -> not is_top && uf_arity > 0 + +But actually postInlineUnconditionally does some of this and overall +it makes virtually no difference to nofib. So I simplified away this +special case + +Note [Cast then apply] +~~~~~~~~~~~~~~~~~~~~~~ +Consider + myIndex = __inline_me ( (/\a. ) |> co ) + co :: (forall a. a -> a) ~ (forall a. T a) + ... /\a.\x. case ((myIndex a) |> sym co) x of { ... } ... + +We need to inline myIndex to unravel this; but the actual call (myIndex a) has +no value arguments. The ValAppCtxt gives it enough incentive to inline. + +Note [Inlining in ArgCtxt] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +The condition (arity > 0) here is very important, because otherwise +we end up inlining top-level stuff into useless places; eg + x = I# 3# + f = \y. g x +This can make a very big difference: it adds 16% to nofib 'integer' allocs, +and 20% to 'power'. + +At one stage I replaced this condition by 'True' (leading to the above +slow-down). The motivation was test eyeball/inline1.hs; but that seems +to work ok now. + +NOTE: arguably, we should inline in ArgCtxt only if the result of the +call is at least CONLIKE. At least for the cases where we use ArgCtxt +for the RHS of a 'let', we only profit from the inlining if we get a +CONLIKE thing (modulo lets). + +Note [Lone variables] See also Note [Interaction of exprIsWorkFree and lone variables] +~~~~~~~~~~~~~~~~~~~~~ which appears below +The "lone-variable" case is important. I spent ages messing about +with unsatisfactory variants, but this is nice. The idea is that if a +variable appears all alone + + as an arg of lazy fn, or rhs BoringCtxt + as scrutinee of a case CaseCtxt + as arg of a fn ArgCtxt +AND + it is bound to a cheap expression + +then we should not inline it (unless there is some other reason, +e.g. it is the sole occurrence). That is what is happening at +the use of 'lone_variable' in 'interesting_call'. + +Why? At least in the case-scrutinee situation, turning + let x = (a,b) in case x of y -> ... +into + let x = (a,b) in case (a,b) of y -> ... +and thence to + let x = (a,b) in let y = (a,b) in ... +is bad if the binding for x will remain. + +Another example: I discovered that strings +were getting inlined straight back into applications of 'error' +because the latter is strict. + s = "foo" + f = \x -> ...(error s)... + +Fundamentally such contexts should not encourage inlining because, provided +the RHS is "expandable" (see Note [exprIsExpandable] in GHC.Core.Utils) the +context can ``see'' the unfolding of the variable (e.g. case or a +RULE) so there's no gain. + +However, watch out: + + * Consider this: + foo = _inline_ (\n. [n]) + bar = _inline_ (foo 20) + baz = \n. case bar of { (m:_) -> m + n } + Here we really want to inline 'bar' so that we can inline 'foo' + and the whole thing unravels as it should obviously do. This is + important: in the NDP project, 'bar' generates a closure data + structure rather than a list. + + So the non-inlining of lone_variables should only apply if the + unfolding is regarded as cheap; because that is when exprIsConApp_maybe + looks through the unfolding. Hence the "&& is_wf" in the + InlineRule branch. + + * Even a type application or coercion isn't a lone variable. + Consider + case $fMonadST @ RealWorld of { :DMonad a b c -> c } + We had better inline that sucker! The case won't see through it. + + For now, I'm treating treating a variable applied to types + in a *lazy* context "lone". The motivating example was + f = /\a. \x. BIG + g = /\a. \y. h (f a) + There's no advantage in inlining f here, and perhaps + a significant disadvantage. Hence some_val_args in the Stop case + +Note [Interaction of exprIsWorkFree and lone variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The lone-variable test says "don't inline if a case expression +scrutinises a lone variable whose unfolding is cheap". It's very +important that, under these circumstances, exprIsConApp_maybe +can spot a constructor application. So, for example, we don't +consider + let x = e in (x,x) +to be cheap, and that's good because exprIsConApp_maybe doesn't +think that expression is a constructor application. + +In the 'not (lone_variable && is_wf)' test, I used to test is_value +rather than is_wf, which was utterly wrong, because the above +expression responds True to exprIsHNF, which is what sets is_value. + +This kind of thing can occur if you have + + {-# INLINE foo #-} + foo = let x = e in (x,x) + +which Roman did. + +Note [Minimum value discount] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We always give *some* benefit to value arguments. +A discount of 10 per arg because we replace the arguments +and another of 10 if it's some non-trivial value. +However when computing unfolding guidance we might have come to +the conclusion that certain argument values deservere little or no +discount. But we want to chance of inlining to only ever increase as +more is known about the argument to keep things more predictable. So +we always give at least 10 discount if the argument is a value. No matter +what the actual value is. +-} + + + +computeDiscount :: [ArgDiscount] -> Int -> [ArgSummary] -> CallCtxt + -> Int +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 + + + 10 * applied_arg_length + -- Discount of 10 for each arg supplied, + -- because the result replaces the call + + + total_arg_discount + res_discount' + where + (applied_arg_length,total_arg_discount) = zipWithSumLength arg_discounts arg_infos + -- actual_arg_discounts = zipWith mk_arg_discount (arg_discounts) arg_infos + -- total_arg_discount = sum actual_arg_discounts + + -- See Note [Minimum value discount] + mk_arg_discount :: ArgDiscount -> ArgSummary -> Int + mk_arg_discount _ TrivArg = 0 + mk_arg_discount _ NonTrivArg = 10 + mk_arg_discount NoSeqUse _ = 10 + mk_arg_discount discount ValueArg = max 10 (ad_seq_discount discount) + mk_arg_discount (DiscSeq seq_discount con_discounts) (ConArg con args) + + -- There is a discount specific to this constructor, use that. + | Just (ConDiscount _ branch_dc arg_discounts) <- lookupUFM con_discounts con + = max 10 $ max seq_discount (branch_dc + (sum $ zipWith mk_arg_discount arg_discounts args)) + + -- Otherwise give it the generic seq discount + | otherwise = max 10 seq_discount + mk_arg_discount (SomeArgUse d) ConArg{} = max 10 d + mk_arg_discount (FunDisc d _) (ConArg{}) + -- How can this arise? With dictionary constructors for example. + -- We see C:Show foo bar and give it a FunDisc for being applied + -- like a function. + -- But when constructing ArgSummaries we treat it as constructor + -- since well it is one. This is harmless, but a bit odd for sure. + -- We just treat it like any other boring ValueArg here. + = -- pprTrace "Function discount for con arg" (ppr arg_infos) + max 10 d + + -- zipWithSumLength xs ys = (length $ zip xs ys, sum $ zipWith _ xs ys) + zipWithSumLength :: [ArgDiscount] -> [ArgSummary] -> (Int, Int) + zipWithSumLength dcs args = go 0 0 dcs args + where + go !length !discount (dc:dcs) (arg:args) = + let arg_discount = mk_arg_discount dc arg + in go (1+length) (discount + arg_discount) dcs args + go l d [] _ = (l,d) + go l d _ [] = (l,d) + + res_discount' + | LT <- arg_discounts `compareLength` arg_infos + = res_discount -- Over-saturated + | otherwise + = case cont_info of + BoringCtxt -> 0 + CaseCtxt -> res_discount -- Presumably a constructor + ValAppCtxt -> res_discount -- Presumably a function + _ -> 40 `min` res_discount + -- ToDo: this 40 `min` res_discount doesn't seem right + -- for DiscArgCtxt it shouldn't matter because the function will + -- get the arg discount for any non-triv arg + -- for RuleArgCtxt we do want to be keener to inline; but not only + -- constructor results + -- for RhsCtxt I suppose that exposing a data con is good in general + -- And 40 seems very arbitrary + -- + -- res_discount can be very large when a function returns + -- constructors; but we only want to invoke that large discount + -- when there's a case continuation. + -- Otherwise we, rather arbitrarily, threshold it. Yuk. + -- But we want to avoid inlining large functions that return + -- constructors into contexts that are simply "interesting" + +{- Note [Interesting arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +An argument is interesting if it deserves a discount for unfoldings +with a discount in that argument position. The idea is to avoid +unfolding a function that is applied only to variables that have no +unfolding (i.e. they are probably lambda bound): f x y z There is +little point in inlining f here. + +Generally, *values* (like (C a b) and (\x.e)) deserve discounts. But +we must look through lets, eg (let x = e in C a b), because the let will +float, exposing the value, if we inline. That makes it different to +exprIsHNF. + +Before 2009 we said it was interesting if the argument had *any* structure +at all; i.e. (hasSomeUnfolding v). But does too much inlining; see #3016. + +But we don't regard (f x y) as interesting, unless f is unsaturated. +If it's saturated and f hasn't inlined, then it's probably not going +to now! + +Note [Conlike is interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f d = ...((*) d x y)... + ... f (df d')... +where df is con-like. Then we'd really like to inline 'f' so that the +rule for (*) (df d) can fire. To do this + a) we give a discount for being an argument of a class-op (eg (*) d) + b) we say that a con-like argument (eg (df d)) is interesting +-} + +interestingArg :: SimplEnv -> CoreExpr -> ArgSummary +-- See Note [Interesting arguments] +interestingArg env e = + go env depth_limit 0 e + where + depth_limit = unfoldingMaxDiscountDepth . sm_uf_opts . seMode $ env + + -- n is # value args to which the expression is applied + go :: SimplEnv -> Int -> Int -> CoreExpr -> ArgSummary + go !_env max_depth _n !_ + | max_depth <= 0 = TrivArg + go env depth n (Var v) + = case substId env v of + DoneId v' -> go_var depth n v' + DoneEx e _ -> go (zapSubstEnv env) depth n e + ContEx tvs cvs ids e -> go (setSubstEnv env tvs cvs ids) depth n e + + go _ _depth _ (Lit l) + | isLitRubbish l = TrivArg -- Leads to unproductive inlining in WWRec, #20035 + | otherwise = ValueArg + go _ _depth _ (Type _) = TrivArg + go _ _depth _ (Coercion _) = TrivArg + go env depth n (App fn (Type _)) = go env depth n fn + go env depth n e@(App _fn _arg) + | (fn,arg_summaries,_ticks) <- mapArgsTicksVal (go env (depth-1) 0) e + = let fn_summary = go env depth (n + length arg_summaries) fn + in case fn_summary of + ConArg con fn_args + | isClassTyCon (dataConTyCon con) -> ValueArg + | otherwise -> + assert (null fn_args) $ + ConArg con arg_summaries + _ -> fn_summary + + go env depth n (Tick _ a) = go env depth n a + go env depth n (Cast e _) = go env depth n e + go env depth n (Lam v e) + | isTyVar v = go env depth n e + | n>0 = NonTrivArg -- (\x.b) e is NonTriv + | otherwise = ValueArg + go _ _depth _ (Case {}) = NonTrivArg + go env depth n (Let b e) = case go env' depth n e of + ValueArg -> ValueArg + c at ConArg{} -> c + _ -> NonTrivArg + where + env' = env `addNewInScopeBndr` b + + go_var depth n v + | Just rhs <- maybeUnfoldingTemplate (idUnfolding v) + , (f, arg_summaries, _ticks) <- mapArgsTicksVal (go env (depth-1) 0) rhs + , Var f' <- varView f + , Just con <- isDataConId_maybe f' + , not (isClassTyCon $ dataConTyCon con) + = + -- pprTrace "ConArg1" (ppr $ ConArg con $ map (go env 0) args) $ + ConArg con arg_summaries + + | Just con <- isDataConId_maybe v + = ConArg con [] + | isConLikeId v = ValueArg -- Experimenting with 'conlike' rather that + -- data constructors here + | idArity v > n = ValueArg -- Catches (eg) primops with arity but no unfolding + | n > 0 = NonTrivArg -- Saturated or unknown call + | conlike_unfolding = ValueArg -- n==0; look for an interesting unfolding + -- See Note [Conlike is interesting] + | otherwise = TrivArg -- n==0, no useful unfolding + where + conlike_unfolding = isConLikeUnfolding (idUnfolding v) + + varView (Cast e _) = e + varView (Tick _ e) = e + varView e = e + +-- | Like @collectArgs@, but maps over the arguments at the same time. +-- and also looks through casts. +mapArgsTicksVal :: (Expr b -> c) -> Expr b + -> (Expr b, [c], [CoreTickish]) +mapArgsTicksVal fm expr + = go expr [] [] + where + go (App f a) as ts + | isValArg a = go f (fm a:as) ts + | otherwise = go f as ts + go (Tick t e) as ts = go e as (t:ts) + go (Cast e _) as ts = go e as ts + go e as ts = (e, as, reverse ts) + + +contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) +-- Summarises value args, discards type args and coercions +-- The returned continuation of the call is only used to +-- answer questions like "are you interesting?" +contArgs cont + | lone cont = (True, [], cont) + | otherwise = go [] cont + where + lone (ApplyToTy {}) = False -- See Note [Lone variables] in GHC.Core.Unfold + lone (ApplyToVal {}) = False -- NB: even a type application or cast + lone (CastIt {}) = False -- stops it being "lone" + lone _ = True + + go args (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = k }) + = go (is_interesting arg se : args) k + go args (ApplyToTy { sc_cont = k }) = go args k + go args (CastIt _ k) = go args k + go args k = (False, reverse args, k) + + -- is_interesting arg _se = arg + is_interesting arg se = interestingArg se arg + -- Do *not* use short-cutting substitution here + -- because we want to get as much IdInfo as possible ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -74,6 +74,7 @@ import GHC.Utils.Logger import GHC.Utils.Misc import Control.Monad +import GHC.Core.Opt.Simplify.Inline {- The guts of the simplifier is in this module, but the driver loop for @@ -3568,7 +3569,7 @@ mkDupableContWithDmds env _ do { let rhs_ty = contResultType cont (m,arg_ty,_) = splitFunTy fun_ty ; arg_bndr <- newId (fsLit "arg") m arg_ty - ; let env' = env `addNewInScopeIds` [arg_bndr] + ; let env' = env `addNewInScopeId` arg_bndr ; (floats, join_rhs) <- rebuildCall env' (addValArgTo fun (Var arg_bndr) fun_ty) cont ; mkDupableStrictBind env' arg_bndr (wrapFloats floats join_rhs) rhs_ty } where @@ -3670,7 +3671,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr , ai_rules = Nothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd - , ai_discs = repeat 0 } + , ai_discs = repeat NoSeqUse } ; return ( addJoinFloats (emptyFloats env) $ unitJoinFloat $ NonRec join_bndr $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -24,7 +24,7 @@ module GHC.Core.Opt.Simplify.Utils ( SimplCont(..), DupFlag(..), StaticEnv, isSimplified, contIsStop, contIsDupable, contResultType, contHoleType, contHoleScaling, - contIsTrivial, contArgs, contIsRhs, + contIsTrivial, contIsRhs, countArgs, mkBoringStop, mkRhsStop, mkLazyArgStop, interestingCallContext, @@ -44,7 +44,6 @@ module GHC.Core.Opt.Simplify.Utils ( import GHC.Prelude import GHC.Core -import GHC.Types.Literal ( isLitRubbish ) import GHC.Core.Opt.Simplify.Env import GHC.Core.Opt.Stats ( Tick(..) ) import qualified GHC.Core.Subst @@ -320,8 +319,9 @@ data ArgInfo -- that the function diverges after being given -- that number of args - ai_discs :: [Int] -- Discounts for remaining value arguments (beyong ai_args) - -- non-zero => be keener to inline + ai_discs :: [ArgDiscount] + -- Discounts for remaining value arguments (beyong ai_args) + -- non-NoSeqUse => be keener to inline -- Always infinite } @@ -525,29 +525,6 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 -contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) --- Summarises value args, discards type args and coercions --- The returned continuation of the call is only used to --- answer questions like "are you interesting?" -contArgs cont - | lone cont = (True, [], cont) - | otherwise = go [] cont - where - lone (ApplyToTy {}) = False -- See Note [Lone variables] in GHC.Core.Unfold - lone (ApplyToVal {}) = False -- NB: even a type application or cast - lone (CastIt {}) = False -- stops it being "lone" - lone _ = True - - go args (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = k }) - = go (is_interesting arg se : args) k - go args (ApplyToTy { sc_cont = k }) = go args k - go args (CastIt _ k) = go args k - go args k = (False, reverse args, k) - - is_interesting arg se = interestingArg se arg - -- Do *not* use short-cutting substitution here - -- because we want to get as much IdInfo as possible - -- | Describes how the 'SimplCont' will evaluate the hole as a 'SubDemand'. -- This can be more insightful than the limited syntactic context that -- 'SimplCont' provides, because the 'Stop' constructor might carry a useful @@ -597,14 +574,14 @@ mkArgInfo env fun rules n_val_args call_cont = ArgInfo { ai_fun = fun , ai_args = [] , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_encl = computeArgShapeContext rules call_cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where fun_rules = mkFunRules rules - vanilla_discounts, arg_discounts :: [Int] - vanilla_discounts = repeat 0 + vanilla_discounts, arg_discounts :: [ArgDiscount] + vanilla_discounts = repeat NoSeqUse arg_discounts = case idUnfolding fun of CoreUnfolding {uf_guidance = UnfIfGoodArgs {ug_args = discounts}} -> discounts ++ vanilla_discounts @@ -758,14 +735,14 @@ lazyArgContext :: ArgInfo -> CallCtxt -- Use this for lazy arguments lazyArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs }) | encl_rules = RuleArgCtxt - | disc:_ <- discs, disc > 0 = DiscArgCtxt -- Be keener here + | disc:_ <- discs, disc /= NoSeqUse = DiscArgCtxt -- Be keener here | otherwise = BoringCtxt -- Nothing interesting strictArgContext :: ArgInfo -> CallCtxt strictArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs }) -- Use this for strict arguments | encl_rules = RuleArgCtxt - | disc:_ <- discs, disc > 0 = DiscArgCtxt -- Be keener here + | disc:_ <- discs, disc /= NoSeqUse = DiscArgCtxt -- Be keener here | otherwise = RhsCtxt NonRecursive -- Why RhsCtxt? if we see f (g x), and f is strict, we -- want to be a bit more eager to inline g, because it may @@ -814,7 +791,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +computeArgShapeContext :: [CoreRule] -> SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -823,7 +800,7 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) -- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- call_cont argument to computeArgShapeContext -- -- The ai-rules flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f @@ -833,9 +810,9 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined -- --- The call_cont passed to interestingArgContext is the context of +-- The call_cont passed to computeArgShapeContext is the context of -- the call itself, e.g. g in the example above -interestingArgContext rules call_cont +computeArgShapeContext rules call_cont = notNull rules || enclosing_fn_has_rules where enclosing_fn_has_rules = go call_cont @@ -850,78 +827,7 @@ interestingArgContext rules call_cont go (Stop _ _ _) = False go (TickIt _ c) = go c -{- Note [Interesting arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An argument is interesting if it deserves a discount for unfoldings -with a discount in that argument position. The idea is to avoid -unfolding a function that is applied only to variables that have no -unfolding (i.e. they are probably lambda bound): f x y z There is -little point in inlining f here. - -Generally, *values* (like (C a b) and (\x.e)) deserve discounts. But -we must look through lets, eg (let x = e in C a b), because the let will -float, exposing the value, if we inline. That makes it different to -exprIsHNF. - -Before 2009 we said it was interesting if the argument had *any* structure -at all; i.e. (hasSomeUnfolding v). But does too much inlining; see #3016. -But we don't regard (f x y) as interesting, unless f is unsaturated. -If it's saturated and f hasn't inlined, then it's probably not going -to now! - -Note [Conlike is interesting] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider - f d = ...((*) d x y)... - ... f (df d')... -where df is con-like. Then we'd really like to inline 'f' so that the -rule for (*) (df d) can fire. To do this - a) we give a discount for being an argument of a class-op (eg (*) d) - b) we say that a con-like argument (eg (df d)) is interesting --} - -interestingArg :: SimplEnv -> CoreExpr -> ArgSummary --- See Note [Interesting arguments] -interestingArg env e = go env 0 e - where - -- n is # value args to which the expression is applied - go env n (Var v) - = case substId env v of - DoneId v' -> go_var n v' - DoneEx e _ -> go (zapSubstEnv env) n e - ContEx tvs cvs ids e -> go (setSubstEnv env tvs cvs ids) n e - - go _ _ (Lit l) - | isLitRubbish l = TrivArg -- Leads to unproductive inlining in WWRec, #20035 - | otherwise = ValueArg - go _ _ (Type _) = TrivArg - go _ _ (Coercion _) = TrivArg - go env n (App fn (Type _)) = go env n fn - go env n (App fn _) = go env (n+1) fn - go env n (Tick _ a) = go env n a - go env n (Cast e _) = go env n e - go env n (Lam v e) - | isTyVar v = go env n e - | n>0 = NonTrivArg -- (\x.b) e is NonTriv - | otherwise = ValueArg - go _ _ (Case {}) = NonTrivArg - go env n (Let b e) = case go env' n e of - ValueArg -> ValueArg - _ -> NonTrivArg - where - env' = env `addNewInScopeIds` bindersOf b - - go_var n v - | isConLikeId v = ValueArg -- Experimenting with 'conlike' rather that - -- data constructors here - | idArity v > n = ValueArg -- Catches (eg) primops with arity but no unfolding - | n > 0 = NonTrivArg -- Saturated or unknown call - | conlike_unfolding = ValueArg -- n==0; look for an interesting unfolding - -- See Note [Conlike is interesting] - | otherwise = TrivArg -- n==0, no useful unfolding - where - conlike_unfolding = isConLikeUnfolding (idUnfolding v) {- ************************************************************************ ===================================== compiler/GHC/Core/Ppr.hs ===================================== @@ -614,7 +614,8 @@ instance Outputable UnfoldingGuidance where text "boring_ok=" <> ppr boring_ok) ppr (UnfIfGoodArgs { ug_args = cs, ug_size = size, ug_res = discount }) = hsep [ text "IF_ARGS", - brackets (hsep (map int cs)), + ppUnlessOption sdocSuppressUnfoldingGuidance + (brackets (hsep (map ppr cs))), int size, int discount ] ===================================== compiler/GHC/Core/Seq.hs ===================================== @@ -23,6 +23,8 @@ import GHC.Types.Var( varType, tyVarKind ) import GHC.Core.Type( seqType, isTyVar ) import GHC.Core.Coercion( seqCo ) import GHC.Types.Id( idInfo ) +import GHC.Utils.Misc (seqList) +import GHC.Types.Unique.FM (seqEltsUFM) -- | Evaluate all the fields of the 'IdInfo' that are generally demanded by the -- compiler @@ -112,5 +114,15 @@ seqUnfolding (CoreUnfolding { uf_tmpl = e, uf_is_top = top, seqUnfolding _ = () seqGuidance :: UnfoldingGuidance -> () -seqGuidance (UnfIfGoodArgs ns n b) = n `seq` sum ns `seq` b `seq` () +seqGuidance (UnfIfGoodArgs ns n b) = n `seq` (seqList (map seqArgDiscount ns) ()) `seq` b `seq` () seqGuidance _ = () + +-- seqTopDiscount :: (a, ArgDiscount) -> () +-- seqTopDiscount (!_,dc) = seqArgDiscount dc + +seqArgDiscount :: ArgDiscount -> () +seqArgDiscount (DiscSeq !_ sub_args) = seqEltsUFM seqConDiscount sub_args +seqArgDiscount !_ = () + +seqConDiscount :: ConDiscount -> () +seqConDiscount (ConDiscount !_ !_ sub_args) = seqList (map seqArgDiscount sub_args) () \ No newline at end of file ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -26,20 +26,19 @@ module GHC.Core.Unfold ( updateFunAppDiscount, updateDictDiscount, updateVeryAggressive, updateCaseScaling, updateCaseThreshold, updateReportPrefix, + updateMaxDiscountDepth, updateMaxGuideDepth, - ArgSummary(..), + ArgSummary(..), nonTrivArg, couldBeSmallEnoughToInline, inlineBoringOk, smallEnoughToInline, - callSiteInline, CallCtxt(..), + CallCtxt(..), calcUnfoldingGuidance ) where import GHC.Prelude -import GHC.Driver.Flags - import GHC.Core import GHC.Core.Utils import GHC.Types.Id @@ -51,16 +50,19 @@ import GHC.Types.RepType ( isZeroBitTy ) import GHC.Types.Basic ( Arity, RecFlag(..) ) import GHC.Core.Type import GHC.Builtin.Names -import GHC.Data.Bag -import GHC.Utils.Logger import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Types.ForeignCall -import GHC.Types.Name import GHC.Types.Tickish import qualified Data.ByteString as BS -import Data.List (isPrefixOf) +import GHC.Types.Unique.FM +import Data.Maybe +import GHC.Types.Var.Env +import GHC.Utils.Panic.Plain (assert) +import GHC.Data.Graph.UnVar +import GHC.Utils.Trace (pprTraceDebug) + -- | Unfolding options @@ -88,6 +90,11 @@ data UnfoldingOpts = UnfoldingOpts , unfoldingReportPrefix :: !(Maybe String) -- ^ Only report inlining decisions for names with this prefix + + , unfoldingMaxDiscountDepth :: !Int + -- ^ When considering unfolding a definition look this deep + -- into the applied arguments and into nested argument use. + } defaultUnfoldingOpts :: UnfoldingOpts @@ -122,6 +129,8 @@ defaultUnfoldingOpts = UnfoldingOpts -- Don't filter inlining decision reports , unfoldingReportPrefix = Nothing + + , unfoldingMaxDiscountDepth = 20 } -- Helpers for "GHC.Driver.Session" @@ -151,6 +160,10 @@ updateCaseScaling n opts = opts { unfoldingCaseScaling = n } updateReportPrefix :: Maybe String -> UnfoldingOpts -> UnfoldingOpts updateReportPrefix n opts = opts { unfoldingReportPrefix = n } +updateMaxDiscountDepth :: Int -> UnfoldingOpts -> UnfoldingOpts +updateMaxDiscountDepth n opts = opts { unfoldingMaxDiscountDepth = n } + + {- Note [Occurrence analysis of unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -258,17 +271,11 @@ calcUnfoldingGuidance opts is_top_bottoming expr val_bndrs = filter isId bndrs n_val_bndrs = length val_bndrs - mk_discount :: Bag (Id,Int) -> Id -> Int - mk_discount cbs bndr = foldl' combine 0 cbs - where - combine acc (bndr', disc) - | bndr == bndr' = acc `plus_disc` disc - | otherwise = acc - - plus_disc :: Int -> Int -> Int - plus_disc | isFunTy (idType bndr) = max - | otherwise = (+) - -- See Note [Function and non-function discounts] + mk_discount :: VarEnv ArgDiscount -> Id -> (ArgDiscount) + mk_discount cbs bndr = + let !dc = lookupWithDefaultVarEnv cbs NoSeqUse bndr + -- !depth = discountDepth dc + in (dc) {- Note [Inline unsafeCoerce] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -402,6 +409,39 @@ the constructor would lead to a separate allocation instead of just sharing the wrapper closure. The solution: don’t ignore coercion arguments after all. + +Note [Nested discounts] +~~~~~~~~~~~~~~~~~~~~~~~ +If we have code like: + +f :: Either Bool Int -> Int +f x = case x of + Left l -> case l of + True -> 1 + False -> sum [1..200] :: Int + Right r -> case r of + r -> r + succ r + +What should the discount be? I argue it should be a discount *tree* like this: + [some_con:62, + Left:43 + [some_con:30, False:10[], True:49[]], + Right:70 + [some_con:20, GHC.Types.I#:11[disc:30]] + ] + +How can we compute this? While we traverse the expression if we see a case on a interesting +binder (e.g. x): +* We look at all the alternatives(Left,Right), treating the constructor bound vars(l,r) as + additional interesting binders for their rhss. +* We compute a default discount `some_con` which assumes we will statically choose the largest + alternative if we inline. +* We compute specific discounts for each constructor alternative by attributing any + discount on alternative binders(l,r) to the constructor this alternative is matching on. +* The discounts for the whole case are then represented by the combination of the flat default discount + as well as a list of constructor specific discounts, which carry inside them the discounts for their + arguments. + -} uncondInline :: CoreExpr -> Arity -> Int -> Bool @@ -412,6 +452,7 @@ uncondInline rhs arity size | arity > 0 = size <= 10 * (arity + 1) -- See Note [INLINE for small functions] (1) | otherwise = exprIsTrivial rhs -- See Note [INLINE for small functions] (4) +-- {-# NOINLINE sizeExpr #-} sizeExpr :: UnfoldingOpts -> Int -- Bomb out if it gets bigger than this -> [Id] -- Arguments; we're interested in which of these @@ -423,81 +464,107 @@ sizeExpr :: UnfoldingOpts -- Forcing bOMB_OUT_SIZE early prevents repeated -- unboxing of the Int argument. -sizeExpr opts !bOMB_OUT_SIZE top_args expr - = size_up expr +sizeExpr opts !bOMB_OUT_SIZE top_args' expr + = size_up depth_limit (mkUnVarSet top_args') expr where - size_up (Cast e _) = size_up e - size_up (Tick _ e) = size_up e - size_up (Type _) = sizeZero -- Types cost nothing - size_up (Coercion _) = sizeZero - size_up (Lit lit) = sizeN (litSize lit) - size_up (Var f) | isZeroBitId f = sizeZero - -- Make sure we get constructor discounts even - -- on nullary constructors - | otherwise = size_up_call f [] 0 - - size_up (App fun arg) - | isTyCoArg arg = size_up fun - | otherwise = size_up arg `addSizeNSD` - size_up_app fun [arg] (if isZeroBitExpr arg then 1 else 0) - - size_up (Lam b e) - | isId b && not (isZeroBitId b) = lamScrutDiscount opts (size_up e `addSizeN` 10) - | otherwise = size_up e - - size_up (Let (NonRec binder rhs) body) - = size_up_rhs (binder, rhs) `addSizeNSD` - size_up body `addSizeN` + depth_limit = unfoldingMaxDiscountDepth opts + size_up :: Int -> UnVarSet -> Expr Var -> ExprSize + size_up !depth !arg_comps (Cast e _) = size_up depth arg_comps e + size_up !depth arg_comps (Tick _ e) = size_up depth arg_comps e + size_up !_depth _arg_comps (Type _) = sizeZero -- Types cost nothing + size_up !_depth _arg_comps (Coercion _) = sizeZero + size_up !_depth _arg_comps (Lit lit) = sizeN (litSize lit) + size_up !_depth arg_comps (Var f) | isZeroBitId f = sizeZero + -- Make sure we get constructor discounts even + -- on nullary constructors + | otherwise = size_up_call arg_comps f [] 0 + + size_up !depth arg_comps (App fun arg) + | isTyCoArg arg = size_up depth arg_comps fun + | otherwise = size_up depth arg_comps arg `addSizeNSD` + size_up_app depth arg_comps fun [arg] (if isZeroBitExpr arg then 1 else 0) + + size_up !depth arg_comps (Lam b e) + | isId b && not (isZeroBitId b) = lamScrutDiscount opts (size_up depth (delUnVarSet arg_comps b) e `addSizeN` 10) + | otherwise = size_up depth (delUnVarSet arg_comps b) e + + size_up !depth arg_comps (Let (NonRec binder rhs) body) + = let arg_comps' = delUnVarSet arg_comps binder + in + size_up_rhs depth arg_comps' (binder, rhs) `addSizeNSD` + size_up depth arg_comps' body `addSizeN` size_up_alloc binder - size_up (Let (Rec pairs) body) - = foldr (addSizeNSD . size_up_rhs) - (size_up body `addSizeN` sum (map (size_up_alloc . fst) pairs)) + size_up !depth arg_comps (Let (Rec pairs) body) + = let lhs_bnds = map fst pairs + arg_comps' = delUnVarSetList arg_comps lhs_bnds + in + foldr (addSizeNSD . (size_up_rhs depth arg_comps')) + (size_up depth arg_comps' body `addSizeN` sum (map (size_up_alloc . fst) pairs)) pairs - size_up (Case e _ _ alts) + size_up !depth arg_comps (Case e _ _ alts) | null alts - = size_up e -- case e of {} never returns, so take size of scrutinee + = size_up depth arg_comps e -- case e of {} never returns, so take size of scrutinee - size_up (Case e _ _ alts) + size_up !depth arg_comps (Case e _ _ alts) -- Now alts is non-empty - | Just v <- is_top_arg e -- We are scrutinising an argument variable + -- We are scrutinising an argument variable or a subcomponent thereof. + | Just v <- is_top_arg e = let - alt_sizes = map size_up_alt alts - - -- alts_size tries to compute a good discount for - -- the case when we are scrutinising an argument variable + -- Compute size of alternatives + alt_sizes = map (size_up_alt depth (Just v) arg_comps) alts + + -- Apply a discount for a given constructor that brings the size down to just + -- the size of the alternative. + alt_size_discount tot_size (Alt (DataAlt con) alt_bndrs _rhs) (SizeIs alt_size _ _) = + let trim_discount = max 10 $ tot_size - alt_size + in Just (unitUFM con (ConDiscount con trim_discount (map (const NoSeqUse) alt_bndrs))) + alt_size_discount _tot_size _ _alt_size = Nothing + + -- Add up discounts from the alternatives + added_alt_sizes = (foldr1 addAltSize alt_sizes) + -- Compute size of the largest rhs + largest_alt_size = (foldr (maxSize bOMB_OUT_SIZE) 0 alt_sizes) + + -- alts_size tries to compute a good discount for + -- the case when we are scrutinising an argument variable or subcomponent thereof alts_size (SizeIs tot tot_disc tot_scrut) - -- Size of all alternatives - (SizeIs max _ _) - -- Size of biggest alternative - = SizeIs tot (unitBag (v, 20 + tot - max) - `unionBags` tot_disc) tot_scrut - -- If the variable is known, we produce a - -- discount that will take us back to 'max', - -- the size of the largest alternative The - -- 1+ is a little discount for reduced - -- allocation in the caller + largest_alt_size + + = let default_alt_discount = 20 + tot - largest_alt_size + alt_discounts = unitUFM v $ DiscSeq default_alt_discount $ plusUFMList $ catMaybes $ zipWith (alt_size_discount tot) alts alt_sizes + in + SizeIs tot + (tot_disc + `plusDiscountEnv` (alt_discounts)) + tot_scrut + -- If the variable is known but we don't have a + -- specific constructor discount for it, we produce a + -- discount that will take us back to 'largest_alt_size', + -- the size of the largest alternative. -- -- Notice though, that we return tot_disc, -- the total discount from all branches. I -- think that's right. - alts_size tot_size _ = tot_size + alts_size tot_size _max_alt_size = tot_size -- Too Big in - alts_size (foldr1 addAltSize alt_sizes) -- alts is non-empty - (foldr1 maxSize alt_sizes) + -- Why foldr1? We might get TooBig already after the first few alternatives + -- in which case we don't have to look at the remaining ones. + alts_size added_alt_sizes -- alts is non-empty + largest_alt_size -- Good to inline if an arg is scrutinised, because -- that may eliminate allocation in the caller -- And it eliminates the case itself where - is_top_arg (Var v) | v `elem` top_args = Just v + is_top_arg (Var v) | v `elemUnVarSet` arg_comps = Just v is_top_arg (Cast e _) = is_top_arg e is_top_arg _ = Nothing - size_up (Case e _ _ alts) = size_up e `addSizeNSD` - foldr (addAltSize . size_up_alt) case_size alts + size_up !depth arg_comps (Case e _ _ alts) = size_up depth arg_comps e `addSizeNSD` + foldr (addAltSize . (size_up_alt depth Nothing arg_comps) ) case_size alts where case_size | is_inline_scrut e, lengthAtMost alts 1 = sizeN (-10) @@ -534,42 +601,54 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr | otherwise = False - size_up_rhs (bndr, rhs) + size_up_rhs !depth !arg_comps (bndr, rhs) | Just join_arity <- isJoinId_maybe bndr -- Skip arguments to join point - , (_bndrs, body) <- collectNBinders join_arity rhs - = size_up body + , (bndrs, body) <- collectNBinders join_arity rhs + = size_up depth (delUnVarSetList arg_comps bndrs) body | otherwise - = size_up rhs + = size_up depth arg_comps rhs ------------ -- size_up_app is used when there's ONE OR MORE value args - size_up_app (App fun arg) args voids - | isTyCoArg arg = size_up_app fun args voids - | isZeroBitExpr arg = size_up_app fun (arg:args) (voids + 1) - | otherwise = size_up arg `addSizeNSD` - size_up_app fun (arg:args) voids - size_up_app (Var fun) args voids = size_up_call fun args voids - size_up_app (Tick _ expr) args voids = size_up_app expr args voids - size_up_app (Cast expr _) args voids = size_up_app expr args voids - size_up_app other args voids = size_up other `addSizeN` + size_up_app depth !arg_comps (App fun arg) args voids + | isTyCoArg arg = size_up_app depth arg_comps fun args voids + | isZeroBitExpr arg = size_up_app depth arg_comps fun (arg:args) (voids + 1) + | otherwise = size_up depth arg_comps arg `addSizeNSD` + size_up_app depth arg_comps fun (arg:args) voids + size_up_app _depth arg_comps (Var fun) args voids = size_up_call arg_comps fun args voids + size_up_app depth arg_comps (Tick _ expr) args voids = size_up_app depth arg_comps expr args voids + size_up_app depth arg_comps (Cast expr _) args voids = size_up_app depth arg_comps expr args voids + size_up_app depth arg_comps other args voids = size_up depth arg_comps other `addSizeN` callSize (length args) voids -- if the lhs is not an App or a Var, or an invisible thing like a -- Tick or Cast, then we should charge for a complete call plus the -- size of the lhs itself. ------------ - size_up_call :: Id -> [CoreExpr] -> Int -> ExprSize - size_up_call fun val_args voids + size_up_call :: UnVarSet -> Id -> [CoreExpr] -> Int -> ExprSize + size_up_call !arg_comps fun val_args voids = case idDetails fun of FCallId _ -> sizeN (callSize (length val_args) voids) DataConWorkId dc -> conSize dc (length val_args) PrimOpId op _ -> primOpSize op (length val_args) - ClassOpId _ -> classOpSize opts top_args val_args - _ -> funSize opts top_args fun (length val_args) voids + ClassOpId _ -> classOpSize opts arg_comps val_args + _ -> funSize opts arg_comps fun (length val_args) voids ------------ - size_up_alt (Alt _con _bndrs rhs) = size_up rhs `addSizeN` 10 + -- Take into acount the binders of scrutinized argument binders + -- But not too deeply! Hence we check if we exhausted depth. + -- If so we simply ingore the case binders. + size_up_alt depth m_top_arg !arg_comps (Alt alt_con bndrs rhs) + | Just top_arg <- m_top_arg + , depth > 0 + , DataAlt con <- alt_con + = + let alt_size = size_up depth (extendUnVarSetList bndrs arg_comps) rhs `addSizeN` 10 + -- let alt_size = size_up (arg_comps) rhs `addSizeN` 10 + + in asExprSize top_arg alt_size con bndrs + size_up_alt depth _ arg_comps (Alt _con bndrs rhs) = size_up depth (delUnVarSetList arg_comps bndrs) rhs `addSizeN` 10 -- Don't charge for args, so that wrappers look cheap -- (See comments about wrappers with Case) -- @@ -590,6 +669,7 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr ------------ -- These addSize things have to be here because -- I don't want to give them bOMB_OUT_SIZE as an argument + addSizeN :: ExprSize -> Int -> ExprSize addSizeN TooBig _ = TooBig addSizeN (SizeIs n xs d) m = mkSizeIs bOMB_OUT_SIZE (n + m) xs d @@ -598,7 +678,7 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr addAltSize _ TooBig = TooBig addAltSize (SizeIs n1 xs d1) (SizeIs n2 ys d2) = mkSizeIs bOMB_OUT_SIZE (n1 + n2) - (xs `unionBags` ys) + (xs `plusDiscountEnv` ys) (d1 + d2) -- Note [addAltSize result discounts] -- This variant ignores the result discount from its LEFT argument @@ -607,7 +687,7 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr addSizeNSD _ TooBig = TooBig addSizeNSD (SizeIs n1 xs _) (SizeIs n2 ys d2) = mkSizeIs bOMB_OUT_SIZE (n1 + n2) - (xs `unionBags` ys) + (xs `plusDiscountEnv` ys) d2 -- Ignore d1 -- don't count expressions such as State# RealWorld @@ -631,21 +711,23 @@ litSize _other = 0 -- Must match size of nullary constructors -- Key point: if x |-> 4, then x must inline unconditionally -- (eg via case binding) -classOpSize :: UnfoldingOpts -> [Id] -> [CoreExpr] -> ExprSize +classOpSize :: UnfoldingOpts -> UnVarSet -> [CoreExpr] -> ExprSize -- See Note [Conlike is interesting] classOpSize _ _ [] = sizeZero -classOpSize opts top_args (arg1 : other_args) - = SizeIs size arg_discount 0 +classOpSize opts !top_args (arg1 : other_args) + = SizeIs size (arg_discount arg1) 0 where size = 20 + (10 * length other_args) -- If the class op is scrutinising a lambda bound dictionary then -- give it a discount, to encourage the inlining of this function -- The actual discount is rather arbitrarily chosen - arg_discount = case arg1 of - Var dict | dict `elem` top_args - -> unitBag (dict, unfoldingDictDiscount opts) - _other -> emptyBag + arg_discount dict_arg = case dict_arg of + Var dict | dict `elemUnVarSet` top_args + -> unitUFM dict (classOpArgDiscount $ unfoldingDictDiscount opts) + Tick _ e -> arg_discount e + Cast e _ -> arg_discount e + _other -> mempty -- | The size of a function call callSize @@ -668,10 +750,10 @@ jumpSize n_val_args voids = 2 * (1 + n_val_args - voids) -- spectral/puzzle. TODO Perhaps adjusting the default threshold would be a -- better solution? -funSize :: UnfoldingOpts -> [Id] -> Id -> Int -> Int -> ExprSize +funSize :: UnfoldingOpts -> UnVarSet -> Id -> Int -> Int -> ExprSize -- Size for functions that are not constructors or primops -- Note [Function applications] -funSize opts top_args fun n_val_args voids +funSize opts !top_args fun n_val_args voids | fun `hasKey` buildIdKey = buildSize | fun `hasKey` augmentIdKey = augmentSize | otherwise = SizeIs size arg_discount res_discount @@ -685,9 +767,10 @@ funSize opts top_args fun n_val_args voids -- DISCOUNTS -- See Note [Function and non-function discounts] - arg_discount | some_val_args && fun `elem` top_args - = unitBag (fun, unfoldingFunAppDiscount opts) - | otherwise = emptyBag + arg_discount | some_val_args && fun `elemUnVarSet` top_args + = -- pprTrace "mkFunSize" (ppr fun) $ + unitUFM fun (FunDisc (unfoldingFunAppDiscount opts) (idName fun)) + | otherwise = mempty -- If the function is an argument and is applied -- to some values, give it an arg-discount @@ -698,13 +781,13 @@ funSize opts top_args fun n_val_args voids conSize :: DataCon -> Int -> ExprSize conSize dc n_val_args - | n_val_args == 0 = SizeIs 0 emptyBag 10 -- Like variables + | n_val_args == 0 = SizeIs 0 mempty 10 -- Like variables -- See Note [Unboxed tuple size and result discount] - | isUnboxedTupleDataCon dc = SizeIs 0 emptyBag 10 + | isUnboxedTupleDataCon dc = SizeIs 0 mempty 10 -- See Note [Constructor size and result discount] - | otherwise = SizeIs 10 emptyBag 10 + | otherwise = SizeIs 10 mempty 10 {- Note [Constructor size and result discount] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -808,7 +891,7 @@ primOpSize op n_val_args buildSize :: ExprSize -buildSize = SizeIs 0 emptyBag 40 +buildSize = SizeIs 0 mempty 40 -- We really want to inline applications of build -- build t (\cn -> e) should cost only the cost of e (because build will be inlined later) -- Indeed, we should add a result_discount because build is @@ -817,7 +900,7 @@ buildSize = SizeIs 0 emptyBag 40 -- The "4" is rather arbitrary. augmentSize :: ExprSize -augmentSize = SizeIs 0 emptyBag 40 +augmentSize = SizeIs 0 mempty 40 -- Ditto (augment t (\cn -> e) ys) should cost only the cost of -- e plus ys. The -2 accounts for the \cn @@ -899,37 +982,86 @@ Code for manipulating sizes data ExprSize = TooBig | SizeIs { _es_size_is :: {-# UNPACK #-} !Int -- ^ Size found - , _es_args :: !(Bag (Id,Int)) + , _es_args :: !(VarEnv ArgDiscount) -- ^ Arguments cased herein, and discount for each such , _es_discount :: {-# UNPACK #-} !Int -- ^ Size to subtract if result is scrutinised by a case -- expression } +plusDiscountEnv :: VarEnv ArgDiscount -> VarEnv ArgDiscount -> VarEnv ArgDiscount +plusDiscountEnv el er = plusUFM_C combineArgDiscount el er + +-- TODO: Might be worth giving this a larger discount if the type class is known. +-- So that `f @T $d x = opDoStuff @T $d x ` applied to `f @Bool $dC_$Bool` is likely +-- to inline turning the unknown into a known call. +classOpArgDiscount :: Int -> ArgDiscount +classOpArgDiscount n = SomeArgUse n + +-- After computing the discounts for an alternatives rhs we transfer discounts from the +-- alt binders to the constructor specific discount of the scrutinee for the given constructor. +asExprSize :: Id -> ExprSize -> DataCon -> [Id] -> ExprSize +asExprSize _ TooBig _ _ = TooBig +asExprSize scrut (SizeIs n arg_discs s_d) con alt_bndrs = + let (alt_discount_bags, top_discounts) = partitionWithKeyUFM (\k _v -> k `elem` map getUnique alt_bndrs) arg_discs + alt_discount_map = alt_discount_bags + alt_bndr_uses = map (\bndr -> lookupWithDefaultVarEnv alt_discount_map NoSeqUse bndr ) alt_bndrs :: [ArgDiscount] + + in SizeIs n (unitUFM scrut (mkConUse con alt_bndr_uses) `plusUFM` top_discounts) s_d + + +mkConUse :: DataCon -> [ArgDiscount] -> ArgDiscount +mkConUse con uses = + DiscSeq + 0 + -- We apply a penalty of 1 per case alternative, so here we apply a discount of 1 per *eliminated* + -- case alternative. And then one more because we get rid of a conditional branch which is always good. + (unitUFM con (ConDiscount con (length uses) uses)) + +combineArgDiscount :: ArgDiscount -> ArgDiscount -> ArgDiscount +combineArgDiscount NoSeqUse u2 = u2 +combineArgDiscount u1 NoSeqUse = u1 +combineArgDiscount (SomeArgUse d1) (SomeArgUse d2) = SomeArgUse $! d1 + d2 +combineArgDiscount (SomeArgUse d1) (DiscSeq d2 m2) = DiscSeq (d1 + d2) m2 +combineArgDiscount (DiscSeq d1 m1) (SomeArgUse d2) = DiscSeq (d1 + d2) m1 +combineArgDiscount (DiscSeq d1 m1) (DiscSeq d2 m2) = DiscSeq (d1 + d2) (plusUFM_C combineMapEntry m1 m2) +-- See Note [Function and non-function discounts] why we need this +combineArgDiscount f1@(FunDisc d1 _f1) f2@(FunDisc d2 _f2) = if d1 > d2 then f1 else f2 +-- This can happen either through shadowing or with things like unsafeCoerce. A good idea to warn for debug builds but we don't want to panic here. +combineArgDiscount f1@(FunDisc _d _n) u2 = pprTraceDebug "Variable seemingly discounted as both function and constructor" (ppr f1 $$ ppr u2) f1 +combineArgDiscount u1 f2@(FunDisc _d _n) = pprTraceDebug "Variable seemingly discounted as both function and constructor" (ppr u1 $$ ppr f2) f2 + +combineMapEntry :: ConDiscount -> ConDiscount -> ConDiscount +combineMapEntry (ConDiscount c1 dc1 u1) (ConDiscount c2 dc2 u2) = + assert(c1 == c2) $ ConDiscount c1 (dc1+dc2) (combinArgDiscountLists u1 u2) + +combinArgDiscountLists :: [ArgDiscount] -> [ArgDiscount] -> [ArgDiscount] +combinArgDiscountLists uses1 uses2 = zipWith combineArgDiscount uses1 uses2 + instance Outputable ExprSize where ppr TooBig = text "TooBig" - ppr (SizeIs a _ c) = brackets (int a <+> int c) + -- ppr (SizeIs a _ c) = brackets (int a <+> int c) + ppr (SizeIs a d c) = brackets (int a <+> int c <+> ppr d) -- subtract the discount before deciding whether to bale out. eg. we -- want to inline a large constructor application into a selector: -- tup = (a_1, ..., a_99) -- x = case tup of ... -- -mkSizeIs :: Int -> Int -> Bag (Id, Int) -> Int -> ExprSize +mkSizeIs :: Int -> Int -> VarEnv ArgDiscount -> Int -> ExprSize mkSizeIs max n xs d | (n - d) > max = TooBig | otherwise = SizeIs n xs d -maxSize :: ExprSize -> ExprSize -> ExprSize -maxSize TooBig _ = TooBig -maxSize _ TooBig = TooBig -maxSize s1@(SizeIs n1 _ _) s2@(SizeIs n2 _ _) | n1 > n2 = s1 - | otherwise = s2 +maxSize :: Int -> ExprSize -> Int -> Int +maxSize !max TooBig _n1 = max +maxSize _max (SizeIs n1 _ _) n2 | n1 >= n2 = n1 + | otherwise = n2 sizeZero :: ExprSize sizeN :: Int -> ExprSize -sizeZero = SizeIs 0 emptyBag 0 -sizeN n = SizeIs n emptyBag 0 +sizeZero = SizeIs 0 mempty 0 +sizeN n = SizeIs n mempty 0 {- ************************************************************************ @@ -990,15 +1122,21 @@ data ArgSummary = TrivArg -- Nothing interesting | NonTrivArg -- Arg has structure | ValueArg -- Arg is a con-app or PAP -- ..or con-like. Note [Conlike is interesting] + | ConArg !DataCon + [ArgSummary] -- It's important that the sub-summaries are + -- computed lazily. This way they only get forced + -- if there is a interesting discount which matches + -- on them. Which improves performance quite a lot. instance Outputable ArgSummary where ppr TrivArg = text "TrivArg" ppr NonTrivArg = text "NonTrivArg" ppr ValueArg = text "ValueArg" + ppr (ConArg con _args) = text "ConArg:" <> ppr con -- <+> ppr args -nonTriv :: ArgSummary -> Bool -nonTriv TrivArg = False -nonTriv _ = True +nonTrivArg :: ArgSummary -> Bool +nonTrivArg TrivArg = False +nonTrivArg _ = True data CallCtxt = BoringCtxt @@ -1021,474 +1159,3 @@ instance Outputable CallCtxt where ppr DiscArgCtxt = text "DiscArgCtxt" ppr RuleArgCtxt = text "RuleArgCtxt" -callSiteInline :: Logger - -> UnfoldingOpts - -> Int -- Case depth - -> Id -- The Id - -> Bool -- True <=> unfolding is active - -> Bool -- True if there are no arguments at all (incl type args) - -> [ArgSummary] -- One for each value arg; True if it is interesting - -> CallCtxt -- True <=> continuation is interesting - -> Maybe CoreExpr -- Unfolding, if any -callSiteInline logger opts !case_depth id active_unfolding lone_variable arg_infos cont_info - = case idUnfolding id of - -- idUnfolding checks for loop-breakers, returning NoUnfolding - -- Things with an INLINE pragma may have an unfolding *and* - -- be a loop breaker (maybe the knot is not yet untied) - CoreUnfolding { uf_tmpl = unf_template - , uf_is_work_free = is_wf - , uf_guidance = guidance, uf_expandable = is_exp } - | active_unfolding -> tryUnfolding logger opts case_depth id lone_variable - arg_infos cont_info unf_template - is_wf is_exp guidance - | otherwise -> traceInline logger opts id "Inactive unfolding:" (ppr id) Nothing - NoUnfolding -> Nothing - BootUnfolding -> Nothing - OtherCon {} -> Nothing - DFunUnfolding {} -> Nothing -- Never unfold a DFun - --- | Report the inlining of an identifier's RHS to the user, if requested. -traceInline :: Logger -> UnfoldingOpts -> Id -> String -> SDoc -> a -> a -traceInline logger opts inline_id str doc result - -- We take care to ensure that doc is used in only one branch, ensuring that - -- the simplifier can push its allocation into the branch. See Note [INLINE - -- conditional tracing utilities]. - | enable = logTraceMsg logger str doc result - | otherwise = result - where - enable - | logHasDumpFlag logger Opt_D_dump_verbose_inlinings - = True - | Just prefix <- unfoldingReportPrefix opts - = prefix `isPrefixOf` occNameString (getOccName inline_id) - | otherwise - = False -{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] - -{- Note [Avoid inlining into deeply nested cases] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Consider a function f like this: - - f arg1 arg2 = - case ... - ... -> g arg1 - ... -> g arg2 - -This function is small. So should be safe to inline. -However sometimes this doesn't quite work out like that. -Consider this code: - -f1 arg1 arg2 ... = ... - case _foo of - alt1 -> ... f2 arg1 ... - alt2 -> ... f2 arg2 ... - -f2 arg1 arg2 ... = ... - case _foo of - alt1 -> ... f3 arg1 ... - alt2 -> ... f3 arg2 ... - -f3 arg1 arg2 ... = ... - -... repeats up to n times. And then f1 is -applied to some arguments: - -foo = ... f1 ... - -Initially f2..fn are not interesting to inline so we don't. -However we see that f1 is applied to interesting args. -So it's an obvious choice to inline those: - -foo = - ... - case _foo of - alt1 -> ... f2 ... - alt2 -> ... f2 ... - -As a result we go and inline f2 both mentions of f2 in turn are now applied to interesting -arguments and f2 is small: - -foo = - ... - case _foo of - alt1 -> ... case _foo of - alt1 -> ... f3 ... - alt2 -> ... f3 ... - - alt2 -> ... case _foo of - alt1 -> ... f3 ... - alt2 -> ... f3 ... - -The same thing happens for each binding up to f_n, duplicating the amount of inlining -done in each step. Until at some point we are either done or run out of simplifier -ticks/RAM. This pattern happened #18730. - -To combat this we introduce one more heuristic when weighing inlining decision. -We keep track of a "case-depth". Which increases each time we look inside a case -expression with more than one alternative. - -We then apply a penalty to inlinings based on the case-depth at which they would -be inlined. Bounding the number of inlinings in such a scenario. - -The heuristic can be tuned in two ways: - -* We can ignore the first n levels of case nestings for inlining decisions using - -funfolding-case-threshold. -* The penalty grows linear with the depth. It's computed as size*(depth-threshold)/scaling. - Scaling can be set with -funfolding-case-scaling. - -Some guidance on setting these defaults: - -* A low treshold (<= 2) is needed to prevent exponential cases from spiraling out of - control. We picked 2 for no particular reason. -* Scaling the penalty by any more than 30 means the reproducer from - T18730 won't compile even with reasonably small values of n. Instead - it will run out of runs/ticks. This means to positively affect the reproducer - a scaling <= 30 is required. -* A scaling of >= 15 still causes a few very large regressions on some nofib benchmarks. - (+80% for gc/fulsom, +90% for real/ben-raytrace, +20% for spectral/fibheaps) -* A scaling of >= 25 showed no regressions on nofib. However it showed a number of - (small) regression for compiler perf benchmarks. - -The end result is that we are settling for a scaling of 30, with a threshold of 2. -This gives us minimal compiler perf regressions. No nofib runtime regressions and -will still avoid this pattern sometimes. This is a "safe" default, where we err on -the side of compiler blowup instead of risking runtime regressions. - -For cases where the default falls short the flag can be changed to allow more/less inlining as -needed on a per-module basis. - --} - -tryUnfolding :: Logger -> UnfoldingOpts -> Int -> Id -> Bool -> [ArgSummary] -> CallCtxt - -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance - -> Maybe CoreExpr -tryUnfolding logger opts !case_depth id lone_variable - arg_infos cont_info unf_template - is_wf is_exp guidance - = case guidance of - UnfNever -> traceInline logger opts id str (text "UnfNever") Nothing - - UnfWhen { ug_arity = uf_arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } - | enough_args && (boring_ok || some_benefit || unfoldingVeryAggressive opts) - -- See Note [INLINE for small functions] (3) - -> traceInline logger opts id str (mk_doc some_benefit empty True) (Just unf_template) - | otherwise - -> traceInline logger opts id str (mk_doc some_benefit empty False) Nothing - where - some_benefit = calc_some_benefit uf_arity - enough_args = (n_val_args >= uf_arity) || (unsat_ok && n_val_args > 0) - - UnfIfGoodArgs { ug_args = arg_discounts, ug_res = res_discount, ug_size = size } - | unfoldingVeryAggressive opts - -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) - | is_wf && some_benefit && small_enough - -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) - | otherwise - -> traceInline logger opts id str (mk_doc some_benefit extra_doc False) Nothing - where - some_benefit = calc_some_benefit (length arg_discounts) - extra_doc = vcat [ text "case depth =" <+> int case_depth - , text "depth based penalty =" <+> int depth_penalty - , text "discounted size =" <+> int adjusted_size ] - -- See Note [Avoid inlining into deeply nested cases] - depth_treshold = unfoldingCaseThreshold opts - depth_scaling = unfoldingCaseScaling opts - depth_penalty | case_depth <= depth_treshold = 0 - | otherwise = (size * (case_depth - depth_treshold)) `div` depth_scaling - adjusted_size = size + depth_penalty - discount - small_enough = adjusted_size <= unfoldingUseThreshold opts - discount = computeDiscount arg_discounts res_discount arg_infos cont_info - - where - mk_doc some_benefit extra_doc yes_or_no - = vcat [ text "arg infos" <+> ppr arg_infos - , text "interesting continuation" <+> ppr cont_info - , text "some_benefit" <+> ppr some_benefit - , text "is exp:" <+> ppr is_exp - , text "is work-free:" <+> ppr is_wf - , text "guidance" <+> ppr guidance - , extra_doc - , text "ANSWER =" <+> if yes_or_no then text "YES" else text "NO"] - - ctx = log_default_dump_context (logFlags logger) - str = "Considering inlining: " ++ showSDocOneLine ctx (ppr id) - n_val_args = length arg_infos - - -- some_benefit is used when the RHS is small enough - -- and the call has enough (or too many) value - -- arguments (ie n_val_args >= arity). But there must - -- be *something* interesting about some argument, or the - -- result context, to make it worth inlining - calc_some_benefit :: Arity -> Bool -- The Arity is the number of args - -- expected by the unfolding - calc_some_benefit uf_arity - | not saturated = interesting_args -- Under-saturated - -- Note [Unsaturated applications] - | otherwise = interesting_args -- Saturated or over-saturated - || interesting_call - where - saturated = n_val_args >= uf_arity - over_saturated = n_val_args > uf_arity - interesting_args = any nonTriv arg_infos - -- NB: (any nonTriv arg_infos) looks at the - -- over-saturated args too which is "wrong"; - -- but if over-saturated we inline anyway. - - interesting_call - | over_saturated - = True - | otherwise - = case cont_info of - CaseCtxt -> not (lone_variable && is_exp) -- Note [Lone variables] - ValAppCtxt -> True -- Note [Cast then apply] - RuleArgCtxt -> uf_arity > 0 -- See Note [RHS of lets] - DiscArgCtxt -> uf_arity > 0 -- Note [Inlining in ArgCtxt] - RhsCtxt NonRecursive - -> uf_arity > 0 -- See Note [RHS of lets] - _other -> False -- See Note [Nested functions] - - -{- Note [RHS of lets] -~~~~~~~~~~~~~~~~~~~~~ -When the call is the argument of a function with a RULE, or the RHS of a let, -we are a little bit keener to inline (in tryUnfolding). For example - f y = (y,y,y) - g y = let x = f y in ...(case x of (a,b,c) -> ...) ... -We'd inline 'f' if the call was in a case context, and it kind-of-is, -only we can't see it. Also - x = f v -could be expensive whereas - x = case v of (a,b) -> a -is patently cheap and may allow more eta expansion. - -So, in `interesting_call` in `tryUnfolding`, we treat the RHS of a -/non-recursive/ let as not-totally-boring. A /recursive/ let isn't -going be inlined so there is much less point. Hence the (only reason -for the) RecFlag in RhsCtxt - -Note [Unsaturated applications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a call is not saturated, we *still* inline if one of the -arguments has interesting structure. That's sometimes very important. -A good example is the Ord instance for Bool in Base: - - Rec { - $fOrdBool =GHC.Classes.D:Ord - @ Bool - ... - $cmin_ajX - - $cmin_ajX [Occ=LoopBreaker] :: Bool -> Bool -> Bool - $cmin_ajX = GHC.Classes.$dmmin @ Bool $fOrdBool - } - -But the defn of GHC.Classes.$dmmin is: - - $dmmin :: forall a. GHC.Classes.Ord a => a -> a -> a - {- Arity: 3, HasNoCafRefs, Strictness: SLL, - Unfolding: (\ @ a $dOrd :: GHC.Classes.Ord a x :: a y :: a -> - case @ a GHC.Classes.<= @ a $dOrd x y of wild { - GHC.Types.False -> y GHC.Types.True -> x }) -} - -We *really* want to inline $dmmin, even though it has arity 3, in -order to unravel the recursion. - - -Note [Things to watch] -~~~~~~~~~~~~~~~~~~~~~~ -* { y = I# 3; x = y `cast` co; ...case (x `cast` co) of ... } - Assume x is exported, so not inlined unconditionally. - Then we want x to inline unconditionally; no reason for it - not to, and doing so avoids an indirection. - -* { x = I# 3; ....f x.... } - Make sure that x does not inline unconditionally! - Lest we get extra allocation. - -Note [Inlining an InlineRule] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An InlineRules is used for - (a) programmer INLINE pragmas - (b) inlinings from worker/wrapper - -For (a) the RHS may be large, and our contract is that we *only* inline -when the function is applied to all the arguments on the LHS of the -source-code defn. (The uf_arity in the rule.) - -However for worker/wrapper it may be worth inlining even if the -arity is not satisfied (as we do in the CoreUnfolding case) so we don't -require saturation. - -Note [Nested functions] -~~~~~~~~~~~~~~~~~~~~~~~ -At one time we treated a call of a non-top-level function as -"interesting" (regardless of how boring the context) in the hope -that inlining it would eliminate the binding, and its allocation. -Specifically, in the default case of interesting_call we had - _other -> not is_top && uf_arity > 0 - -But actually postInlineUnconditionally does some of this and overall -it makes virtually no difference to nofib. So I simplified away this -special case - -Note [Cast then apply] -~~~~~~~~~~~~~~~~~~~~~~ -Consider - myIndex = __inline_me ( (/\a. ) |> co ) - co :: (forall a. a -> a) ~ (forall a. T a) - ... /\a.\x. case ((myIndex a) |> sym co) x of { ... } ... - -We need to inline myIndex to unravel this; but the actual call (myIndex a) has -no value arguments. The ValAppCtxt gives it enough incentive to inline. - -Note [Inlining in ArgCtxt] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -The condition (arity > 0) here is very important, because otherwise -we end up inlining top-level stuff into useless places; eg - x = I# 3# - f = \y. g x -This can make a very big difference: it adds 16% to nofib 'integer' allocs, -and 20% to 'power'. - -At one stage I replaced this condition by 'True' (leading to the above -slow-down). The motivation was test eyeball/inline1.hs; but that seems -to work ok now. - -NOTE: arguably, we should inline in ArgCtxt only if the result of the -call is at least CONLIKE. At least for the cases where we use ArgCtxt -for the RHS of a 'let', we only profit from the inlining if we get a -CONLIKE thing (modulo lets). - -Note [Lone variables] See also Note [Interaction of exprIsWorkFree and lone variables] -~~~~~~~~~~~~~~~~~~~~~ which appears below -The "lone-variable" case is important. I spent ages messing about -with unsatisfactory variants, but this is nice. The idea is that if a -variable appears all alone - - as an arg of lazy fn, or rhs BoringCtxt - as scrutinee of a case CaseCtxt - as arg of a fn ArgCtxt -AND - it is bound to a cheap expression - -then we should not inline it (unless there is some other reason, -e.g. it is the sole occurrence). That is what is happening at -the use of 'lone_variable' in 'interesting_call'. - -Why? At least in the case-scrutinee situation, turning - let x = (a,b) in case x of y -> ... -into - let x = (a,b) in case (a,b) of y -> ... -and thence to - let x = (a,b) in let y = (a,b) in ... -is bad if the binding for x will remain. - -Another example: I discovered that strings -were getting inlined straight back into applications of 'error' -because the latter is strict. - s = "foo" - f = \x -> ...(error s)... - -Fundamentally such contexts should not encourage inlining because, provided -the RHS is "expandable" (see Note [exprIsExpandable] in GHC.Core.Utils) the -context can ``see'' the unfolding of the variable (e.g. case or a -RULE) so there's no gain. - -However, watch out: - - * Consider this: - foo = _inline_ (\n. [n]) - bar = _inline_ (foo 20) - baz = \n. case bar of { (m:_) -> m + n } - Here we really want to inline 'bar' so that we can inline 'foo' - and the whole thing unravels as it should obviously do. This is - important: in the NDP project, 'bar' generates a closure data - structure rather than a list. - - So the non-inlining of lone_variables should only apply if the - unfolding is regarded as cheap; because that is when exprIsConApp_maybe - looks through the unfolding. Hence the "&& is_wf" in the - InlineRule branch. - - * Even a type application or coercion isn't a lone variable. - Consider - case $fMonadST @ RealWorld of { :DMonad a b c -> c } - We had better inline that sucker! The case won't see through it. - - For now, I'm treating treating a variable applied to types - in a *lazy* context "lone". The motivating example was - f = /\a. \x. BIG - g = /\a. \y. h (f a) - There's no advantage in inlining f here, and perhaps - a significant disadvantage. Hence some_val_args in the Stop case - -Note [Interaction of exprIsWorkFree and lone variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The lone-variable test says "don't inline if a case expression -scrutinises a lone variable whose unfolding is cheap". It's very -important that, under these circumstances, exprIsConApp_maybe -can spot a constructor application. So, for example, we don't -consider - let x = e in (x,x) -to be cheap, and that's good because exprIsConApp_maybe doesn't -think that expression is a constructor application. - -In the 'not (lone_variable && is_wf)' test, I used to test is_value -rather than is_wf, which was utterly wrong, because the above -expression responds True to exprIsHNF, which is what sets is_value. - -This kind of thing can occur if you have - - {-# INLINE foo #-} - foo = let x = e in (x,x) - -which Roman did. - - --} - -computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt - -> Int -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 - - + 10 * length actual_arg_discounts - -- Discount of 10 for each arg supplied, - -- because the result replaces the call - - + total_arg_discount + res_discount' - where - actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos - total_arg_discount = sum actual_arg_discounts - - mk_arg_discount _ TrivArg = 0 - mk_arg_discount _ NonTrivArg = 10 - mk_arg_discount discount ValueArg = discount - - res_discount' - | LT <- arg_discounts `compareLength` arg_infos - = res_discount -- Over-saturated - | otherwise - = case cont_info of - BoringCtxt -> 0 - CaseCtxt -> res_discount -- Presumably a constructor - ValAppCtxt -> res_discount -- Presumably a function - _ -> 40 `min` res_discount - -- ToDo: this 40 `min` res_discount doesn't seem right - -- for DiscArgCtxt it shouldn't matter because the function will - -- get the arg discount for any non-triv arg - -- for RuleArgCtxt we do want to be keener to inline; but not only - -- constructor results - -- for RhsCtxt I suppose that exposing a data con is good in general - -- And 40 seems very arbitrary - -- - -- res_discount can be very large when a function returns - -- constructors; but we only want to invoke that large discount - -- when there's a case continuation. - -- Otherwise we, rather arbitrarily, threshold it. Yuk. - -- But we want to avoid inlining large functions that return - -- constructors into contexts that are simply "interesting" ===================================== compiler/GHC/Data/Graph/UnVar.hs ===================================== @@ -14,6 +14,8 @@ It does not normalize the graphs. This means that g `unionUnVarGraph` g is equal to g, but twice as expensive and large. -} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + module GHC.Data.Graph.UnVar ( UnVarSet , emptyUnVarSet, mkUnVarSet, varEnvDom, unionUnVarSet, unionUnVarSets @@ -45,8 +47,9 @@ import qualified Data.IntSet as S -- Set of uniques, i.e. for adjancet nodes newtype UnVarSet = UnVarSet (S.IntSet) - deriving Eq + deriving (Eq,Semigroup,Monoid) +{-# INLINE k #-} k :: Var -> Int k v = getKey (getUnique v) @@ -64,7 +67,8 @@ delUnVarSet :: UnVarSet -> Var -> UnVarSet delUnVarSet (UnVarSet s) v = UnVarSet $ k v `S.delete` s delUnVarSetList :: UnVarSet -> [Var] -> UnVarSet -delUnVarSetList s vs = s `minusUnVarSet` mkUnVarSet vs +delUnVarSetList (UnVarSet s) vs = + UnVarSet $ foldl' (\s v -> S.delete (k v) s) s vs minusUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet minusUnVarSet (UnVarSet s) (UnVarSet s') = UnVarSet $ s `S.difference` s' @@ -73,7 +77,7 @@ sizeUnVarSet :: UnVarSet -> Int sizeUnVarSet (UnVarSet s) = S.size s mkUnVarSet :: [Var] -> UnVarSet -mkUnVarSet vs = UnVarSet $ S.fromList $ map k vs +mkUnVarSet vs = UnVarSet $ foldl' (\s v -> S.insert (k v) s) S.empty vs varEnvDom :: VarEnv a -> UnVarSet varEnvDom ae = UnVarSet $ ufmToSet_Directly ae @@ -82,7 +86,8 @@ extendUnVarSet :: Var -> UnVarSet -> UnVarSet extendUnVarSet v (UnVarSet s) = UnVarSet $ S.insert (k v) s extendUnVarSetList :: [Var] -> UnVarSet -> UnVarSet -extendUnVarSetList vs s = s `unionUnVarSet` mkUnVarSet vs +extendUnVarSetList vs (UnVarSet s) = + UnVarSet $ foldl' (\s v -> S.insert (k v) s) s vs unionUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet unionUnVarSet (UnVarSet set1) (UnVarSet set2) = UnVarSet (set1 `S.union` set2) ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -415,6 +415,7 @@ data GeneralFlag -- Suppress separate type signatures in core, but leave types on -- lambda bound vars | Opt_SuppressUnfoldings + | Opt_SuppressUnfoldingGuidance -- Suppress the details of even stable unfoldings | Opt_SuppressTypeSignatures -- Suppress unique ids on variables. ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2825,6 +2825,8 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d { unfoldingOpts = updateCaseThreshold n (unfoldingOpts d)})) , make_ord_flag defFlag "funfolding-case-scaling" (intSuffix (\n d -> d { unfoldingOpts = updateCaseScaling n (unfoldingOpts d)})) + , make_ord_flag defFlag "funfolding-discount-depth" + (intSuffix (\n d -> d { unfoldingOpts = updateMaxDiscountDepth n (unfoldingOpts d)})) , make_dep_flag defFlag "funfolding-keeness-factor" (floatSuffix (\_ d -> d)) @@ -3355,7 +3357,8 @@ dFlagsDeps = [ flagSpec "suppress-type-signatures" Opt_SuppressTypeSignatures, flagSpec "suppress-uniques" Opt_SuppressUniques, flagSpec "suppress-var-kinds" Opt_SuppressVarKinds, - flagSpec "suppress-core-sizes" Opt_SuppressCoreSizes + flagSpec "suppress-core-sizes" Opt_SuppressCoreSizes, + flagSpec "suppress-guidance" Opt_SuppressUnfoldingGuidance ] -- | These @-f\@ flags can all be reversed with @-fno-\@ @@ -5017,6 +5020,7 @@ initSDocContext dflags style = SDC , sdocSuppressCoercions = gopt Opt_SuppressCoercions dflags , sdocSuppressCoercionTypes = gopt Opt_SuppressCoercionTypes dflags , sdocSuppressUnfoldings = gopt Opt_SuppressUnfoldings dflags + , sdocSuppressUnfoldingGuidance = gopt Opt_SuppressUnfoldingGuidance dflags , sdocSuppressVarKinds = gopt Opt_SuppressVarKinds dflags , sdocSuppressUniques = gopt Opt_SuppressUniques dflags , sdocSuppressModulePrefixes = gopt Opt_SuppressModulePrefixes dflags ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -79,12 +79,12 @@ module GHC.Types.Unique.FM ( ufmToSet_Directly, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, unsafeCastUFMKey, - pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM + pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM,partitionWithKeyUFM ) where import GHC.Prelude -import GHC.Types.Unique ( Uniquable(..), Unique, getKey ) +import GHC.Types.Unique ( Uniquable(..), Unique, getKey, mkUniqueGrimily ) import GHC.Utils.Outputable import GHC.Utils.Panic.Plain import qualified Data.IntMap as M @@ -361,6 +361,11 @@ partitionUFM p (UFM m) = case M.partition p m of (left, right) -> (UFM left, UFM right) +partitionWithKeyUFM :: (Unique -> elt -> Bool) -> UniqFM key elt -> (UniqFM key elt, UniqFM key elt) +partitionWithKeyUFM p (UFM m) = + case M.partitionWithKey (\k -> p (mkUniqueGrimily k)) m of + (left, right) -> (UFM left, UFM right) + sizeUFM :: UniqFM key elt -> Int sizeUFM (UFM m) = M.size m ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -540,6 +540,7 @@ extendVarEnvList = addListToUFM plusVarEnv_C = plusUFM_C plusVarEnv_CD = plusUFM_CD plusMaybeVarEnv_C = plusMaybeUFM_C +{-# INLINE delVarEnvList #-} delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -382,7 +382,8 @@ data SDocContext = SDC , sdocSuppressIdInfo :: !Bool , sdocSuppressCoercions :: !Bool , sdocSuppressCoercionTypes :: !Bool - , sdocSuppressUnfoldings :: !Bool + , sdocSuppressUnfoldings :: !Bool -- Maybe it should be a cutoff for the depth instead? + , sdocSuppressUnfoldingGuidance :: !Bool , sdocSuppressVarKinds :: !Bool , sdocSuppressUniques :: !Bool , sdocSuppressModulePrefixes :: !Bool @@ -443,6 +444,7 @@ defaultSDocContext = SDC , sdocSuppressCoercions = False , sdocSuppressCoercionTypes = False , sdocSuppressUnfoldings = False + , sdocSuppressUnfoldingGuidance = False , sdocSuppressVarKinds = False , sdocSuppressUniques = False , sdocSuppressModulePrefixes = False ===================================== compiler/ghc.cabal.in ===================================== @@ -323,6 +323,7 @@ Library GHC.Core.Opt.Simplify GHC.Core.Opt.Simplify.Env GHC.Core.Opt.Simplify.Iteration + GHC.Core.Opt.Simplify.Inline GHC.Core.Opt.Simplify.Monad GHC.Core.Opt.Simplify.Utils GHC.Core.Opt.SpecConstr ===================================== docs/users_guide/hints.rst ===================================== @@ -404,6 +404,8 @@ decision about inlining a specific binding. * :ghc-flag:`-funfolding-case-scaling=⟨n⟩` * :ghc-flag:`-funfolding-dict-discount=⟨n⟩` * :ghc-flag:`-funfolding-fun-discount=⟨n⟩` +* :ghc-flag:`-funfolding-max-guide-depth=⟨n⟩` +* :ghc-flag:`-funfolding-discount-depth=⟨n⟩` Should the simplifier run out of ticks because of a inlining loop users are encouraged to try decreasing :ghc-flag:`-funfolding-case-threshold=⟨n⟩` ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1651,6 +1651,37 @@ by saying ``-fno-wombat``. while still allowing GHC to compile modules containing such inlining loops. +.. ghc-flag:: -funfolding-discount-depth=⟨n⟩ + :shortdesc: *default: 20.* Don't look deeper than `n` levels into function argument use. + :type: dynamic + :category: + + :default: 20 + + .. index:: + single: inlining, controlling + single: unfolding, controlling + + If we have a function application `f (Succ (Succ Zero))` with the function `f`:: + + f x = + case x of + Zero -> 0 + Succ y -> case y of + Zero -> 1 + Succ z -> case z of + Zero -> 2 + _ -> error "Large" + + Then GHC can consider the nested structure of the argument as well as how + deeply the function looks into the argument to make inlining decisions. + + This allows us to properly estimate the result code size from applying arguments + with complex structure to functions taking these arguments appart. + + However inspecting deeply nested arguments can be costly in terms of compile + time overhead. So we restrict these considerations to a certain depth. + .. ghc-flag:: -fworker-wrapper :shortdesc: Enable the worker/wrapper transformation. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bac008ae520815bc7cabd42240ca78565d0a52e0...4cbe93cf04b788857a93676c780b40e48cdbb0dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bac008ae520815bc7cabd42240ca78565d0a52e0...4cbe93cf04b788857a93676c780b40e48cdbb0dc You're receiving 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 Oct 2 14:27:16 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Sun, 02 Oct 2022 10:27:16 -0400 Subject: [Git][ghc/ghc][wip/andreask/deep_discounts] Remove one flag Message-ID: <63399fc4ac10e_2c975742bd2a1c1404870@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/deep_discounts at Glasgow Haskell Compiler / GHC Commits: f0919c83 by Andreas Klebinger at 2022-10-02T16:26:21+02:00 Remove one flag - - - - - 8 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/hints.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -2022,10 +2022,6 @@ bindersOf (Rec pairs) = [binder | (binder, _) <- pairs] bindersOfBinds :: [Bind b] -> [b] bindersOfBinds binds = foldr ((++) . bindersOf) [] binds -{-# INLINE foldBindersOf #-} -foldBindersOf :: (a -> b -> a) -> Bind b -> a -> a -foldBindersOf f b r = foldl' f r (bindersOf b) - rhssOfBind :: Bind b -> [Expr b] rhssOfBind (NonRec _ rhs) = [rhs] rhssOfBind (Rec pairs) = [rhs | (_,rhs) <- pairs] ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -21,7 +21,8 @@ module GHC.Core.Opt.Simplify.Env ( extendTvSubst, extendCvSubst, zapSubstEnv, setSubstEnv, bumpCaseDepth, getInScope, setInScopeFromE, setInScopeFromF, - setInScopeSet, modifyInScope, addNewInScopeIds, addNewInScopeId, addNewInScopeBndr, + setInScopeSet, modifyInScope, addNewInScopeIds, + addNewInScopeId, addNewInScopeBndr, getSimplRules, enterRecGroupRHSs, -- * Substitution results ===================================== compiler/GHC/Core/Opt/Simplify/Inline.hs ===================================== @@ -26,7 +26,6 @@ import GHC.Core.DataCon import GHC.Types.Var import GHC.Core.Opt.Simplify.Utils import GHC.Utils.Panic.Plain (assert) -import GHC.Utils.Trace import GHC.Types.Tickish callSiteInline :: Logger @@ -581,7 +580,7 @@ interestingArg :: SimplEnv -> CoreExpr -> ArgSummary interestingArg env e = go env depth_limit 0 e where - depth_limit = unfoldingMaxAppDepth . sm_uf_opts . seMode $ env + depth_limit = unfoldingMaxDiscountDepth . sm_uf_opts . seMode $ env -- n is # value args to which the expression is applied go :: SimplEnv -> Int -> Int -> CoreExpr -> ArgSummary ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -7,7 +7,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiWayIf #-} --- {-# OPTIONS_GHC -ddump-simpl -ddump-to-file -ddump-stg-final -dsuppress-coercions -dsuppress-coercion-types #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates -Wno-incomplete-uni-patterns #-} module GHC.Core.Opt.Simplify.Iteration ( simplTopBinds, simplExpr, simplImpRules ) where ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Core.Unfold ( updateFunAppDiscount, updateDictDiscount, updateVeryAggressive, updateCaseScaling, updateCaseThreshold, updateReportPrefix, - updateMaxAppDepth, updateMaxGuideDepth, + updateMaxDiscountDepth, ArgSummary(..), nonTrivArg, @@ -91,13 +91,9 @@ data UnfoldingOpts = UnfoldingOpts , unfoldingReportPrefix :: !(Maybe String) -- ^ Only report inlining decisions for names with this prefix - , unfoldingMaxAppDepth :: !Int + , unfoldingMaxDiscountDepth :: !Int -- ^ When considering unfolding a definition look this deep - -- into the applied argument. - - , unfoldingMaxGuideDepth :: !Int - -- ^ When creating unfolding guidance look this deep into - -- nested argument use. + -- into the applied arguments and into nested argument use. } @@ -134,8 +130,7 @@ defaultUnfoldingOpts = UnfoldingOpts -- Don't filter inlining decision reports , unfoldingReportPrefix = Nothing - , unfoldingMaxAppDepth = 20 - , unfoldingMaxGuideDepth = 20 + , unfoldingMaxDiscountDepth = 20 } -- Helpers for "GHC.Driver.Session" @@ -165,11 +160,9 @@ updateCaseScaling n opts = opts { unfoldingCaseScaling = n } updateReportPrefix :: Maybe String -> UnfoldingOpts -> UnfoldingOpts updateReportPrefix n opts = opts { unfoldingReportPrefix = n } -updateMaxAppDepth :: Int -> UnfoldingOpts -> UnfoldingOpts -updateMaxAppDepth n opts = opts { unfoldingMaxAppDepth = n } +updateMaxDiscountDepth :: Int -> UnfoldingOpts -> UnfoldingOpts +updateMaxDiscountDepth n opts = opts { unfoldingMaxDiscountDepth = n } -updateMaxGuideDepth :: Int -> UnfoldingOpts -> UnfoldingOpts -updateMaxGuideDepth n opts = opts { unfoldingMaxGuideDepth = n } {- Note [Occurrence analysis of unfoldings] @@ -474,7 +467,7 @@ sizeExpr :: UnfoldingOpts sizeExpr opts !bOMB_OUT_SIZE top_args' expr = size_up depth_limit (mkUnVarSet top_args') expr where - depth_limit = unfoldingMaxGuideDepth opts + depth_limit = unfoldingMaxDiscountDepth opts size_up :: Int -> UnVarSet -> Expr Var -> ExprSize size_up !depth !arg_comps (Cast e _) = size_up depth arg_comps e size_up !depth arg_comps (Tick _ e) = size_up depth arg_comps e ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2825,10 +2825,8 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d { unfoldingOpts = updateCaseThreshold n (unfoldingOpts d)})) , make_ord_flag defFlag "funfolding-case-scaling" (intSuffix (\n d -> d { unfoldingOpts = updateCaseScaling n (unfoldingOpts d)})) - , make_ord_flag defFlag "funfolding-max-arg-depth" - (intSuffix (\n d -> d { unfoldingOpts = updateMaxAppDepth n (unfoldingOpts d)})) - , make_ord_flag defFlag "funfolding-max-guide-depth" - (intSuffix (\n d -> d { unfoldingOpts = updateMaxGuideDepth n (unfoldingOpts d)})) + , make_ord_flag defFlag "funfolding-discount-depth" + (intSuffix (\n d -> d { unfoldingOpts = updateMaxDiscountDepth n (unfoldingOpts d)})) , make_dep_flag defFlag "funfolding-keeness-factor" (floatSuffix (\_ d -> d)) ===================================== docs/users_guide/hints.rst ===================================== @@ -405,7 +405,7 @@ decision about inlining a specific binding. * :ghc-flag:`-funfolding-dict-discount=⟨n⟩` * :ghc-flag:`-funfolding-fun-discount=⟨n⟩` * :ghc-flag:`-funfolding-max-guide-depth=⟨n⟩` -* :ghc-flag:`-funfolding-max-arg-depth=⟨n⟩` +* :ghc-flag:`-funfolding-discount-depth=⟨n⟩` Should the simplifier run out of ticks because of a inlining loop users are encouraged to try decreasing :ghc-flag:`-funfolding-case-threshold=⟨n⟩` ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -1651,8 +1651,8 @@ by saying ``-fno-wombat``. while still allowing GHC to compile modules containing such inlining loops. -.. ghc-flag:: -funfolding-max-arg-depth=⟨n⟩ - :shortdesc: *default: 20.* Don't look deepter than `n` levels into function arguments. +.. ghc-flag:: -funfolding-discount-depth=⟨n⟩ + :shortdesc: *default: 20.* Don't look deeper than `n` levels into function argument use. :type: dynamic :category: @@ -1673,35 +1673,14 @@ by saying ``-fno-wombat``. Zero -> 2 _ -> error "Large" - Then GHC can consider the nested use of the argument when making inlining decisions. - However inspecting deeply nested arguments can be costly in terms of compile time overhead. - So we restrict inspection of the argument to a certain depth. + Then GHC can consider the nested structure of the argument as well as how + deeply the function looks into the argument to make inlining decisions. -.. ghc-flag:: -funfolding-max-guide-depth=⟨n⟩ - :shortdesc: *default: 20.* Don't look deepter than `n` levels into a functions use of it's arguments. - :type: dynamic - :category: - - :default: 20 - - .. index:: - single: inlining, controlling - single: unfolding, controlling - - If we have a function f:: - - f x = - case x of - Zero -> 0 - Succ y -> case y of - Zero -> 1 - Succ z -> case z of - Zero -> 2 - _ -> error "Large" + This allows us to properly estimate the result code size from applying arguments + with complex structure to functions taking these arguments appart. - GHC can consider the nested use of the argument when making inlining decisions. - However looking deeply into nested argument use can be costly in terms of compile time overhead. - So we restrict inspection of nested argument use to a certain level of nesting. + However inspecting deeply nested arguments can be costly in terms of compile + time overhead. So we restrict these considerations to a certain depth. .. ghc-flag:: -fworker-wrapper :shortdesc: Enable the worker/wrapper transformation. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f0919c83e3ef82ad63e44723631b672e4580fb29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f0919c83e3ef82ad63e44723631b672e4580fb29 You're receiving 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 Oct 2 18:13:43 2022 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sun, 02 Oct 2022 14:13:43 -0400 Subject: [Git][ghc/ghc][wip/pattern-synonym-docs] Fix docs for pattern synonyms Message-ID: <6339d4d77a6e_2c9757514141422221@gitlab.mail> Brandon Chinn pushed to branch wip/pattern-synonym-docs at Glasgow Haskell Compiler / GHC Commits: cceea0f1 by Brandon Chinn at 2022-10-02T11:13:38-07:00 Fix docs for pattern synonyms - - - - - 1 changed file: - docs/users_guide/exts/pattern_synonyms.rst Changes: ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cceea0f195bc23219058fc0f59883550ab811b68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cceea0f195bc23219058fc0f59883550ab811b68 You're receiving 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 Oct 2 18:19:25 2022 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sun, 02 Oct 2022 14:19:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/chinn/T21730-import Message-ID: <6339d62d563ba_2c9757514141424362@gitlab.mail> Brandon Chinn pushed new branch wip/chinn/T21730-import at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/chinn/T21730-import You're receiving 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 Oct 2 18:23:40 2022 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sun, 02 Oct 2022 14:23:40 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/chinn/T21730-import Message-ID: <6339d72c32b0c_2c9757dfd401424555@gitlab.mail> Brandon Chinn deleted branch wip/chinn/T21730-import 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 Sun Oct 2 19:53:07 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Sun, 02 Oct 2022 15:53:07 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 359 commits: DmdAnal: Don't panic in addCaseBndrDmd (#22039) Message-ID: <6339ec23e789b_2c97575148c14271aa@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - bea3e880 by Josh Meredith at 2022-10-02T14:32:18-04:00 Add ghcjs changes to deriveConstants: - change String targetOS option in deriveConstants to an enum - separate out getWantedGHSJS, removing generated c file in this path - - - - - 905c954e by doyougnu at 2022-10-02T14:32:18-04:00 Add JavaScript code generator Adapt code generator of GHCJS to GHC head. Currently it is only enabled with the hidden -fjavascript flag. It produces .o files that can't be used yet except by GHCJS's linker. Codegen: doc Codegen: correctly return linkable object Now we can build a static library (-staticlib) Codegen: doc genLit Codegen: use assignAll Codegen: introduce TypedExpr Refactor assignAll et al, add documentation Codegen: minor changes Doc - - - - - fe226d6e by doyougnu at 2022-10-02T14:32:18-04:00 Add JS.Rts JS.Rts: compiles reword: progress on RtsTypes StgToJS.Config: add SDoc Context JSRts: move ppr, workaround def type JSRts.Types: compiles JS.Rts: closer to compiling JS.Rts: move jsIdIdent' to StgToJS.Monad JS.Rts: remove unused predicates JS: cleanup, comment sections, math funcs to Make JS.Rts.Types: compiles StgToJS.Expr: fix compilation errors StgToJS.DataCon: move initClosure JS.Rts: remove Alloc module JS.Rts: initalize Rts module, remove redundant fs JS: init Rts.Alloc move initClosure JS.Apply: unwinding combinators in progress JS: add helpers and fixmes JS.Rts.Apply: no more e's, add closure, reg helper StgToJS: add ToStat instance ClosureInfo JS.Rts.Apply: closer to compiling JS.Rts.Apply: more removal of # JS.Rts.Apply: (#) removed JS.Rts.Apply: compiles JS.Rts.Rts: just pretty printing left JS.Rts: Add Notes JS.Rts: add file headers and notes JS.Rts.Rts: fixing stringy issues JS.Rts.Rts: compiles JS.Rts.Rts: fix non-exhaustive patterns warnings - - - - - ee79436c by Sylvain Henry at 2022-10-02T14:32:18-04:00 Doc has been moved into GHC.StgToJs top-level module - - - - - d1f1e910 by Sylvain Henry at 2022-10-02T14:32:19-04:00 JS.Rts; refactoring and move to StgToJS * add closure manipulation helpers and use them in Apply * add cache (Array) for pre-generated PAP names * reduce line length: * use BlockArguments instead of parens * remove implicit mconcat in jVar's body Rts: more refactorings Rts: move into StgToJS hierarchy - - - - - b861896b by Sylvain Henry at 2022-10-02T14:32:19-04:00 JS: cleanup, renaming, better module layout Various degrees of cleanup adapting GHCJS to GHC. We move several functions to CoreUtils, remove duplication between the JS.Rts.Apply and Apply module and factor out closure related code into a Closure module for cohesion. Deduplicate code between Rts.Apply and Apply Move might_be_a_function into CoreUtils Factorize closure stuff into Closure module Rename closureExtra into closureField Minor renamings, comments... - - - - - 20a01a8f by Sylvain Henry at 2022-10-02T14:32:19-04:00 JS.Backend: add FFI code but don't implement yet FFI: don't crash on JavaScript foreign imports Note that they are still not desugared properly!! But the following cmd doesn't crash anymore: ghc -fjavascript Test.hs -fforce-recomp -ddump-tc -fno-code -ddump-ds FFI: adapt GHCJS desugarer FFI: support direct application The following example: foo :: Int# -> Int# foo = add 50000# foreign import javascript "(function(x,y) { return (x + y) })" add :: Int# -> Int# -> Int# is compiled into an application like this: var h$mainZCMzifoozur2_e; h$mainZCMzifoozur2_e = (function() { var h$mainZCMziaddzur1; h$mainZCMziaddzur1 = h$r1.d1; var h$$mainZCMzietazuB0_8KXnScrCjF5; h$$mainZCMzietazuB0_8KXnScrCjF5 = h$r2; h$r3 = h$$mainZCMzietazuB0_8KXnScrCjF5; h$r2 = 50000; h$r1 = h$mainZCMziaddzur1; return h$ap_2_2_fast(); return h$rs(); }); var h$mainZCMziaddzur1_e; h$mainZCMziaddzur1_e = (function() { var h$$mainZCMzidszusAk_236l8r0P8S9; h$$mainZCMzidszusAk_236l8r0P8S9 = h$r2; var h$$mainZCMzids1zusAl_336l8r0P8S9; h$$mainZCMzids1zusAl_336l8r0P8S9 = h$r3; var h$$mainZCM_2; var h$$mainZCMziwildzusAn_536l8r0P8S9; try { h$$mainZCMziwildzusAn_536l8r0P8S9 = (function(x,y) { return (x + y) })(h$$mainZCMzidszusAk_236l8r0P8S9, h$$mainZCMzids1zusAl_336l8r0P8S9) } catch(except) { return h$throwJSException(except) }; var h$$mainZCMzids3zusAp_736l8r0P8S9; h$$mainZCMzids3zusAp_736l8r0P8S9 = h$$mainZCMziwildzusAn_536l8r0P8S9; h$r1 = h$$mainZCMzids3zusAp_736l8r0P8S9; return h$rs(); }); FFI: correctly dispatch for foreign exports too FFI: move C FFI desugaring into its own module FFI: avoid DynFlags in toJsName (copy of toCName) - - - - - a1732f18 by Sylvain Henry at 2022-10-02T14:32:19-04:00 Configure: preliminary support for triple js-unknown-ghcjs - - - - - 0b91daee by Sylvain Henry at 2022-10-02T14:32:20-04:00 Driver: enable JS backend by default for JS arch - - - - - 57957cb4 by doyougnu at 2022-10-02T14:32:20-04:00 JS.Backend: Add JS specific Linker JS: initialize Linker, DynamicLinking JS.Printer: adapted to GHC Head JS.Printer: some cleanup and init Printer StgToJS.Printer: Compiles JS.Linker: Add types, expose JS keywords JS.Syntax: add Binary instance on Ident's JS.Linker: Migrate more Types to Data.Binary JS.Linker.Types: compiles and adapted to GHC Head JS.Linker.Types: compiles JS.Linker.Types: add UseBase type JS.Linker: Comments and Cleanup JS.Linker.Types: add TH types, Env type, DepsLoc JS.Linker: more FIXMEs numerous Linker fixes JS.Linker: removed Text references JS.UnitUtils: add package related helper functions JS.Linker: more DynFlags removal JS.Linker: Time for semantic errors JS.Linker: DynFlags finally removed JS.Linker: 107 compile errors to go JS.Linker.Utils: initialized, adapted to GHC Head JS.Linker.Utils: initialize Utils module JS.Linker.Utils: more utils JS.Rts: move rtsText to Rts JS.Linker: linkerStats implemented JS.Compactor: compiles, adapted to GHC Head JS.Compactor: have to retrofit compact for linker JS.Linker.Compactor: unwinding lenses JS.Linker.Compactor: comments over addItem JS.Linker.Compactor: Lenses removed JS.Linker.Compactor: SHA256 removed JS.Linker.Compactor: only missing instances left JS.Linker.Compactor: compiles JS.Linker: compiles, adapted to ghc Head JS.Linker: More progress JS.Linker: link in memory compiles JS.Linker: just shims left JS.Linker.DynamicLinking compiles: adapted to head JS.Linker.DynamicLinking: initialization JS.Linker.DynamicLinking: compiles up to Variants JS.Variants: initialize JS.Linker: numerous and various fixes JS.Linker.DynamicLinking: only small errors left JS.Linker.Archive: compiles, adapted to GHC Head JS.Linker: initialize Archive compat module JS.Linker.Archive: minor fixes JS.Linker.DynamicLinking: compiles JS.Linker: cleanup, remove Variants, add comments fixup: more cleanup JS.Linker: more cleanup and comments - - - - - 342e2d0a by Sylvain Henry at 2022-10-02T14:32:20-04:00 Minor panic fix - - - - - a327451f by Sylvain Henry at 2022-10-02T14:32:20-04:00 Linker: fix stage2 build - - - - - 90e08bfe by Sylvain Henry at 2022-10-02T14:32:21-04:00 Configure: Add support fo JS as unregistered ABI Configure: detect emscripten tools e.g. on ArchLinux: EMSDK=/usr/lib/emscripten EMSDK_LLVM=/opt/emscripten-llvm ./configure --target=js-unknown-ghcjs Configure: detect nm tool too, required by Hadrian Configure: make StgToJS use non-unregisterised ABI It should probably be a third kind of ABI... - - - - - 0ab051c2 by doyougnu at 2022-10-02T14:32:21-04:00 JS.Linker: Hook up to GHC.Driver.Pipeline JS.Linker.Types: Add newGhcjsEnv function JS.UnitUtils: fix encodeModule api JS.Linker: more removal of HscEnv JS.Linker: hooked into GHC.Driver.Pipeline - - - - - 8617b12d by Sylvain Henry at 2022-10-02T14:34:44-04:00 VERY WIP Hadrian/rts fixes export EMSDK_LLVM=/opt/emscripten-llvm export EMSDK=/usr/lib/emscripten export PATH=./inplace/ghcjs_toolchain/bin:$PATH ./configure --target=js-unknown-ghcjs ./hadrian/build --flavour=quick-js -j --bignum=native --docs=none -V - - - - - 49ac32f1 by Sylvain Henry at 2022-10-02T14:34:49-04:00 Force creation of rts library with dummy file - - - - - b490b19c by Sylvain Henry at 2022-10-02T14:34:49-04:00 ghc-prim: avoid building C files - - - - - 376cfb32 by Sylvain Henry at 2022-10-02T14:34:49-04:00 Hadrian: disable -fllvm - - - - - c48f2ff1 by Sylvain Henry at 2022-10-02T14:34:50-04:00 JS: fix caches Note that the fact that we need index 0 may hide another issue... - - - - - 2c79cd1e by Sylvain Henry at 2022-10-02T14:34:50-04:00 codegen: enhance genCon debug message - - - - - fad0bde0 by Sylvain Henry at 2022-10-02T14:34:50-04:00 RTS: fix stupid comment - - - - - 20e68576 by Sylvain Henry at 2022-10-02T14:34:50-04:00 RTS: embed headers - - - - - 8c876598 by Sylvain Henry at 2022-10-02T14:34:50-04:00 JS.StgToJS: add documentation header for JS Types - - - - - 068618a0 by Sylvain Henry at 2022-10-02T14:34:51-04:00 CodeGen: refactor ExprCtx code - - - - - aa981870 by Sylvain Henry at 2022-10-02T14:34:51-04:00 CodeGen: cache LNE frame size - - - - - bd8d55c3 by doyougnu at 2022-10-02T14:34:51-04:00 JS.Types: Add Outputable for TypedExpr - - - - - e7ab82f0 by doyougnu at 2022-10-02T14:34:51-04:00 JS.CoreUtils: handle IOPort case - - - - - be61f5e6 by doyougnu at 2022-10-02T14:34:51-04:00 JS.Expr: Fix unhandled datacon for RuntimeRep - - - - - 4573084b by doyougnu at 2022-10-02T14:34:52-04:00 JS.Literals: Adapt genLit to new Literal domain - - - - - 8921ab0d by Sylvain Henry at 2022-10-02T14:34:52-04:00 RTS: expose more headers (required to build base) - - - - - 6b290d5e by Sylvain Henry at 2022-10-02T14:34:52-04:00 Base: don't build C and Cmm sources with ghcjs - - - - - d7d0a007 by Sylvain Henry at 2022-10-02T14:34:52-04:00 Tentatively set NO_REGS for JS platforms - - - - - a0c1b082 by Sylvain Henry at 2022-10-02T14:34:52-04:00 CodeGen: output LitRubbish as null JS values - - - - - 8db5980b by Sylvain Henry at 2022-10-02T14:34:53-04:00 base: disable forkOS and bound thread machinery - - - - - 9f4fb961 by Sylvain Henry at 2022-10-02T14:34:53-04:00 CodeGen: support StackSnapshot# in primTypeVt - - - - - 2b508b5e by Sylvain Henry at 2022-10-02T14:34:53-04:00 CodeGen: better debug message for assignCoerce1 - - - - - 179e9717 by Sylvain Henry at 2022-10-02T14:34:53-04:00 Misc: enable HasDebugCallStack for zipWithEqual* - - - - - 06a14daa by Sylvain Henry at 2022-10-02T14:34:53-04:00 CodeGen: remove useless imports - - - - - 966b3896 by Sylvain Henry at 2022-10-02T14:34:54-04:00 Stg: expose pprStgAlt - - - - - c8e1ae63 by Sylvain Henry at 2022-10-02T14:34:54-04:00 CodeGen: restore assignAll (instead of assignAllEqual) - - - - - a3f1e56a by Sylvain Henry at 2022-10-02T14:34:54-04:00 CodeGen: handle proxy# - - - - - ab1eb451 by doyougnu at 2022-10-02T14:34:54-04:00 ghc-heap: Don't compile Cmm file for JS-Backend - - - - - 5c552bdd by doyougnu at 2022-10-02T14:34:54-04:00 Driver.Main: minor refactor do_code_gen To clearly separate the JS-Backend from any other backend - - - - - d1741871 by Sylvain Henry at 2022-10-02T14:34:54-04:00 Configure: fix echo on Mac, add ghcjs target OS - - - - - ef65a12d by Sylvain Henry at 2022-10-02T14:34:55-04:00 Configure: fix previous commit - - - - - 4c642f9f by Luite Stegeman at 2022-10-02T14:34:55-04:00 fix package name in module name field of system dependencies - - - - - 51a73fe4 by Luite Stegeman at 2022-10-02T14:34:55-04:00 fix duplicate module name in symbols - - - - - 95015786 by doyougnu at 2022-10-02T14:34:55-04:00 GHCi.FFI: ignore ffi.h and friends for js-backend - - - - - 39fa3fa3 by Sylvain Henry at 2022-10-02T14:34:55-04:00 RTS: fix build of native rts - - - - - 83571f4c by Sylvain Henry at 2022-10-02T14:34:56-04:00 Remove temporary -fjavascript flag - - - - - bb74d223 by Sylvain Henry at 2022-10-02T14:34:56-04:00 Codegen: fix symbol names ppr - - - - - 8bec6029 by Sylvain Henry at 2022-10-02T14:34:56-04:00 Outputable: add ShortText instance - - - - - 71ba2a1a by Sylvain Henry at 2022-10-02T14:34:56-04:00 Linker: enhance debugging message - - - - - 367f4e5b by Sylvain Henry at 2022-10-02T14:34:56-04:00 Remove unused ghcjs unit related code - - - - - fd018282 by Sylvain Henry at 2022-10-02T14:34:57-04:00 ghci: Avoid unused-xyz warnings - - - - - 2e830e94 by Sylvain Henry at 2022-10-02T14:34:57-04:00 Linker: remove wiring of ghcjs-prim and ghcjs-th They will be replaced by ghc-prim, base, template-haskell, etc. - - - - - 1e04274a by Sylvain Henry at 2022-10-02T14:34:57-04:00 Add outputable instance for Deps - - - - - a22744fa by doyougnu at 2022-10-02T14:34:57-04:00 Docs: JS.Syntax, JS.Make docs done JS-backend: Add documentation headers Docs: JS.Syntax done Docs: JS.Make done Docs: JS.Make JS.Syntax refined a bit - - - - - 7cd6a8d5 by Sylvain Henry at 2022-10-02T14:34:57-04:00 Rename u_env into unit_env (more common) - - - - - c0e09342 by Sylvain Henry at 2022-10-02T14:34:58-04:00 Linker: deduplication + fixes - deduplicate code that was copied from old GHC - explicitly add preloadUnits to the link - avoid calling getShims - - - - - 3b6544f4 by Sylvain Henry at 2022-10-02T14:34:58-04:00 Linker: reenable packStrings (not yet implemented though) - - - - - 1bfbb146 by Sylvain Henry at 2022-10-02T14:34:58-04:00 ShortText: add singleton - - - - - 0b27abf6 by Sylvain Henry at 2022-10-02T14:34:58-04:00 Linker: force less efficient (but working) static encoding - - - - - 6f852d18 by Luite Stegeman at 2022-10-02T14:34:58-04:00 add GHCJS modules to base package - - - - - be2a2ba1 by Sylvain Henry at 2022-10-02T14:34:59-04:00 Linker: remove JS Shims,tiny GHC.Linker refactor - - - - - 1534bcae by doyougnu at 2022-10-02T14:34:59-04:00 Hadrian: QuickJS ways [] --> Set - - - - - ead3a2d3 by doyougnu at 2022-10-02T14:34:59-04:00 JS-Backend: rebased to master 468f919b First rebase of the JS-Backend. This rebase includes the JS backend combined with !7442 (new backend design). Unfortunately we have to short circuit the new backend design because the JS backend takes over after STG and not after StgToCmm. What's working: - hadrian builds JS backend - JS backend outputs .js files and "links" them What still has to be done: - JS backend is missing core js libraries as we add these we discover bugs in the linker and js rts. - - - - - cd114848 by doyougnu at 2022-10-02T14:34:59-04:00 JS: silence haddock warnings JS Backend: remove misc. warnings - - - - - 54f943fa by doyougnu at 2022-10-02T14:34:59-04:00 JS Backend: ghcjs_HOST_OS --> js_HOST_ARCH - - - - - 6d25a9cc by Sylvain Henry at 2022-10-02T14:35:00-04:00 JS.Linker: add shims GHCJS uses JS files for primitive things like the GC and RTS. We call these JS files "shims". This sequence of commits adds shims from JS and includes them for linking. In addition the shim directory is controlled via an evironment variable JS_RTS_PATH...at least for now. Linker: implement tryReadShimFile Linker: link with shims provided via an env variable Use JS_RTS_PATH to provide a directory into which .js and .js.pp files will be linked into rts.js JS.Linker: add js dir at root, fix js cpp includes JS.gc.pp: remove variadic macro JS.RTS: add rts JS shims files, remove shim CPP RTS: remove the need for rts.h and add rts JS files rts.h only contained a few constants duplicated in the codegen. Let's use the Haskell version as the single source of truth and pass defined values explicitly to cpp command line ("-DXYZ=abc" arguments). Also switch from "raw" (use_cpp_and_not_cc_dash_E = True) to the opposite: in both case we call "cc -E" (meh), but with False the preprocessor doesn't choke one varargs in macros. RTS: remove integer.js.pp We use the native ghc-bignum backend, so we don't need the GMP compatible JS code. In addition, this code was failing to run as it requires the JSBN (https://www.npmjs.com/package/jsbn) "Javascript big number" library, which we don't necessarily have installed. RTS: fix typo in field name RTS: generate CPP macros in Haskell RTS: share common CPP def into CAFs - - - - - 4620ec86 by Sylvain Henry at 2022-10-02T14:35:00-04:00 CPP: disable line markers CPP: move option before input filename (to be squashed) - - - - - ba30a8f5 by Sylvain Henry at 2022-10-02T14:35:00-04:00 Linker: add more types Some cleanup Enhance and fix LinkerStats Document and refactor renderLinker Split collectDeps Fix collectDeps Fix linker stats rendering Remove unused seqListSpine It isn't used in ghcjs either - - - - - c69e10ce by Sylvain Henry at 2022-10-02T14:35:00-04:00 Add some missing primops (Word32,Int32) Also fix the rendering of missing primops (they must be z-encoded to avoid having a "#" in their JS name) - - - - - 6ce342e0 by Sylvain Henry at 2022-10-02T14:35:00-04:00 FFI: desugar every foreign import/export in JS with JS backend It means we also desugar CApi calls into JS. It's probably wrong but instead of generating invalid JS we will only get the failure at runtime when we will use the function. fixup - - - - - 1738ffe9 by doyougnu at 2022-10-02T14:35:01-04:00 JS.Linker: remove dflags includePath workaround. We implemented a workaround for shims that modified the dynflags includePaths so that the JS backend would find the rts.h file during CPP of shims. Since aebcca98 this is no longer required because we've removed the need for rts.h completely. Thus, this commit reverts that modification. - - - - - bd080245 by Sylvain Henry at 2022-10-02T14:35:01-04:00 Temporarily wire-in base's shim Use JS_BASE_PATH env var to set base's shim directory (js_base for now) Also minor other changes base: fix encoding for JS arch - - - - - 84214c20 by Sylvain Henry at 2022-10-02T14:35:01-04:00 Add primops Add primop - - - - - aa0db4b0 by doyougnu at 2022-10-02T14:35:01-04:00 Make Shims type, refactor JS Linker This commit: - Adds a proper Shim type and associated utilities. These utitlies are purposefully limited to ensure the ShimLbl tag is preserved thus guarenteeing shim ordering at link time. - Refactors the JS backend linker to use this ordering and Shim API. The ordering is not correct (yet!) but with this API its much easier to triage, experiment and diagnose link time issues. Refactor linker to compile time shim ordering - - - - - 3d418975 by doyougnu at 2022-10-02T14:35:01-04:00 Base: Adapt primitives to JS backend, add base.js - - - - - 961b41d4 by doyougnu at 2022-10-02T14:35:01-04:00 Base: Remove binding forms in JS ffi - - - - - 077669aa by Josh Meredith at 2022-10-02T14:35:02-04:00 Replace GHCJS Objectable with GHC Binary - - - - - e7d16352 by Sylvain Henry at 2022-10-02T14:35:02-04:00 Binary: remove unused Map instance - - - - - 028b842b by Sylvain Henry at 2022-10-02T14:35:02-04:00 CodeGen: Add export list - - - - - 525f8904 by Sylvain Henry at 2022-10-02T14:35:02-04:00 Primops: add some Int64/Word64 primops - - - - - 7d1d87e2 by Sylvain Henry at 2022-10-02T14:35:03-04:00 base: fix one ffi import - - - - - f838ff59 by doyougnu at 2022-10-02T14:35:03-04:00 base: CPP for JS-backend, adapt write in base shim This commit ports over each CPP directive from GHCJS to base. In addition, it adds struct.js.pp to Base shim directory and modifies h$base_write to always take 6 arguments. Thereby avoiding errors such as "c(bytesWritten) is not a function". The missing parameter was the file descriptor object, fdo, which was looked up in the function itself and is now passed through to comport with the FFI expectations. - - - - - 095620c3 by doyougnu at 2022-10-02T14:35:03-04:00 fixup: remove redundant struct.js.pp in js_base - - - - - ef0e8d34 by doyougnu at 2022-10-02T14:35:03-04:00 JS.Linker: enable linker RTS symbols - - - - - bd889329 by doyougnu at 2022-10-02T14:35:03-04:00 base.GHCJS: adapt Prim to direct call FFI format - - - - - c574a945 by doyougnu at 2022-10-02T14:35:04-04:00 Linker: Load JSVal from base not ghc-prim - - - - - 484d4a93 by doyougnu at 2022-10-02T14:35:04-04:00 fixup: caught one more reference to JSVal in prim - - - - - 0f903562 by Sylvain Henry at 2022-10-02T14:35:04-04:00 base: match on js arch , not ghcjs os - - - - - 3ace99b6 by Sylvain Henry at 2022-10-02T14:35:04-04:00 Fix MK_JSVAL - - - - - a4f658bf by doyougnu at 2022-10-02T14:35:05-04:00 Prim: cleanup comments - - - - - 56a2dc7e by doyougnu at 2022-10-02T14:35:05-04:00 JS.Prim: add Int64 PrimOps - - - - - 96cc328f by Sylvain Henry at 2022-10-02T14:35:05-04:00 Vendor MD5 lib - - - - - b34a53d7 by Sylvain Henry at 2022-10-02T14:35:05-04:00 More 64-bit primops - - - - - 1261fb76 by Sylvain Henry at 2022-10-02T14:35:05-04:00 CodeGen: use if10 helper - - - - - e0f7281f by Sylvain Henry at 2022-10-02T14:35:06-04:00 Ppr: fix selector to avoid adding a newline - - - - - 8b9f5355 by doyougnu at 2022-10-02T14:35:06-04:00 base: GHCJS.Prim make ffi imports use anon funcs - - - - - 31af9a82 by Sylvain Henry at 2022-10-02T14:35:06-04:00 Linker: disable invalid constructors again - - - - - 8a8a7648 by Sylvain Henry at 2022-10-02T14:35:06-04:00 More 64-bits primops - - - - - 4654ba8f by Sylvain Henry at 2022-10-02T14:35:06-04:00 Fix base_write function - - - - - eefb7b75 by Sylvain Henry at 2022-10-02T14:35:07-04:00 Fix base_write for 32-bit size_t - - - - - 60bcef03 by Sylvain Henry at 2022-10-02T14:35:07-04:00 Configure: fix detection of the target toolchain - - - - - ce80fb8a by Sylvain Henry at 2022-10-02T14:35:07-04:00 Remove js_base directory - - - - - 63038b6b by Sylvain Henry at 2022-10-02T14:35:07-04:00 Kill Node when the main loop reports an unhandled exception - - - - - c326778f by Sylvain Henry at 2022-10-02T14:35:07-04:00 CodeGen: preparation to make match on primops complete - - - - - 748d722a by Sylvain Henry at 2022-10-02T14:35:07-04:00 Primops: fix Compact primops - - - - - 100c696d by Sylvain Henry at 2022-10-02T14:35:08-04:00 Ignore result arity for some exception primops - - - - - 36c4b6ed by Sylvain Henry at 2022-10-02T14:35:08-04:00 Fix more primops. Bump array submodule! - - - - - f5b83bce by Sylvain Henry at 2022-10-02T14:35:08-04:00 Compact: fix return of 3 values - - - - - 7ed29cfd by Sylvain Henry at 2022-10-02T14:35:08-04:00 Configure: switch to absolute path - - - - - e08711ee by Sylvain Henry at 2022-10-02T14:35:08-04:00 Add a few primops - - - - - aafb39bd by Sylvain Henry at 2022-10-02T14:35:09-04:00 Primop: implement WordAdd2 - - - - - 5d3964a2 by Luite Stegeman at 2022-10-02T14:35:09-04:00 quick fix for uTypeVt and typePrimRep panics this may cause other panics, a full fix will require a bit more rework and probably removal of VarType - - - - - c6fdb0b7 by Josh Meredith at 2022-10-02T14:35:09-04:00 Replace ShortText with (Lexical)FastString in GHCJS backend - - - - - c9dd28b6 by Sylvain Henry at 2022-10-02T14:35:09-04:00 Primops: add arithmetic ops Primops: add decodeDoubleInt64 back Primop: added timesInt2# Primop: add mulWord32 and mul2Word32 - - - - - 8011da77 by Sylvain Henry at 2022-10-02T14:35:09-04:00 Reduce dependency on goog - - - - - 3ca0ebbe by Sylvain Henry at 2022-10-02T14:35:10-04:00 Primop: implement quotWord32, remWord32, and quotRemWord32 - - - - - 9f411739 by Sylvain Henry at 2022-10-02T14:35:10-04:00 Primop: Implement quotRem2Word32, misc fixes Primop: implement quotRem2Word32 Primop: fix timesInt2# Primop: fix some shifting primops - - - - - 9a6ea784 by Sylvain Henry at 2022-10-02T14:35:10-04:00 Fix bug in upd_frame I've introduced this bug when I've refactored the code to use helpers to assign closures. - - - - - 72de8930 by Sylvain Henry at 2022-10-02T14:35:10-04:00 Primop: throw an exception for unimplemented primops - - - - - 21afdae8 by Sylvain Henry at 2022-10-02T14:35:10-04:00 Primop: fix remWord32 - - - - - e0aec61f by Josh Meredith at 2022-10-02T14:35:11-04:00 Configure: add EMSDK_BIN, match emsdk expectations Change EMSDK vars to match emscripten/emsdk_env.sh definitions Add EMSDK_BIN environment variable to configure - - - - - 16e09ac9 by Sylvain Henry at 2022-10-02T14:35:11-04:00 resultSize: correctly handle Void# - - - - - ce29eb73 by Sylvain Henry at 2022-10-02T14:35:11-04:00 Primop: fix Sized test, more shifting fixes Primop: ensure that we return u32 values for word primops Also a refactoring from i3 to i32 for clarity. Primop: add/fix more shifting primops Primops: fix Sized test! - - - - - 89afe98a by Sylvain Henry at 2022-10-02T14:35:11-04:00 StgToJS.Apply: Docs Doc Doc - - - - - 05949bea by Josh Meredith at 2022-10-02T14:35:11-04:00 Fix EMSDK configure condition - - - - - 5e007d22 by doyougnu at 2022-10-02T14:35:12-04:00 StgToJS.Arg: Unboxable Literal Optimization note - - - - - fe911a64 by Sylvain Henry at 2022-10-02T14:35:12-04:00 Fix Outputable instances for JExpr/JVal - Put orphan instances in JS.Ppr - Also fix some redundant imports - - - - - 49effd4b by doyougnu at 2022-10-02T14:35:12-04:00 configure: avoid CXX stdlib check for js backend and some cleanup for a previously mis-applied commit during rebasing - - - - - 34d01c3c by doyougnu at 2022-10-02T14:35:12-04:00 fixup: misc. fixes post rebase - - - - - 1c6726e7 by Sylvain Henry at 2022-10-02T14:35:12-04:00 PrimOps: add more 64-bit primops PrimOp: implement more 64-bit primops + PM fix Ensure that we cover every primop explicitly - - - - - 103c0062 by Sylvain Henry at 2022-10-02T14:35:13-04:00 PrimOp: correclty (un)handle new thread related primops - - - - - 314cfb54 by Sylvain Henry at 2022-10-02T14:35:13-04:00 PrimOp: disable LabelThreadOp for now - - - - - 0bf05b17 by Sylvain Henry at 2022-10-02T14:35:13-04:00 Minor doc/cleanup Fix more redundant imports - - - - - 7c46109f by doyougnu at 2022-10-02T14:35:13-04:00 base: GHCJS.Prim directory --> GHC.JS.Prim - - - - - d7454442 by Luite Stegeman at 2022-10-02T14:35:14-04:00 implement KeepAlive primop - - - - - 03fcccce by Sylvain Henry at 2022-10-02T14:35:14-04:00 Remove orphan instance for StaticArg - - - - - d4c9dca2 by Sylvain Henry at 2022-10-02T14:35:14-04:00 Remove redundant jsIdIdent' function - - - - - ec7df189 by Sylvain Henry at 2022-10-02T14:35:14-04:00 Split StgToJS.Monad into StgToJS.{Monad,Ids,Stack} - - - - - 9f083fb1 by Sylvain Henry at 2022-10-02T14:35:14-04:00 Apply: remove commented case (wasn't optimized either in latest ghcjs) - - - - - 07ea2b0b by Sylvain Henry at 2022-10-02T14:35:15-04:00 Doc: Apply Apply: doc and refactoring - use new types instead of Bool/Int - factorize some code - - - - - 3aace720 by Sylvain Henry at 2022-10-02T14:35:15-04:00 Primop: arith fixes Primop: fix 64-bit shifting primops + add some traces Primop: fix quotRem2Word32 Primop: fix timesInt2. Progress towards passing arith003 PrimOp: fix timesInt32 PrimOp: use mulWord32 when appropriate - - - - - 45c0b30c by doyougnu at 2022-10-02T14:35:15-04:00 Configure: remove EMSDK hacks and wrapper scripts configure JS: remove wrapper scripts Configure: remove EMSDK hacks. Use emconfigure instead emconfigure ./configure --target=js-unknown-ghcjs - - - - - cfc4ffc8 by Sylvain Henry at 2022-10-02T14:35:15-04:00 GHCJS.Prim leftovers - - - - - f50a946c by Sylvain Henry at 2022-10-02T14:35:15-04:00 Linker: fix linking issue for tuples - - - - - 7a9c0afe by Sylvain Henry at 2022-10-02T14:35:16-04:00 FFI: remove narrowing Fix tests such as cgrun015 (Core lint error) - - - - - 804e6fe1 by Sylvain Henry at 2022-10-02T14:35:16-04:00 Linker: disable logs with default verbosity - - - - - 28aa7302 by Sylvain Henry at 2022-10-02T14:35:16-04:00 Append program name in top-level exception handler - - - - - b456884e by doyougnu at 2022-10-02T14:35:16-04:00 GHC.JS: Remove FIXMEs JS.Syntax: Remove FIXMEs JS.Make: remove FIXMEs JS.Ppr/Transform: Remove FIXMEs - - - - - cba7f9a3 by Sylvain Henry at 2022-10-02T14:35:16-04:00 Primop: fix timesInt2# Pass arith003 test - - - - - 6fabd857 by doyougnu at 2022-10-02T14:35:17-04:00 JS.Linker.Linker: remove FIXMEs, clean dead code - - - - - be2519ed by Sylvain Henry at 2022-10-02T14:35:17-04:00 Linker: link platform shim before the others - - - - - 1f842564 by Sylvain Henry at 2022-10-02T14:35:17-04:00 Primops: rework 64-bit and Word32 primops - Use BigInt instead of complex and buggy bit twiddling. We'll assess performance later. Let's use a correct and simple implementation for now. - Implement previously missing 64-bit quot and rem - Refactor logical operators and Prim module more generally - - - - - 69770001 by Sylvain Henry at 2022-10-02T14:35:17-04:00 PrimOp: fixup previous commit... - - - - - 277b73d7 by Sylvain Henry at 2022-10-02T14:35:18-04:00 Primop: fixup previous commit - - - - - 0fc9ade3 by Sylvain Henry at 2022-10-02T14:35:18-04:00 Doc: minor changes - - - - - b9495f6d by Sylvain Henry at 2022-10-02T14:35:18-04:00 Add debug option to watch for insertion of undefined/null in the stack - - - - - 183f9fff by Sylvain Henry at 2022-10-02T14:35:18-04:00 Apply: fix tag generation - - - - - 6f33191c by Sylvain Henry at 2022-10-02T14:35:18-04:00 Remove redundant import - - - - - 73e793b3 by Sylvain Henry at 2022-10-02T14:35:19-04:00 Testsuite: disable Cmm tests with the JS backend - - - - - d291d080 by Sylvain Henry at 2022-10-02T14:35:19-04:00 Base: fix c_interruptible_open - - - - - 5aaec337 by Sylvain Henry at 2022-10-02T14:35:19-04:00 Base: fix typo in long_from_number - - - - - 694e0734 by Sylvain Henry at 2022-10-02T14:35:19-04:00 Env: only add program name to errors, not to traces - - - - - 645e96fb by Sylvain Henry at 2022-10-02T14:35:19-04:00 Testsuite: disable more Cmm tests - - - - - 75b180b6 by doyougnu at 2022-10-02T14:35:19-04:00 JS.Linker: removes FIXMEs JS.Linker.Linker: remove FIXMEs, clean dead code StgToJS.Linker.Utils: remove FIXMEs Compactor: Remove FIXMEs StgToJS.Linker.Types: Remove FIXMEs JS.Linker.Archive/Dynamic: remove FIXMEs StgToJS.Linker.Shims: remove FIXMEs - - - - - e108ae59 by doyougnu at 2022-10-02T14:35:20-04:00 JS RTS: remove FIXMEs StgToJS.Rts.Types: Remove FIXMEs - - - - - 37407855 by Sylvain Henry at 2022-10-02T14:35:20-04:00 Primop: fix bswap32/64 (cf cgrun072) - - - - - ae66c1a7 by Sylvain Henry at 2022-10-02T14:35:20-04:00 Testsuite: normalise ghc program name - - - - - a984939f by doyougnu at 2022-10-02T14:35:20-04:00 JS Backend: Remove FIXMEs StgToJS.Apply: Remove FIXMEs StgToJS.FFI: remove FIXMEs StgToJS.Expr: remove FIXMEs StgToJS: Remove FIXMEs - - - - - 646b82ba by Sylvain Henry at 2022-10-02T14:35:20-04:00 Enable RTS args filtering (cf cgrun025) - - - - - 31f10ddd by Sylvain Henry at 2022-10-02T14:35:21-04:00 Remove trailing whitespaces (whitespace test) - - - - - 289f8d2c by Sylvain Henry at 2022-10-02T14:35:21-04:00 Testsuite: remove platform prefix for unlit tool - - - - - 18ed51e4 by Sylvain Henry at 2022-10-02T14:35:21-04:00 Primop: fix Int64 conversion/negate (integerConversions test) - - - - - c9b6d1c4 by Sylvain Henry at 2022-10-02T14:35:21-04:00 Linker: remove message with default verbosity - - - - - 771bb0f5 by Sylvain Henry at 2022-10-02T14:35:22-04:00 Testsuite: normalise .jsexe suffix - - - - - 2c536507 by Sylvain Henry at 2022-10-02T14:35:22-04:00 Remove warning about orphan instance - - - - - 1d7b442f by Sylvain Henry at 2022-10-02T14:35:22-04:00 Compactor: disable dead code - - - - - 0279057b by Sylvain Henry at 2022-10-02T14:35:22-04:00 Exception: implement raiseUnderflow etc. as primops - - - - - ebbc5777 by Sylvain Henry at 2022-10-02T14:35:22-04:00 Primop: fix Int8/18 quot/rem - - - - - e53eab67 by Sylvain Henry at 2022-10-02T14:35:23-04:00 Linker: refactor wired-in deps - - - - - 58afdfb8 by Sylvain Henry at 2022-10-02T14:35:23-04:00 Ppr: remove useless left padding for functions in JS dumps - - - - - a15ea327 by Josh Meredith at 2022-10-02T14:35:23-04:00 Disable llvm ways and ghci for JS backend testsuite - - - - - a5e899b9 by Sylvain Henry at 2022-10-02T14:35:23-04:00 StaticPtr: don't generate CStubs for the JS backend - - - - - c14be598 by Sylvain Henry at 2022-10-02T14:35:23-04:00 StaticPtr: fix hs_spt_lookup after upstream change - - - - - 190a863e by Sylvain Henry at 2022-10-02T14:35:24-04:00 Testsuite: fix normalisation for unlit T8430 shows: `js-unknown-ghcjs-unlit' failed in phase `Literate pre-processor'. (Exit code: 1) Notice the quote around the program name. So I've made the regex match more cases (i.e. not only lines starting with the program name). - - - - - 7c4353d7 by Sylvain Henry at 2022-10-02T14:35:24-04:00 Codegen: fix codegen of string literals Due to FastString change: Before: Text.pack . BSC.unpack After: mkFastString . BSC.unpack It seems that Text handles buggy multi-byte codepoints split into several String Chars. - - - - - e3032ffc by Sylvain Henry at 2022-10-02T14:35:24-04:00 CPP: fix LINE markers. Only disable them for JS - - - - - 54645bc5 by Luite Stegeman at 2022-10-02T14:37:55-04:00 add JavaScript files listed in js-sources to package archives - - - - - f6bbfabe by Luite Stegeman at 2022-10-02T14:37:59-04:00 update rts js files to include recent fixes - - - - - 80993453 by Luite Stegeman at 2022-10-02T14:37:59-04:00 fix definitions in js/rts.h - - - - - 658eaa3a by Josh Meredith at 2022-10-02T14:38:00-04:00 stopgap fix for missing ghc-pkg in cross-compiler tests - - - - - bc7e12bb by Sylvain Henry at 2022-10-02T14:38:00-04:00 Testsuite: better fix for finding prefixed tools - - - - - fdc31c5e by Sylvain Henry at 2022-10-02T14:38:00-04:00 Ppr: add hangBrace helper - - - - - 5da49c85 by Sylvain Henry at 2022-10-02T14:38:00-04:00 Only declare ccs var in profiling mode - - - - - 85e45c64 by Sylvain Henry at 2022-10-02T14:38:00-04:00 Don't consider recursive bindings as inline nor as evaluated Fix mdo001 - - - - - 1c38b7d5 by Sylvain Henry at 2022-10-02T14:38:01-04:00 Hadrian: disable shared libs for JS target - - - - - 868b86b0 by Sylvain Henry at 2022-10-02T14:38:01-04:00 Support -ddump-stg-final with the JS backend - - - - - 1495d7f3 by Sylvain Henry at 2022-10-02T14:38:01-04:00 Add ticky_ghc0 flavour transformer to ticky stage1 - - - - - 246cb9e1 by Sylvain Henry at 2022-10-02T14:38:01-04:00 Don't read object file when -ddump-js isn't passed - - - - - a7f8d415 by Sylvain Henry at 2022-10-02T14:38:01-04:00 Object: remove dead code + renaming - - - - - caff1451 by Sylvain Henry at 2022-10-02T14:38:02-04:00 Object: replace SymbolTableR with Dictionary - - - - - 6f47c83d by Sylvain Henry at 2022-10-02T14:38:02-04:00 Object: refactoring - - - - - c499a09c by Sylvain Henry at 2022-10-02T14:38:02-04:00 RTS: link platform.js before the others! - - - - - ca5011bc by Sylvain Henry at 2022-10-02T14:38:02-04:00 Hadrian: treat JS objects similarly to other objects - - - - - b5e5f1f1 by Luite Stegeman at 2022-10-02T14:38:02-04:00 fix javascript FFI calls for read and write - - - - - 88507917 by doyougnu at 2022-10-02T14:38:03-04:00 propagate ppr code changes to JS backend - - - - - 7843ade6 by Sylvain Henry at 2022-10-02T14:38:03-04:00 Switch from Data.Binary and ByteString to BinHandle - - - - - b3304f0d by Sylvain Henry at 2022-10-02T14:38:03-04:00 Perf: use Ppr's LeftMode to output JS - - - - - 67b53f7c by doyougnu at 2022-10-02T14:38:03-04:00 Primops: Add {Index,Write,Read}ByteArrayAs ops Still need to check for correctness based on T4442. minor doc fixes fixup: add some Index..As primops fixup missed type signature Primops: Add WriteByteArrayOp_Word8AsFoo ops Primops: {Index,Read,Write}FooAsBar done except Addr's Primops: add {Index,Read,Write}ByteArrayAsAddr ops These will need to be tested for correctness with T4442.hs - - - - - 025ce0b1 by Sylvain Henry at 2022-10-02T14:38:03-04:00 Move platform.js to base (it must be linked first) - - - - - f523bc7e by Sylvain Henry at 2022-10-02T14:38:04-04:00 Remove old shim directory - - - - - 0f6ffc6a by doyougnu at 2022-10-02T15:49:29-04:00 JS.Prim: more PrimOps {IndexByteArrayAs, CAS} Primop: WriteByteArrayOp_Word8AsChar use setInt8 Primops: remove dv_s_u8 This function is non-sensical. Due to the infelicities of JS as a platform we must use Int8 and friends to write, then coerce to a word, thus dv_s_iN are the only legal calls for a write, and dv_s_uN legal for Index and Reads. Primops: set dv_u8 to correct method call should be getUint8, not getUInt8, of course the naming convention changes ever so slightly for Words. Primops: T4442 finishes ByteArrayAs still fails JS.Prim: More IndexByteAAs primops JS.Prim: Prefetch PrimOps are noOps JS.Primops: Doc explaining lack of vector support JS.Prim: add CAS and Fetch Ops - - - - - 7c0d9f71 by doyougnu at 2022-10-02T15:50:45-04:00 GHC.Utils.Binary: BinDictionary -> FSTable Rename to avoid naming conflict with haddock. - - - - - 09f1ed63 by Josh Meredith at 2022-10-02T15:50:45-04:00 Adjust derefnull test exit code for ghcjs - - - - - 86c66d33 by doyougnu at 2022-10-02T15:50:45-04:00 Fix Driver missing type signature warnings - - - - - 00c09dd6 by doyougnu at 2022-10-02T15:50:45-04:00 PipeLine.Execute: silence warnings on JS backend - - - - - 5903d8a6 by doyougnu at 2022-10-02T15:50:45-04:00 JS.Primops: Add Bit reverse ops - - - - - 66dc3924 by doyougnu at 2022-10-02T15:50:46-04:00 SysTools.Tasks: quiet non-totality warnings - - - - - 15e6d84a by doyougnu at 2022-10-02T15:50:46-04:00 JS.Primops: Add InterlockedExchange Addr Word - - - - - 0fd97149 by Sylvain Henry at 2022-10-02T15:50:46-04:00 base: conditional js-sources - - - - - 7031f2cd by Sylvain Henry at 2022-10-02T15:50:46-04:00 TH: add support for JS files - - - - - 26874f14 by Sylvain Henry at 2022-10-02T15:50:46-04:00 Linker: fix creation of directories in output paths - - - - - f972a2c4 by Sylvain Henry at 2022-10-02T15:50:46-04:00 Backpack: fix empty stubs - - - - - d9555749 by Sylvain Henry at 2022-10-02T15:50:47-04:00 Add encodeDouble/Float RTS functions - - - - - 7367b122 by Sylvain Henry at 2022-10-02T15:50:47-04:00 encodeDouble: correctly handle 0 base - - - - - c69c84a5 by doyougnu at 2022-10-02T15:50:47-04:00 JS.Primops: Add listThreads op - - - - - 2242ff55 by doyougnu at 2022-10-02T15:50:47-04:00 JS.Primops: Add Read/WriteAddrOp ops - - - - - 09411526 by doyougnu at 2022-10-02T15:50:47-04:00 JS: Linker and Compactor: cleanup and docs Compactor: Cleanup: Remove dead comments JS.Linker.Types: cleanup and document module - - - - - c80f12ca by doyougnu at 2022-10-02T15:50:47-04:00 StgToJS.Linker: Add docs to utility modules StgToJS.Linker.Utils: more docs StgToJS.Linker.Archive: more docs - - - - - d5e2684c by doyougnu at 2022-10-02T15:50:48-04:00 StgToJS.Object: Add documentation - - - - - 98cf128a by Sylvain Henry at 2022-10-02T15:50:48-04:00 Refactor Expr - - - - - f3950422 by Sylvain Henry at 2022-10-02T15:50:48-04:00 Object: reduce pinned allocation. And don't forget to hClose invalid objects - - - - - d104517c by Sylvain Henry at 2022-10-02T15:50:48-04:00 Fix pdep (cgrun075) - - - - - 9deb6f4d by Sylvain Henry at 2022-10-02T15:50:48-04:00 Fix error message (don't mention emscripten) - - - - - 38edfcb7 by Sylvain Henry at 2022-10-02T15:50:49-04:00 Add Float/Word casts - - - - - 36e64d74 by Sylvain Henry at 2022-10-02T15:50:49-04:00 Disable HPC tests with JS backend - - - - - e589c3d2 by Sylvain Henry at 2022-10-02T15:50:49-04:00 Fix encodeDouble/Float - - - - - d57e76ed by Sylvain Henry at 2022-10-02T15:50:49-04:00 Implement putchar (fix cgrun015) - - - - - 289691bf by Sylvain Henry at 2022-10-02T15:50:49-04:00 Fix decoding of denormalized floats - - - - - abad80bd by Sylvain Henry at 2022-10-02T15:50:49-04:00 Fix isFloatDenormalized function - - - - - ffeb892d by Sylvain Henry at 2022-10-02T15:50:50-04:00 Reuse convert buffer - - - - - 8a02e46f by Sylvain Henry at 2022-10-02T15:50:50-04:00 Reuse convert buffer bis - - - - - af01f3e7 by Sylvain Henry at 2022-10-02T15:50:50-04:00 Skip some tests that require the dynamic linker - - - - - 4616a911 by Josh Meredith at 2022-10-02T15:50:50-04:00 JavaScript ShrinkSmallMutableArrayOp_Char & GetSizeofSmallMutableArrayOp - - - - - 3af8aa5a by Sylvain Henry at 2022-10-02T15:50:50-04:00 Disable more linker tests - - - - - 34e3eca5 by Sylvain Henry at 2022-10-02T15:50:50-04:00 Testsuite: better normalisation for ghc and ghc-pkg Allow normalisation for ghc and ghc-pkg anywhere in the output, not just at the beginning of the line. Fix T1750 and ghcpkg05 for example - - - - - 60c08ad7 by Sylvain Henry at 2022-10-02T15:50:50-04:00 Skip T14373 because it requires Cmm - - - - - 123fe84e by Sylvain Henry at 2022-10-02T15:50:51-04:00 Disable cg010 with JS backend - - - - - 1b674f7c by Sylvain Henry at 2022-10-02T15:50:51-04:00 Testsuite: better normalisation of .jsexe extension - - - - - cf50e08d by doyougnu at 2022-10-02T15:52:06-04:00 JS: Linker,Rts docs and cleanup JS.Linker: Cleanup: remove unused functions/types JS.Rts.Types: remove dead code, docs StgToJS.RTS: cleanup and more docs - - - - - 26fb6a91 by Sylvain Henry at 2022-10-02T15:52:18-04:00 Disable recomp015 - - - - - 6ca51286 by Sylvain Henry at 2022-10-02T15:52:18-04:00 Minor refactoring - - - - - 238f66eb by Sylvain Henry at 2022-10-02T15:52:18-04:00 Temporary fix the testsuite bug - - - - - 42db926e by doyougnu at 2022-10-02T15:52:18-04:00 JS.StgToJS.Types: Docs and cleanup - - - - - 17cd1502 by Josh Meredith at 2022-10-02T15:52:19-04:00 change JS.Transform.Idents* to use UniqDSet from Set - - - - - 25b82eed by Sylvain Henry at 2022-10-02T15:52:19-04:00 Minor Linker cleanup Minor cleanup - - - - - 186b8b60 by Sylvain Henry at 2022-10-02T15:52:19-04:00 Linker: load all the dependent units transitively - - - - - 178a1724 by doyougnu at 2022-10-02T15:52:19-04:00 JS: Add Docs and cleanup StgToJS.{Arg,Ids} JS.Arg: docs and cleanup StgToJS.Arg: add minimal docs StgToJS.Ids: Add header - - - - - c12a233f by Sylvain Henry at 2022-10-02T15:52:19-04:00 Implement h$sleep (T5611) - - - - - 260e5b88 by Sylvain Henry at 2022-10-02T15:52:20-04:00 Linker: don't link the same unit twice - - - - - 1e645ecc by doyougnu at 2022-10-02T15:52:20-04:00 JS: docs, cleanup, StgToJS.{Expr,DataCon,Stack} StgToJS.Deps/Expr: add docs StgToJS.DataCon: add minor docs StgToJS.Stack: Docs and cleanup In particular: -- Removing some single use functions -- Some minor refactors related to these removals StgToJS: comments on static args and optimizeFree - - - - - 1eba6392 by Sylvain Henry at 2022-10-02T15:52:20-04:00 Disable compact tests - - - - - e1a040b0 by Sylvain Henry at 2022-10-02T15:52:20-04:00 Add support for JS files passed on the command line - - - - - d38164af by Sylvain Henry at 2022-10-02T15:52:20-04:00 Minor cleanup in compactor - - - - - ace64c34 by Sylvain Henry at 2022-10-02T15:52:20-04:00 Fix encoding of unboxed strings (don't pass through FastString/h$str) - - - - - 109e40c9 by doyougnu at 2022-10-02T15:52:20-04:00 JS: Misc fixes post Del-Cont rebase - - - - - 30 changed files: - − .appveyor.sh - .gitlab-ci.yml - .gitlab/ci.sh - − appveyor.yml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Liveness.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Reg.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/BlockLayout.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bed7d64a1572c4cd677e72fb016be50404098b86...109e40c9c08822cbbb4eba3b52f448cd8a050895 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bed7d64a1572c4cd677e72fb016be50404098b86...109e40c9c08822cbbb4eba3b52f448cd8a050895 You're receiving 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 Oct 3 08:35:28 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 03 Oct 2022 04:35:28 -0400 Subject: [Git][ghc/ghc][wip/T21623] Improve boxing-data-con API Message-ID: <633a9ed0eb815_2c97575140014656b2@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: 720fa45f by Simon Peyton Jones at 2022-10-03T09:37:25+01:00 Improve boxing-data-con API - - - - - 3 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/SetLevels.hs Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Builtin.Types ( promotedLTDataCon, promotedEQDataCon, promotedGTDataCon, -- * Boxing primitive types - boxingDataCon_maybe, boxingDataConUnlifted_maybe, + boxingDataCon, BoxingInfo(..), -- * Char charTyCon, charDataCon, charTyCon_RDR, @@ -1937,14 +1937,25 @@ Wrinkles So we treat Int# and Char# specially, in specialBoxingDataCon_maybe -} -type BoxingInfo b = (DataCon, Expr b, Type) - -- (K, K ty, boxed type) - -- e.g. (I#, I#, Int) - -- recall: data Int = I# Int# - -- or (MkInt8Box, MkInt8Box @ty, Int8Box ty) - -- recall: data Int8Box (a :: TYPE Int8Rep) = MkIntBox a - -boxingDataCon_maybe :: HasDebugCallStack => Type -> Maybe (BoxingInfo b) +data BoxingInfo b + = BI_NoBoxNeeded -- The type has kind Type, so there is nothing to do + + | BI_NoBoxAvailable -- The type does not have kind Type, but sadly we + -- don't have a boxing data constructor either + + | BI_Box -- The type does not have kind Type, and we do have a + -- boxing data constructor; here it is + { bi_data_con :: DataCon + , bi_inst_con :: Expr b + , bi_boxed_type :: Type } + -- e.g. BI_Box { bi_data_con = I#, bi_inst_con = I#, bi_boxed_type = Int } + -- recall: data Int = I# Int# + -- + -- BI_Box { bi_data_con = MkInt8Box, bi_inst_con = MkInt8Box @ty + -- , bi_boxed_type = Int8Box ty }A + -- recall: data Int8Box (a :: TYPE Int8Rep) = MkIntBox a + +boxingDataCon :: Type -> BoxingInfo b -- ^ Given a type 'ty', if 'ty' is not of kind Type, return a data constructor that -- will box it, and the type of the boxed thing, which /does/ now have kind Type. -- @@ -1953,46 +1964,23 @@ boxingDataCon_maybe :: HasDebugCallStack => Type -> Maybe (BoxingInfo b) -- This variant panics if it is given a non-TYPE type -- that it does not know how to box. -- See Note [Boxing constructors] -boxingDataCon_maybe ty +boxingDataCon ty | tcIsLiftedTypeKind kind - = Nothing -- Fast path for Type - - | Just stuff <- get_boxing_data_con ty kind - = Just stuff - - | otherwise - = pprPanic "boxingDataCon_maybe" (ppr ty <+> dcolon <+> ppr kind) - where - kind = typeKind ty + = BI_NoBoxNeeded -- Fast path for Type -boxingDataConUnlifted_maybe :: HasDebugCallStack => Type -> Maybe (BoxingInfo b) --- ^ Given a type 'ty', if 'ty' is not of kind Type, return a data constructor that --- will box it, and the type of the boxed thing, which /does/ now have kind Type. --- --- Nothing => no boxing necessary (already of kind Type) --- or no suitable boxing data constructor is available. --- --- This variant expects the type to be unlifted, and does not --- fail if there is no suitable DataCon (it returns Nothing instead); --- used in SetLevels --- See Note [Boxing constructors] -boxingDataConUnlifted_maybe ty - = assertPpr (not (isLiftedTypeKind kind)) (ppr ty $$ ppr kind) - get_boxing_data_con ty (typeKind ty) - where - kind = typeKind ty - -get_boxing_data_con :: Type -> Kind -> Maybe (BoxingInfo b) --- See Note [Boxing constructors] -get_boxing_data_con ty kind | Just box_con <- specialBoxingDataCon_maybe ty - = Just (box_con, mkConApp box_con [], tyConNullaryTy (dataConTyCon box_con)) + = BI_Box { bi_data_con = box_con, bi_inst_con = mkConApp box_con [] + , bi_boxed_type = tyConNullaryTy (dataConTyCon box_con) } | Just box_con <- lookupTypeMap boxingDataConMap kind - = Just (box_con, mkConApp box_con [Type ty], mkTyConApp (dataConTyCon box_con) [ty]) + = BI_Box { bi_data_con = box_con, bi_inst_con = mkConApp box_con [Type ty] + , bi_boxed_type = mkTyConApp (dataConTyCon box_con) [ty] } | otherwise - = Nothing + = BI_NoBoxAvailable + + where + kind = typeKind ty specialBoxingDataCon_maybe :: Type -> Maybe DataCon -- ^ See Note [Boxing constructors] wrinkle (W1) ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -464,7 +464,7 @@ mkBigCoreVarTup ids = mkBigCoreTup (map Var ids) -- | Build a "big" tuple holding the specified expressions -- One-tuples are flattened; see Note [Flattening one-tuples] -- Arguments don't have to have kind Type; ones that do not are boxed --- This function crashes (in boxingDataCon_maybe) if given a non-Type +-- This function crashes (in wrapBox) if given a non-Type -- argument that it doesn't know how to box. mkBigCoreTup :: [CoreExpr] -> CoreExpr mkBigCoreTup exprs = mkChunkified mkCoreTup (map wrapBox exprs) @@ -491,12 +491,12 @@ wrapBox :: CoreExpr -> CoreExpr -- which has kind Type -- where K is the boxing data constructor for ki -- See Note [Boxing constructors] in GHC.Builtin.Types --- Crashes in boxingDataCon_maybe if there /is/ no boxing data con +-- Panics if there /is/ no boxing data con wrapBox e - | Just (_, boxing_expr, _) <- boxingDataCon_maybe e_ty - = App boxing_expr e - | otherwise - = e + = case boxingDataCon e_ty of + BI_NoBoxNeeded -> e + BI_Box { bi_inst_con = boxing_expr } -> App boxing_expr e + BI_NoBoxAvailable -> pprPanic "wrapBox" (ppr e $$ ppr (exprType e)) where e_ty = exprType e @@ -506,10 +506,10 @@ boxTy :: Type -> Type -- of (K @ty e), where K is the boxing data constructor for ki -- See Note [Boxing constructors] in GHC.Builtin.Types boxTy ty - | Just (_, _, box_ty) <- boxingDataCon_maybe ty - = box_ty - | otherwise - = ty + = case boxingDataCon ty of + BI_NoBoxNeeded -> ty + BI_Box { bi_boxed_type = box_ty } -> box_ty + BI_NoBoxAvailable -> pprPanic "boxTy" (ppr ty) unwrapBox :: UniqSupply -> Id -> CoreExpr -> (UniqSupply, Id, CoreExpr) @@ -520,15 +520,18 @@ unwrapBox :: UniqSupply -> Id -> CoreExpr -- where box_v is a fresh variable -- Otherwise unwrapBox is a no-op unwrapBox us var body - | let var_ty = idType var - , Just (box_con, _, box_ty) <- boxingDataCon_maybe var_ty - , let var' = mkSysLocal (fsLit "uc") uniq ManyTy box_ty - body' = Case (Var var') var' (exprType body) + = case boxingDataCon var_ty of + BI_NoBoxNeeded -> (us, var, body) + BI_NoBoxAvailable -> pprPanic "unwrapBox" (ppr var $$ ppr var_ty) + BI_Box { bi_data_con = box_con, bi_boxed_type = box_ty } + -> (us', var', body') + where + var' = mkSysLocal (fsLit "uc") uniq ManyTy box_ty + body' = Case (Var var') var' (exprType body) [Alt (DataAlt box_con) [var] body] - (uniq, us') = takeUniqFromSupply us - = (us', var', body') - - | otherwise = (us, var, body) + where + var_ty = idType var + (uniq, us') = takeUniqFromSupply us -- | Lifts a \"small\" constructor into a \"big\" constructor by recursive decomposition mkChunkified :: ([a] -> a) -- ^ \"Small\" constructor function, of maximum input arity 'mAX_TUPLE_SIZE' ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -672,7 +672,8 @@ lvlMFE env strict_ctxt ann_expr | escapes_value_lam , not expr_ok_for_spec -- Boxing/unboxing isn't worth it for cheap expressions -- See Note [Test cheapness with exprOkForSpeculation] - , Just (box_dc, boxing_expr, box_ty) <- boxingDataConUnlifted_maybe expr_ty + , BI_Box { bi_data_con = box_dc, bi_inst_con = boxing_expr + , bi_boxed_type = box_ty } <- boxingDataCon expr_ty , let [bx_bndr, ubx_bndr] = mkTemplateLocals [box_ty, expr_ty] = do { expr1 <- lvlExpr rhs_env ann_expr ; let l1r = incMinorLvlFrom rhs_env View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/720fa45f07397c22bbd45f20065c0beb3f78d585 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/720fa45f07397c22bbd45f20065c0beb3f78d585 You're receiving 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 Oct 3 09:27:23 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 03 Oct 2022 05:27:23 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 302 commits: StgLint: Check that functions are applied to compatible runtime reps Message-ID: <633aaafb75070_2c97575148c14892b5@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 636f7c62 by Andreas Klebinger at 2022-05-01T22:21:17-04:00 StgLint: Check that functions are applied to compatible runtime reps We use compatibleRep to compare reps, and avoid checking functions with levity polymorphic types because of #21399. - - - - - 60071076 by Hécate Moonlight at 2022-05-01T22:21:55-04:00 Add documentation to the ByteArray# primetype. close #21417 - - - - - 2b2e3020 by Andreas Klebinger at 2022-05-01T22:22:31-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. - - - - - 4eaf0f33 by Eric Lindblad at 2022-05-01T22:23:11-04:00 typos - - - - - fc58df90 by Niklas Hambüchen at 2022-05-02T08:59:27+00:00 libraries/base: docs: Explain relationshipt between `finalizeForeignPtr` and `*Conc*` creation Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/21420 - - - - - 3e400f20 by Krzysztof Gogolewski at 2022-05-02T18:29:23-04:00 Remove obsolete code in CoreToStg Note [Nullary unboxed tuple] was removed in e9e61f18a548b70693f4. This codepath is tested by T15696_3. - - - - - 4a780928 by Krzysztof Gogolewski at 2022-05-02T18:29:24-04:00 Fix several note references - - - - - 15ffe2b0 by Sebastian Graf at 2022-05-03T20:11:51+02:00 Assume at least one evaluation for nested SubDemands (#21081, #21133) See the new `Note [SubDemand denotes at least one evaluation]`. A demand `n :* sd` on a let binder `x=e` now means > "`x` was evaluated `n` times and in any program trace it is evaluated, `e` is > evaluated deeply in sub-demand `sd`." The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081) ```hs f :: (Bool, Bool) -> (Bool, Bool) f pr = (case pr of (a,b) -> a /= b, True) -- before: <MP(L,L)> -- after: <MP(SL,SL)> g :: Int -> (Bool, Bool) g x = let y = let z = odd x in (z,z) in f y ``` The change in demand signature "before" to "after" allows us to case-bind `z` here. Similarly good things happen for the `sd` in call sub-demands `Cn(sd)`, which allows for more eta-reduction (which is only sound with `-fno-pedantic-bottoms`, albeit). We also fix #21085, a surprising inconsistency with `Poly` to `Call` sub-demand expansion. In an attempt to fix a regression caused by less inlining due to eta-reduction in T15426, I eta-expanded the definition of `elemIndex` and `elemIndices`, thus fixing #21345 on the go. The main point of this patch is that it fixes #21081 and #21133. Annoyingly, I discovered that more precise demand signatures for join points can transform a program into a lazier program if that join point gets floated to the top-level, see #21392. There is no simple fix at the moment, but !5349 might. Thus, we accept a ~5% regression in `MultiLayerModulesTH_OneShot`, where #21392 bites us in `addListToUniqDSet`. T21392 reliably reproduces the issue. Surprisingly, ghc/alloc perf on Windows improves much more than on other jobs, by 0.4% in the geometric mean and by 2% in T16875. Metric Increase: MultiLayerModulesTH_OneShot Metric Decrease: T16875 - - - - - 948c7e40 by Andreas Klebinger at 2022-05-04T09:57:34-04:00 CoreLint - When checking for levity polymorphism look through more ticks. For expressions like `(scc<cc_name> primOp#) arg1` we should also look at arg1 to determine if we call primOp# at a fixed runtime rep. This is what corePrep already does but CoreLint didn't yet. This patch will bring them in sync in this regard. It also uses tickishFloatable in CorePrep instead of CorePrep having it's own slightly differing definition of when a tick is floatable. - - - - - 85bc73bd by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Support Unicode properly - - - - - 063d485e by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Replace LaTeX documentation syntax with Haddock The LaTeX documentation generator does not seem to have been used for quite some time, so the LaTeX-to-Haddock preprocessing step has become a pointless complication that makes documenting the contents of GHC.Prim needlessly difficult. This commit replaces the LaTeX syntax with the Haddock it would have been converted into, anyway, though with an additional distinction: it uses single quotes in places to instruct Haddock to generate hyperlinks to bindings. This improves the quality of the generated output. - - - - - d61f7428 by Ben Gamari at 2022-05-04T09:58:50-04:00 rts/ghc.mk: Only build StgCRunAsm.S when it is needed Previously the make build system unconditionally included StgCRunAsm.S in the link, meaning that the RTS would require an execstack unnecessarily. Fixes #21478. - - - - - 934a90dd by Simon Peyton Jones at 2022-05-04T16:15:34-04:00 Improve error reporting in generated code Our error reporting in generated code (via desugaring before typechecking) only worked when the generated code was just a simple call. This commit makes it work in nested cases. - - - - - 445d3657 by sheaf at 2022-05-04T16:16:12-04:00 Ensure Any is not levity-polymorphic in FFI The previous patch forgot to account for a type such as Any @(TYPE (BoxedRep l)) for a quantified levity variable l. - - - - - ddd2591c by Ben Gamari at 2022-05-04T16:16:48-04:00 Update supported LLVM versions Pull forward minimum version to match 9.2. (cherry picked from commit c26faa54c5fbe902ccb74e79d87e3fa705e270d1) - - - - - f9698d79 by Ben Gamari at 2022-05-04T16:16:48-04:00 testsuite/T7275: Use sed -r Darwin requires the `-r` flag to be compatible with GNU sed. (cherry picked from commit 512338c8feec96c38ef0cf799f3a01b77c967c56) - - - - - 8635323b by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Use ld.lld on ARMv7/Linux Due to #16177. Also cleanup some code style issues. (cherry picked from commit cc1c3861e2372f464bf9e3c9c4d4bd83f275a1a6) - - - - - 4f6370c7 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Always preserve artifacts, even in failed jobs (cherry picked from commit fd08b0c91ea3cab39184f1b1b1aafcd63ce6973f) - - - - - 6f662754 by Ben Gamari at 2022-05-04T16:16:48-04:00 configure: Make sphinx version check more robust It appears that the version of sphinx shipped on CentOS 7 reports a version string of `Sphinx v1...`. Accept the `v`. (cherry picked from commit a9197a292fd4b13308dc6664c01351c7239357ed) - - - - - 0032dc38 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Don't run make job in release pipelines (cherry picked from commit 16d6a8ff011f2194485387dcca1c00f8ddcdbdeb) - - - - - 27f9aab3 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab/ci: Fix name of bootstrap compiler directory Windows binary distributions built with Hadrian have a target platform suffix in the name of their root directory. Teach `ci.sh` about this fact. (cherry picked from commit df5752f39671f6d04d8cd743003469ae5eb67235) - - - - - b528f0f6 by Krzysztof Gogolewski at 2022-05-05T09:05:43-04:00 Fix several note references, part 2 - - - - - 691aacf6 by Adam Sandberg Ericsson at 2022-05-05T09:06:19-04:00 adjustors: align comment about number of integer like arguments with implementation for Amd4+MinGW implementation - - - - - f050557e by Simon Jakobi at 2022-05-05T12:47:32-04:00 Remove two uses of IntMap.size IntMap.size is O(n). The new code should be slightly more efficient. The transformation of GHC.CmmToAsm.CFG.calcFreqs.nodeCount can be described formally as the transformation: (\sum_{0}^{n-1} \sum_{0}^{k-1} i_nk) + n ==> (\sum_{0}^{n-1} 1 + \sum_{0}^{k-1} i_nk) - - - - - 7da90ae3 by Tom Ellis at 2022-05-05T12:48:09-04:00 Explain that 'fail s' should run in the monad itself - - - - - 610d0283 by Matthew Craven at 2022-05-05T12:48:47-04:00 Add a test for the bracketing in rules for (^) - - - - - 016f9ca6 by Matthew Craven at 2022-05-05T12:48:47-04:00 Fix broken rules for (^) with known small powers - - - - - 9372aaab by Matthew Craven at 2022-05-05T12:48:47-04:00 Give the two T19569 tests different names - - - - - 61901b32 by Andreas Klebinger at 2022-05-05T12:49:23-04:00 SpecConstr: Properly create rules for call patterns representing partial applications The main fix is that in addVoidWorkerArg we now add the argument to the front. This fixes #21448. ------------------------- Metric Decrease: T16875 ------------------------- - - - - - 71278dc7 by Teo Camarasu at 2022-05-05T12:50:03-04:00 add since annotations for instances of ByteArray - - - - - 962ff90b by sheaf at 2022-05-05T12:50:42-04:00 Start 9.6.1-notes Updates the documentation notes to start tracking changes for the 9.6.1 release (instead of 9.4). - - - - - aacb15a3 by Matthew Pickering at 2022-05-05T20:24:01-04:00 ci: Add job to check that jobs.yaml is up-to-date There have been quite a few situations where jobs.yaml has been out of date. It's better to add a CI job which checks that it's right. We don't want to use a staged pipeline because it obfuscates the structure of the pipeline. - - - - - be7102e5 by Ben Gamari at 2022-05-05T20:24:37-04:00 rts: Ensure that XMM registers are preserved on Win64 Previously we only preserved the bottom 64-bits of the callee-saved 128-bit XMM registers, in violation of the Win64 calling convention. Fix this. Fixes #21465. - - - - - 73b22ff1 by Ben Gamari at 2022-05-05T20:24:37-04:00 testsuite: Add test for #21465 - - - - - e2ae9518 by Ziyang Liu at 2022-05-06T19:22:22-04:00 Allow `let` just before pure/return in ApplicativeDo The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case. - - - - - 0415449a by Matthew Pickering at 2022-05-06T19:22:58-04:00 template-haskell: Fix representation of OPAQUE pragmas There is a mis-match between the TH representation of OPAQUE pragmas and GHC's internal representation due to how OPAQUE pragmas disallow phase annotations. It seemed most in keeping to just fix the wired in name issue by adding a special case to the desugaring of INLINE pragmas rather than making TH/GHC agree with how the representation should look. Fixes #21463 - - - - - 4de887e2 by Simon Peyton Jones at 2022-05-06T19:23:34-04:00 Comments only: Note [AppCtxt] - - - - - 6e69964d by Matthew Pickering at 2022-05-06T19:24:10-04:00 Fix name of windows release bindist in doc-tarball job - - - - - ced4689e by Matthew Pickering at 2022-05-06T19:24:46-04:00 ci: Generate source-tarball in release jobs We need to distribute the source tarball so we should generate it in the CI pipeline. - - - - - 3c91de21 by Rob at 2022-05-08T13:40:53+02:00 Change Specialise to use OrdList. Fixes #21362 Metric Decrease: T16875 - - - - - 67072c31 by Simon Jakobi at 2022-05-08T12:23:43-04:00 Tweak GHC.CmmToAsm.CFG.delEdge mapAdjust is more efficient than mapAlter. - - - - - 374554bb by Teo Camarasu at 2022-05-09T16:24:37-04:00 Respect -po when heap profiling (#21446) - - - - - 1ea414b6 by Teo Camarasu at 2022-05-09T16:24:37-04:00 add test case for #21446 - - - - - c7902078 by Jens Petersen at 2022-05-09T16:25:17-04:00 avoid hadrian/bindist/Makefile install_docs error when --docs=none When docs are disabled the bindist does not have docs/ and hence docs-utils/ is not generated. Here we just test that docs-utils exists before attempting to install prologue.txt and gen_contents_index to avoid the error: /usr/bin/install: cannot stat 'docs-utils/prologue.txt': No such file or directory make: *** [Makefile:195: install_docs] Error 1 - - - - - 158bd659 by Hécate Moonlight at 2022-05-09T16:25:56-04:00 Correct base's changelog for 4.16.1.0 This commit reaffects the new Ix instances of the foreign integral types from base 4.17 to 4.16.1.0 closes #21529 - - - - - a4fbb589 by Sylvain Henry at 2022-05-09T16:26:36-04:00 STG: only print cost-center if asked to - - - - - 50347ded by Gergo ERDI at 2022-05-10T11:43:33+00:00 Improve "Glomming" note Add a paragraph that clarifies that `occurAnalysePgm` finding out-of-order references, and thus needing to glom, is not a cause for concern when its root cause is rewrite rules. - - - - - df2e3373 by Eric Lindblad at 2022-05-10T20:45:41-04:00 update INSTALL - - - - - dcac3833 by Matthew Pickering at 2022-05-10T20:46:16-04:00 driver: Make -no-keep-o-files -no-keep-hi-files work in --make mode It seems like it was just an oversight to use the incorrect DynFlags (global rather than local) when implementing these two options. Using the local flags allows users to request these intermediate files get cleaned up, which works fine in --make mode because 1. Interface files are stored in memory 2. Object files are only cleaned at the end of session (after link) Fixes #21349 - - - - - 35da81f8 by Ben Gamari at 2022-05-10T20:46:52-04:00 configure: Check for ffi.h As noted in #21485, we checked for ffi.h yet then failed to throw an error if it is missing. Fixes #21485. - - - - - bdc99cc2 by Simon Peyton Jones at 2022-05-10T20:47:28-04:00 Check for uninferrable variables in tcInferPatSynDecl This fixes #21479 See Note [Unquantified tyvars in a pattern synonym] While doing this, I found that some error messages pointed at the pattern synonym /name/, rather than the /declaration/ so I widened the SrcSpan to encompass the declaration. - - - - - 142a73d9 by Matthew Pickering at 2022-05-10T20:48:04-04:00 hadrian: Fix split-sections transformer The splitSections transformer has been broken since -dynamic-too support was implemented in hadrian. This is because we actually build the dynamic way when building the dynamic way, so the predicate would always fail. The fix is to just always pass `split-sections` even if it doesn't do anything for a particular way. Fixes #21138 - - - - - 699f5935 by Matthew Pickering at 2022-05-10T20:48:04-04:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. Closes #21135 - - - - - 21feece2 by Simon Peyton Jones at 2022-05-10T20:48:39-04:00 Use the wrapper for an unlifted binding We assumed the wrapper for an unlifted binding is the identity, but as #21516 showed, that is no always true. Solution is simple: use it. - - - - - 68d1ea5f by Matthew Pickering at 2022-05-10T20:49:15-04:00 docs: Fix path to GHC API docs in index.html In the make bindists we generate documentation in docs/ghc-<VER> but the hadrian bindists generate docs/ghc/ so the path to the GHC API docs was wrong in the index.html file. Rather than make the hadrian and make bindists the same it was easier to assume that if you're using the mkDocs script that you're using hadrian bindists. Fixes #21509 - - - - - 9d8f44a9 by Matthew Pickering at 2022-05-10T20:49:51-04:00 hadrian: Don't pass -j to haddock This has high potential for oversubcribing as many haddock jobs can be spawned in parralel which will each request the given number of capabilities. Once -jsem is implemented (#19416, !5176) we can expose that haddock via haddock and use that to pass a semaphore. Ticket #21136 - - - - - fec3e7aa by Matthew Pickering at 2022-05-10T20:50:27-04:00 hadrian: Only copy and install libffi headers when using in-tree libffi When passed `--use-system-libffi` then we shouldn't copy and install the headers from the system package. Instead the headers are expected to be available as a runtime dependency on the users system. Fixes #21485 #21487 - - - - - 5b791ed3 by mikael at 2022-05-11T08:22:13-04:00 FIND_LLVM_PROG: Recognize llvm suffix used by FreeBSD, ie llc10. - - - - - 8500206e by ARATA Mizuki at 2022-05-11T08:22:57-04:00 Make floating-point abs IEEE 754 compliant The old code used by via-C backend didn't handle the sign bit of NaN. See #21043. - - - - - 4a4c77ed by Alan Zimmerman at 2022-05-11T08:23:33-04:00 EPA: do statement with leading semicolon has wrong anchor The code do; a <- doAsync; b Generated an incorrect Anchor for the statement list that starts after the first semicolon. This commit fixes it. Closes #20256 - - - - - e3ca8dac by Simon Peyton Jones at 2022-05-11T08:24:08-04:00 Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. - - - - - fcc7dc4c by Ben Gamari at 2022-05-11T20:05:41-04:00 gitlab-ci: Check for dynamic msys2 dependencies Both #20878 and #21196 were caused by unwanted dynamic dependencies being introduced by boot libraries. Ensure that we catch this in CI by attempting to run GHC in an environment with a minimal PATH. - - - - - 3c998f0d by Matthew Pickering at 2022-05-11T20:06:16-04:00 Add back Debian9 CI jobs We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19 not being at EOL until April 2023 and they still need tinfo5. Fixes #21469 - - - - - dea9a3d9 by Ben Gamari at 2022-05-11T20:06:51-04:00 rts: Drop setExecutable Since f6e366c058b136f0789a42222b8189510a3693d1 setExecutable has been dead code. Drop it. - - - - - 32cdf62d by Simon Peyton Jones at 2022-05-11T20:07:27-04:00 Add a missing guard in GHC.HsToCore.Utils.is_flat_prod_pat This missing guard gave rise to #21519. - - - - - 2c00a8d0 by Matthew Pickering at 2022-05-11T20:08:02-04:00 Add mention of -hi to RTS --help Fixes #21546 - - - - - a2dcad4e by Andre Marianiello at 2022-05-12T02:15:48+00:00 Decouple dynflags in Cmm parser (related to #17957) - - - - - 3a022baa by Andre Marianiello at 2022-05-12T02:15:48+00:00 Remove Module argument from initCmmParserConfig - - - - - 2fc8d76b by Andre Marianiello at 2022-05-12T02:15:48+00:00 Move CmmParserConfig and PDConfig into GHC.Cmm.Parser.Config - - - - - b8c5ffab by Andre Marianiello at 2022-05-12T18:13:55-04:00 Decouple dynflags in GHC.Core.Opt.Arity (related to #17957) Metric Decrease: T16875 - - - - - 3bf938b6 by sheaf at 2022-05-12T18:14:34-04:00 Update extending_ghc for TcPlugin changes The documentation still mentioned Derived constraints and an outdated datatype TcPluginResult. - - - - - 668a9ef4 by jackohughes at 2022-05-13T12:10:34-04:00 Fix printing of brackets in multiplicities (#20315) Change mulArrow to allow for printing of correct application precedence where necessary and update callers of mulArrow to reflect this. As part of this, move mulArrow from GHC/Utils/Outputtable to GHC/Iface/Type. Fixes #20315 - - - - - 30b8b7f1 by Ben Gamari at 2022-05-13T12:11:09-04:00 rts: Add debug output on ocResolve failure This makes it easier to see how resolution failures nest. - - - - - 53b3fa1c by Ben Gamari at 2022-05-13T12:11:09-04:00 rts/PEi386: Fix handling of weak symbols Previously we would flag the symbol as weak but failed to set its address, which must be computed from an "auxiliary" symbol entry the follows the weak symbol. Fixes #21556. - - - - - 5678f017 by Ben Gamari at 2022-05-13T12:11:09-04:00 testsuite: Add tests for #21556 - - - - - 49af0e52 by Ben Gamari at 2022-05-13T22:23:26-04:00 Re-export augment and build from GHC.List Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/19127 - - - - - aed356e1 by Simon Peyton Jones at 2022-05-13T22:24:02-04:00 Comments only around HsWrapper - - - - - 27b90409 by Ben Gamari at 2022-05-16T08:30:44-04:00 hadrian: Introduce linting flavour transformer (+lint) The linting flavour enables -dlint uniformly across anything build by the stage1 compiler. -dcmm-lint is not currently enabled because it fails on i386 (see #21563) - - - - - 3f316776 by Matthew Pickering at 2022-05-16T08:30:44-04:00 hadrian: Uniformly enable -dlint with enableLinting transformer This fixes some bugs where * -dcore-lint was being passed when building stage1 libraries with the boot compiler * -dcore-lint was not being passed when building executables. Fixes #20135 - - - - - 3d74cfca by Andreas Klebinger at 2022-05-16T08:31:20-04:00 Make closure macros EXTERN_INLINE to make debugging easier Implements #21424. The RTS macros get_itbl and friends are extremely helpful during debugging. However only a select few of those were available in the compiled RTS as actual symbols as the rest were INLINE macros. This commit marks all of them as EXTERN_INLINE. This will still inline them at use sites but allow us to use their compiled counterparts during debugging. This allows us to use things like `p get_fun_itbl(ptr)` in the gdb shell since `get_fun_itbl` will now be available as symbol! - - - - - 93153aab by Matthew Pickering at 2022-05-16T08:31:55-04:00 packaging: Introduce CI job for generating hackage documentation This adds a CI job (hackage-doc-tarball) which generates the necessary tarballs for uploading libraries and documentation to hackage. The release script knows to download this folder and the upload script will also upload the release to hackage as part of the release. The `ghc_upload_libs` script is moved from ghc-utils into .gitlab/ghc_upload_libs There are two modes, preparation and upload. * The `prepare` mode takes a link to a bindist and creates a folder containing the source and doc tarballs ready to upload to hackage. * The `upload` mode takes the folder created by prepare and performs the upload to hackage. Fixes #21493 Related to #21512 - - - - - 65d31d05 by Simon Peyton Jones at 2022-05-16T15:32:50-04:00 Add arity to the INLINE pragmas for pattern synonyms The lack of INLNE arity was exposed by #21531. The fix is simple enough, if a bit clumsy. - - - - - 43c018aa by Krzysztof Gogolewski at 2022-05-16T15:33:25-04:00 Misc cleanup - Remove groupWithName (unused) - Use the RuntimeRepType synonym where possible - Replace getUniqueM + mkSysLocalOrCoVar with mkSysLocalOrCoVarM No functional changes. - - - - - 8dfea078 by Pavol Vargovcik at 2022-05-16T15:34:04-04:00 TcPlugin: access to irreducible givens + fix passed ev_binds_var - - - - - fb579e15 by Ben Gamari at 2022-05-17T00:25:02-04:00 driver: Introduce pgmcxx Here we introduce proper support for compilation of C++ objects. This includes: * logic in `configure` to detect the C++ toolchain and propagating this information into the `settings` file * logic in the driver to use the C++ toolchain when compiling C++ sources - - - - - 43628ed4 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Build T20918 with HC, not CXX - - - - - 0ef249aa by Ben Gamari at 2022-05-17T00:25:02-04:00 Introduce package to capture dependency on C++ stdlib Here we introduce a new "virtual" package into the initial package database, `system-cxx-std-lib`. This gives users a convenient, platform agnostic way to link against C++ libraries, addressing #20010. Fixes #20010. - - - - - 03efe283 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Add tests for system-cxx-std-lib package Test that we can successfully link against C++ code both in GHCi and batch compilation. See #20010 - - - - - 5f6527e0 by nineonine at 2022-05-17T00:25:38-04:00 OverloadedRecordFields: mention parent name in 'ambiguous occurrence' error for better disambiguation (#17420) - - - - - eccdb208 by Simon Peyton Jones at 2022-05-17T07:16:39-04:00 Adjust flags for pprTrace We were using defaultSDocContext for pprTrace, which suppresses lots of useful infomation. This small MR adds GHC.Utils.Outputable.traceSDocContext and uses it for pprTrace and pprTraceUserWarning. traceSDocContext is a global, and hence not influenced by flags, but that seems unavoidable. But I made the sdocPprDebug bit controlled by unsafeHasPprDebug, since we have the latter for exactly this purpose. Fixes #21569 - - - - - d2284c4c by Simon Peyton Jones at 2022-05-17T07:17:15-04:00 Fix bad interaction between withDict and the Specialiser This MR fixes a bad bug, where the withDict was inlined too vigorously, which in turn made the type-class Specialiser generate a bogus specialisation, because it saw the same overloaded function applied to two /different/ dictionaries. Solution: inline `withDict` later. See (WD8) of Note [withDict] in GHC.HsToCore.Expr See #21575, which is fixed by this change. - - - - - 70f52443 by Matthew Pickering at 2022-05-17T07:17:50-04:00 Bump time submodule to 1.12.2 This bumps the time submodule to the 1.12.2 release. Fixes #21571 - - - - - 2343457d by Vladislav Zavialov at 2022-05-17T07:18:26-04:00 Remove unused test files (#21582) Those files were moved to the perf/ subtree in 11c9a469, and then accidentally reintroduced in 680ef2c8. - - - - - cb52b4ae by Ben Gamari at 2022-05-17T16:00:14-04:00 CafAnal: Improve code clarity Here we implement a few measures to improve the clarity of the CAF analysis implementation. Specifically: * Use CafInfo instead of Bool since the former is more descriptive * Rename CAFLabel to CAFfyLabel, since not all CAFfyLabels are in fact CAFs * Add numerous comments - - - - - b048a9f4 by Ben Gamari at 2022-05-17T16:00:14-04:00 codeGen: Ensure that static datacon apps are included in SRTs When generating an SRT for a recursive group, GHC.Cmm.Info.Build.oneSRT filters out recursive references, as described in Note [recursive SRTs]. However, doing so for static functions would be unsound, for the reason described in Note [Invalid optimisation: shortcutting]. However, the same argument applies to static data constructor applications, as we discovered in #20959. Fix this by ensuring that static data constructor applications are included in recursive SRTs. The approach here is not entirely satisfactory, but it is a starting point. Fixes #20959. - - - - - 0e2d16eb by Matthew Pickering at 2022-05-17T16:00:50-04:00 Add test for #21558 This is now fixed on master and 9.2 branch. Closes #21558 - - - - - ef3c8d9e by Sylvain Henry at 2022-05-17T20:22:02-04:00 Don't store LlvmConfig into DynFlags LlvmConfig contains information read from llvm-passes and llvm-targets files in GHC's top directory. Reading these files is done only when needed (i.e. when the LLVM backend is used) and cached for the whole compiler session. This patch changes the way this is done: - Split LlvmConfig into LlvmConfig and LlvmConfigCache - Store LlvmConfigCache in HscEnv instead of DynFlags: there is no good reason to store it in DynFlags. As it is fixed per session, we store it in the session state instead (HscEnv). - Initializing LlvmConfigCache required some changes to driver functions such as newHscEnv. I've used the opportunity to untangle initHscEnv from initGhcMonad (in top-level GHC module) and to move it to GHC.Driver.Main, close to newHscEnv. - I've also made `cmmPipeline` independent of HscEnv in order to remove the call to newHscEnv in regalloc_unit_tests. - - - - - 828fbd8a by Andreas Klebinger at 2022-05-17T20:22:38-04:00 Give all EXTERN_INLINE closure macros prototypes - - - - - cfc8e2e2 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Introduce [sg]etFinalizerExceptionHandler This introduces a global hook which is called when an exception is thrown during finalization. - - - - - 372cf730 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Throw exceptions raised while closing finalized Handles Fixes #21336. - - - - - 3dd2f944 by Ben Gamari at 2022-05-19T04:57:51-04:00 testsuite: Add tests for #21336 - - - - - 297156e0 by Matthew Pickering at 2022-05-19T04:58:27-04:00 Add release flavour and use it for the release jobs The release flavour is essentially the same as the perf flavour currently but also enables `-haddock`. I have hopefully updated all the relevant places where the `-perf` flavour was hardcoded. Fixes #21486 - - - - - a05b6293 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Don't build sphinx documentation on centos The centos docker image lacks the sphinx builder so we disable building sphinx docs for these jobs. Fixes #21580 - - - - - 209d7c69 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Use correct syntax when args list is empty This seems to fail on the ancient version of bash present on CentOS - - - - - 02d16334 by Matthew Pickering at 2022-05-19T04:59:03-04:00 hadrian: Don't attempt to build dynamic profiling libraries We only support building static profiling libraries, the transformer was requesting things like a dynamic, threaded, debug, profiling RTS, which we have never produced nor distributed. Fixes #21567 - - - - - 35bdab1c by Ben Gamari at 2022-05-19T04:59:39-04:00 configure: Check CC_STAGE0 for --target support We previously only checked the stage 1/2 compiler for --target support. We got away with this for quite a while but it eventually caught up with us in #21579, where `bytestring`'s new NEON implementation was unbuildable on Darwin due to Rosetta's seemingly random logic for determining which executable image to execute. This lead to a confusing failure to build `bytestring`'s cbits, when `clang` tried to compile NEON builtins while targetting x86-64. Fix this by checking CC_STAGE0 for --target support. Fixes #21579. - - - - - 0ccca94b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator analysis of `CmmGraph` This commit adds module `GHC.Cmm.Dominators`, which provides a wrapper around two existing algorithms in GHC: the Lengauer-Tarjan dominator analysis from the X86 back end and the reverse postorder ordering from the Cmm Dataflow framework. Issue #20726 proposes that we evaluate some alternatives for dominator analysis, but for the time being, the best path forward is simply to use the existing analysis on `CmmGraph`s. This commit addresses a bullet in #21200. - - - - - 54f0b578 by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator-tree function - - - - - 05ed917b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add HasDebugCallStack; remove unneeded extensions - - - - - 0b848136 by Andreas Klebinger at 2022-05-20T05:32:32-04:00 document fields of `DominatorSet` - - - - - 8a26e8d6 by Ben Gamari at 2022-05-20T05:33:08-04:00 nonmoving: Fix documentation of GC statistics fields These were previously incorrect. Fixes #21553. - - - - - c1e24e61 by Matthew Pickering at 2022-05-20T05:33:44-04:00 Remove pprTrace from pushCoercionIntoLambda (#21555) This firstly caused spurious output to be emitted (as evidenced by #21555) but even worse caused a massive coercion to be attempted to be printed (> 200k terms) which would invariably eats up all the memory of your computer. The good news is that removing this trace allows the program to compile to completion, the bad news is that the program exhibits a core lint error (on 9.0.2) but not any other releases it seems. Fixes #21577 and #21555 - - - - - a36d12ee by Zubin Duggal at 2022-05-20T10:44:35-04:00 docs: Fix LlvmVersion in manpage (#21280) - - - - - 36b8a57c by Matthew Pickering at 2022-05-20T10:45:10-04:00 validate: Use $make rather than make In the validate script we are careful to use the $make variable as this stores whether we are using gmake, make, quiet mode etc. There was just this one place where we failed to use it. Fixes #21598 - - - - - 4aa3c5bd by Norman Ramsey at 2022-05-21T03:11:04+00:00 Change `Backend` type and remove direct dependencies With this change, `Backend` becomes an abstract type (there are no more exposed value constructors). Decisions that were formerly made by asking "is the current back end equal to (or different from) this named value constructor?" are now made by interrogating the back end about its properties, which are functions exported by `GHC.Driver.Backend`. There is a description of how to migrate code using `Backend` in the user guide. Clients using the GHC API can find a backdoor to access the Backend datatype in GHC.Driver.Backend.Internal. Bumps haddock submodule. Fixes #20927 - - - - - ecf5f363 by Julian Ospald at 2022-05-21T12:51:16-04:00 Respect DESTDIR in hadrian bindist Makefile, fixes #19646 - - - - - 7edd991e by Julian Ospald at 2022-05-21T12:51:16-04:00 Test DESTDIR in test_hadrian() - - - - - ea895b94 by Matthew Pickering at 2022-05-22T21:57:47-04:00 Consider the stage of typeable evidence when checking stage restriction We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547 - - - - - ffbe28e5 by Dominik Peteler at 2022-05-22T21:58:23-04:00 Modularize GHC.Core.Opt.LiberateCase Progress towards #17957 - - - - - bc723ac2 by Simon Peyton Jones at 2022-05-23T17:09:34+01:00 Improve FloatOut and SpecConstr This patch addresses a relatively obscure situation that arose when chasing perf regressions in !7847, which itself is fixing It does two things: * SpecConstr can specialise on ($df d1 d2) dictionary arguments * FloatOut no longer checks argument strictness See Note [Specialising on dictionaries] in GHC.Core.Opt.SpecConstr. A test case is difficult to construct, but it makes a big difference in nofib/real/eff/VSM, at least when we have the patch for #21286 installed. (The latter stops worker/wrapper for dictionary arguments). There is a spectacular, but slightly illusory, improvement in runtime perf on T15426. I have documented the specifics in T15426 itself. Metric Decrease: T15426 - - - - - 1a4195b0 by John Ericson at 2022-05-23T17:33:59-04:00 Make debug a `Bool` not an `Int` in `StgToCmmConfig` We don't need any more resolution than this. Rename the field to `stgToCmmEmitDebugInfo` to indicate it is no longer conveying any "level" information. - - - - - e9fff12b by Alan Zimmerman at 2022-05-23T21:04:49-04:00 EPA : Remove duplicate comments in DataFamInstD The code data instance Method PGMigration = MigrationQuery Query -- ^ Run a query against the database | MigrationCode (Connection -> IO (Either String ())) -- ^ Run any arbitrary IO code Resulted in two instances of the "-- ^ Run a query against the database" comment appearing in the Exact Print Annotations when it was parsed. Ensure only one is kept. Closes #20239 - - - - - e2520df3 by Alan Zimmerman at 2022-05-23T21:05:27-04:00 EPA: Comment Order Reversed Make sure comments captured in the exact print annotations are in order of increasing location Closes #20718 - - - - - 4b45fd72 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Add test for T21455 - - - - - e2cd1d43 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Allow passing -po outside profiling way Resolves #21455 - - - - - 3b8c413a by Greg Steuck at 2022-05-24T10:49:52-04:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 1db877a3 by Ben Gamari at 2022-05-24T10:50:28-04:00 hadrian/bindist: Drop redundant include of install.mk `install.mk` is already included by `config.mk`. Moreover, `install.mk` depends upon `config.mk` to set `RelocatableBuild`, making this first include incorrect. - - - - - f485d267 by Greg Steuck at 2022-05-24T10:51:08-04:00 Remove -z wxneeded for OpenBSD With all the recent W^X fixes in the loader this workaround is not necessary any longer. I verified that the only tests failing for me on OpenBSD 7.1-current are the same (libc++ related) before and after this commit (with --fast). - - - - - 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Bodigrim at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergo ERDI at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Bodigrim at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 96ddaf02 by Sven Tennie at 2022-07-03T09:27:51+00:00 Save point: Decode to list of closure types - - - - - 44ad8e00 by Sven Tennie at 2022-07-03T09:28:04+00:00 cleanup - - - - - dfd5d571 by Sven Tennie at 2022-07-03T09:28:04+00:00 Sync for Zurihack - - - - - 51adda0e by Sven Tennie at 2022-07-03T09:28:04+00:00 Segfaults, but compiles again - - - - - 6d734013 by Sven Tennie at 2022-07-03T09:28:04+00:00 Doesn't segfault anymore - - - - - 9a4050be by Sven Tennie at 2022-07-03T09:28:04+00:00 More on RET_SMALL decoding - - - - - dec58adb by Sven Tennie at 2022-07-03T13:50:01+00:00 Decode BIG_RET - - - - - 3564d604 by Sven Tennie at 2022-08-21T16:56:29+00:00 Debug issue with GC / implement BIG_RET - - - - - b758a28e by Sven Tennie at 2022-10-03T09:25:00+00:00 Decode with correct stack bottom - - - - - 19 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - + .gitlab/upload_ghc_libs.py - compile_flags.txt - compiler/.hlint.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps/Ids.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types.hs-boot - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/bytearray-ops.txt.pp - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - + compiler/GHC/Cmm/Dominators.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81b5b1823fe911fdbe3f0cdc69f5fa63c5f3088a...b758a28e10f65f56fbe89a81380657f14e4cb551 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81b5b1823fe911fdbe3f0cdc69f5fa63c5f3088a...b758a28e10f65f56fbe89a81380657f14e4cb551 You're receiving 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 Oct 3 12:19:57 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 08:19:57 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Minor cleanup Message-ID: <633ad36d54465_2c97575148c15353d@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 221a33c3 by Sylvain Henry at 2022-10-03T14:11:34+02:00 Minor cleanup - - - - - 592b13c1 by Sylvain Henry at 2022-10-03T14:11:57+02:00 Add log1p and expm1 (fix cgrun078) - - - - - cc972678 by Sylvain Henry at 2022-10-03T14:16:45+02:00 Assume existence of Math.fround and use it in Float's primops - - - - - 4 changed files: - compiler/GHC/JS/Make.hs - compiler/GHC/StgToJS/FFI.hs - compiler/GHC/StgToJS/Prim.hs - rts/js/arith.js Changes: ===================================== compiler/GHC/JS/Make.hs ===================================== @@ -122,7 +122,8 @@ module GHC.JS.Make -- ** Math functions -- $math , math_log, math_sin, math_cos, math_tan, math_exp, math_acos, math_asin, - math_atan, math_abs, math_pow, math_sqrt, math_asinh, math_acosh, math_atanh + math_atan, math_abs, math_pow, math_sqrt, math_asinh, math_acosh, math_atanh, + math_cosh, math_sinh, math_tanh, math_expm1, math_log1p, math_fround -- * Statement helpers , decl -- * Miscellaneous @@ -592,7 +593,8 @@ math_ :: FastString -> [JExpr] -> JExpr math_ op args = ApplExpr (math .^ op) args math_log, math_sin, math_cos, math_tan, math_exp, math_acos, math_asin, math_atan, - math_abs, math_pow, math_sqrt, math_asinh, math_acosh, math_atanh, math_sign + math_abs, math_pow, math_sqrt, math_asinh, math_acosh, math_atanh, math_sign, + math_sinh, math_cosh, math_tanh, math_expm1, math_log1p, math_fround :: [JExpr] -> JExpr math_log = math_ "log" math_sin = math_ "sin" @@ -609,6 +611,12 @@ math_sqrt = math_ "sqrt" math_asinh = math_ "asinh" math_acosh = math_ "acosh" math_atanh = math_ "atanh" +math_sinh = math_ "sinh" +math_cosh = math_ "cosh" +math_tanh = math_ "tanh" +math_expm1 = math_ "expm1" +math_log1p = math_ "log1p" +math_fround = math_ "fround" instance Num JExpr where x + y = InfixExpr AddOp x y ===================================== compiler/GHC/StgToJS/FFI.hs ===================================== @@ -194,7 +194,7 @@ parseFFIPattern' callback javascriptCc pat t ret args where (TxtI i') = i err = pprPanic "parseFFIPattern': invalid placeholder, check function type" - (vcat [text pat, text (unpackFS i'), ppr args, ppr t]) + (vcat [text pat, ppr i', ppr args, ppr t]) traceCall cs as | csTraceForeign cs = ApplStat (var "h$traceForeign") [toJExpr pat, toJExpr as] | otherwise = mempty ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -468,11 +468,11 @@ genPrim prof ty op = case op of DoubleNegOp -> \[r] [x] -> PrimInline $ r |= Negate x DoubleFabsOp -> \[r] [x] -> PrimInline $ r |= math_abs [x] DoubleToIntOp -> \[r] [x] -> PrimInline $ r |= i32 x - DoubleToFloatOp -> \[r] [x] -> PrimInline $ r |= app "h$fround" [x] + DoubleToFloatOp -> \[r] [x] -> PrimInline $ r |= math_fround [x] DoubleExpOp -> \[r] [x] -> PrimInline $ r |= math_exp [x] - DoubleExpM1Op -> \[r] [x] -> PrimInline $ r |= math_exp [x] + DoubleExpM1Op -> \[r] [x] -> PrimInline $ r |= math_expm1 [x] DoubleLogOp -> \[r] [x] -> PrimInline $ r |= math_log [x] - DoubleLog1POp -> \[r] [x] -> PrimInline $ r |= math_log [x] + DoubleLog1POp -> \[r] [x] -> PrimInline $ r |= math_log1p [x] DoubleSqrtOp -> \[r] [x] -> PrimInline $ r |= math_sqrt [x] DoubleSinOp -> \[r] [x] -> PrimInline $ r |= math_sin [x] DoubleCosOp -> \[r] [x] -> PrimInline $ r |= math_cos [x] @@ -480,9 +480,9 @@ genPrim prof ty op = case op of DoubleAsinOp -> \[r] [x] -> PrimInline $ r |= math_asin [x] DoubleAcosOp -> \[r] [x] -> PrimInline $ r |= math_acos [x] DoubleAtanOp -> \[r] [x] -> PrimInline $ r |= math_atan [x] - DoubleSinhOp -> \[r] [x] -> PrimInline $ r |= (math_exp [x] `Sub` math_exp [Negate x]) `Div` two_ - DoubleCoshOp -> \[r] [x] -> PrimInline $ r |= (math_exp [x] `Add` math_exp [Negate x]) `Div` two_ - DoubleTanhOp -> \[r] [x] -> PrimInline $ r |= (math_exp [Mul two_ x] `Sub` one_) `Div` (math_exp [Mul two_ x] `Add` one_) + DoubleSinhOp -> \[r] [x] -> PrimInline $ r |= math_sinh [x] + DoubleCoshOp -> \[r] [x] -> PrimInline $ r |= math_cosh [x] + DoubleTanhOp -> \[r] [x] -> PrimInline $ r |= math_tanh [x] DoubleAsinhOp -> \[r] [x] -> PrimInline $ r |= math_asinh [x] DoubleAcoshOp -> \[r] [x] -> PrimInline $ r |= math_acosh [x] DoubleAtanhOp -> \[r] [x] -> PrimInline $ r |= math_atanh [x] @@ -498,31 +498,31 @@ genPrim prof ty op = case op of FloatNeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .!==. y) FloatLtOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .<. y) FloatLeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .<=. y) - FloatAddOp -> \[r] [x,y] -> PrimInline $ r |= Add x y - FloatSubOp -> \[r] [x,y] -> PrimInline $ r |= Sub x y - FloatMulOp -> \[r] [x,y] -> PrimInline $ r |= Mul x y - FloatDivOp -> \[r] [x,y] -> PrimInline $ r |= Div x y + FloatAddOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [Add x y] + FloatSubOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [Sub x y] + FloatMulOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [Mul x y] + FloatDivOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [Div x y] FloatNegOp -> \[r] [x] -> PrimInline $ r |= Negate x FloatFabsOp -> \[r] [x] -> PrimInline $ r |= math_abs [x] FloatToIntOp -> \[r] [x] -> PrimInline $ r |= i32 x - FloatExpOp -> \[r] [x] -> PrimInline $ r |= math_exp [x] - FloatExpM1Op -> \[r] [x] -> PrimInline $ r |= math_exp [x] - FloatLogOp -> \[r] [x] -> PrimInline $ r |= math_log [x] - FloatLog1POp -> \[r] [x] -> PrimInline $ r |= math_log [x] - FloatSqrtOp -> \[r] [x] -> PrimInline $ r |= math_sqrt [x] - FloatSinOp -> \[r] [x] -> PrimInline $ r |= math_sin [x] - FloatCosOp -> \[r] [x] -> PrimInline $ r |= math_cos [x] - FloatTanOp -> \[r] [x] -> PrimInline $ r |= math_tan [x] - FloatAsinOp -> \[r] [x] -> PrimInline $ r |= math_asin [x] - FloatAcosOp -> \[r] [x] -> PrimInline $ r |= math_acos [x] - FloatAtanOp -> \[r] [x] -> PrimInline $ r |= math_atan [x] - FloatSinhOp -> \[r] [x] -> PrimInline $ r |= (math_exp [x] `Sub` math_exp [Negate x]) `Div` two_ - FloatCoshOp -> \[r] [x] -> PrimInline $ r |= (math_exp [x] `Add` math_exp [Negate x]) `Div` two_ - FloatTanhOp -> \[r] [x] -> PrimInline $ r |= (math_exp [Mul two_ x] `Sub` one_) `Div` (math_exp [Mul two_ x] `Add` one_) - FloatAsinhOp -> \[r] [x] -> PrimInline $ r |= math_asinh [x] - FloatAcoshOp -> \[r] [x] -> PrimInline $ r |= math_acosh [x] - FloatAtanhOp -> \[r] [x] -> PrimInline $ r |= math_atanh [x] - FloatPowerOp -> \[r] [x,y] -> PrimInline $ r |= math_pow [x,y] + FloatExpOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_exp [x]] + FloatExpM1Op -> \[r] [x] -> PrimInline $ r |= math_fround [math_expm1 [x]] + FloatLogOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_log [x]] + FloatLog1POp -> \[r] [x] -> PrimInline $ r |= math_fround [math_log1p [x]] + FloatSqrtOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_sqrt [x]] + FloatSinOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_sin [x]] + FloatCosOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_cos [x]] + FloatTanOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_tan [x]] + FloatAsinOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_asin [x]] + FloatAcosOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_acos [x]] + FloatAtanOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_atan [x]] + FloatSinhOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_sinh [x]] + FloatCoshOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_cosh [x]] + FloatTanhOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_tanh [x]] + FloatAsinhOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_asinh [x]] + FloatAcoshOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_acosh [x]] + FloatAtanhOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_atanh [x]] + FloatPowerOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [math_pow [x,y]] FloatToDoubleOp -> \[r] [x] -> PrimInline $ r |= x FloatDecode_IntOp -> \[s,e] [x] -> PrimInline $ appT [s,e] "h$decodeFloatInt" [x] ===================================== rts/js/arith.js ===================================== @@ -528,20 +528,6 @@ function h$ctz64(x1,x2) { return (x2 === 0) ? 32 + h$ctz32(x1) : h$ctz32(x2); } -var h$fround = null; -if(typeof Math.fround === 'function') { - h$fround = function(f) { - TRACE_ARITH("fround (native): " + f); - return Math.fround(f); - } -} else { - h$fround = function(f) { - TRACE_ARITH("fround (buffer): " + f); - h$convertFloat[0] = f; - return h$convertFloat[0]; - } -} - function h$decodeDoubleInt64(d) { TRACE_ARITH("decodeDoubleInt64: " + d); if(isNaN(d)) { @@ -592,12 +578,12 @@ function h$__word_encodeDouble(j,e) { function h$__int_encodeFloat(j,e) { if (!j) return 0; - return h$fround((j|0) * (2 ** (e|0))); + return Math.fround((j|0) * (2 ** (e|0))); } function h$__word_encodeFloat(j,e) { if (!j) return 0; - return h$fround((j>>>0) * (2 ** (e|0))); + return Math.fround((j>>>0) * (2 ** (e|0))); } function h$stg_word32ToFloatzh(v) { @@ -622,3 +608,19 @@ function h$stg_doubleToWord64zh(v) { var h = h$convertWord[1]; RETURN_UBX_TUP2(h,l); } + +function h$log1p(x) { + return Math.log1p(x); +} + +function h$log1pf(x) { + return Math.fround(Math.log1p(x)); +} + +function h$expm1(x) { + return Math.expm1(x); +} + +function h$expm1f(x) { + return Math.fround(Math.expm1(x)); +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/109e40c9c08822cbbb4eba3b52f448cd8a050895...cc9726781384cff4f46fd8b5a08529485ce40a7d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/109e40c9c08822cbbb4eba3b52f448cd8a050895...cc9726781384cff4f46fd8b5a08529485ce40a7d You're receiving 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 Oct 3 13:19:22 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 09:19:22 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Disable "debug" test Message-ID: <633ae15a80d8f_2c975742bcfe2015458ca@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: e97eb26c by Sylvain Henry at 2022-10-03T15:21:48+02:00 Disable "debug" test - - - - - 7f8457af by Sylvain Henry at 2022-10-03T15:21:58+02:00 Implement copyMutableArray with overlap support - - - - - dca7ebbd by Sylvain Henry at 2022-10-03T15:22:28+02:00 Skip CmmSwitchTests - - - - - 4 changed files: - compiler/GHC/StgToJS/Prim.hs - rts/js/mem.js - testsuite/tests/codeGen/should_compile/all.T - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -541,7 +541,7 @@ genPrim prof ty op = case op of [ ma .! (Add i o2) |= a .! (Add i o1) , preIncrS i ] - CopyMutableArrayOp -> \[] [a1,o1,a2,o2,n] -> genPrim prof ty CopyArrayOp [] [a1,o1,a2,o2,n] + CopyMutableArrayOp -> \[] [a1,o1,a2,o2,n] -> PrimInline $ appS "h$copyMutableArray" [a1,o1,a2,o2,n] CloneArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] CloneMutableArrayOp -> \[r] [a,start,n] -> genPrim prof ty CloneArrayOp [r] [a,start,n] FreezeArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] ===================================== rts/js/mem.js ===================================== @@ -533,6 +533,21 @@ function h$sliceArray(a, start, n) { return r; } +// copy between two mutable arrays. Range may overlap +function h$copyMutableArray(a1,o1,a2,o2,n) { + if (n <= 0) return; + + if (o1 < o2) { + for (var i=n-1;i>=0;i--) { // start from the end to handle potential overlap + a2[o2+i] = a1[o1+i]; + } + } else { + for (var i=0;i ByteArray# copy var dst = arguments[0]; ===================================== testsuite/tests/codeGen/should_compile/all.T ===================================== @@ -27,7 +27,12 @@ test('T9155', normal, compile, ['-O2']) test('T9303', normal, compile, ['-O2']) test('T9329', [when(unregisterised(), expect_broken(15467)), cmm_src], compile, ['-no-hs-main']) -test('debug', normal, makefile_test, []) +test('debug', + [ normal, + js_skip # requires Cmm + ], + makefile_test, []) + test('T9964', normal, compile, ['-O']) test('T10518', [cmm_src], compile, ['-no-hs-main']) test('T10667', normal, compile, ['-g']) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -148,8 +148,8 @@ test('T9013', omit_ways(['ghci']), # ghci doesn't support unboxed tuples compile_and_run, ['']) test('T9340', normal, compile_and_run, ['']) test('cgrun074', normal, compile_and_run, ['']) -test('CmmSwitchTest32', unless(wordsize(32), skip), compile_and_run, ['']) -test('CmmSwitchTest64', unless(wordsize(64), skip), compile_and_run, ['']) +test('CmmSwitchTest32', [unless(wordsize(32), skip),js_skip], compile_and_run, ['']) +test('CmmSwitchTest64', [unless(wordsize(64), skip),js_skip], compile_and_run, ['']) # Skipping WAY=ghci, because it is not broken. test('T10245', normal, compile_and_run, ['']) test('T10246', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc9726781384cff4f46fd8b5a08529485ce40a7d...dca7ebbdcde465fe7458c4e14b7b77effbd81d51 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc9726781384cff4f46fd8b5a08529485ce40a7d...dca7ebbdcde465fe7458c4e14b7b77effbd81d51 You're receiving 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 Oct 3 13:30:04 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Mon, 03 Oct 2022 09:30:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fragile-T7919 Message-ID: <633ae3dc57f81_2c975742cc31601546048@gitlab.mail> Bryan R pushed new branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fragile-T7919 You're receiving 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 Oct 3 14:10:14 2022 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 03 Oct 2022 10:10:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22218 Message-ID: <633aed469a2be_2c97572ed3bc781557553@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T22218 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22218 You're receiving 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 Oct 3 14:36:44 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 10:36:44 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Fix WordToDouble/WordToFloat (Word2Float32 test) Message-ID: <633af37c2f3c9_2c975742bcfe5c15615e4@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: cb049beb by Sylvain Henry at 2022-10-03T15:33:28+02:00 Fix WordToDouble/WordToFloat (Word2Float32 test) - - - - - 4b51c3c2 by Sylvain Henry at 2022-10-03T16:39:42+02:00 Skip one more test - - - - - 44181250 by Sylvain Henry at 2022-10-03T16:39:52+02:00 Fix after GHC.Tuple to GHC.Tuple.Prim - - - - - 5 changed files: - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Prim.hs - rts/include/js/rts.h - testsuite/tests/concurrent/should_run/all.T Changes: ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -729,7 +729,7 @@ rtsDeps pkgs = diffDeps pkgs $ [ ":" , "[]" ] - , mkPrimFuns "GHC.Tuple" + , mkPrimFuns "GHC.Tuple.Prim" [ "(,)" , "(,,)" , "(,,,)" ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -96,26 +96,26 @@ genCommonCppDefs profiling = mconcat -- low-level heap object manipulation macros , if profiling then mconcat - [ "#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" - , "#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + [ "#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" + , "#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))\n" ] else mconcat - [ "#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziZLz2cUZR_con_e,(x1),(x2)))\n" - , "#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziZLz2cUz2cUZR_con_e,(x1),(x2),(x3)))\n" - , "#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4)))\n" - , "#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5)))\n" - , "#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6)))\n" - , "#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7)))\n" - , "#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8)))\n" - , "#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9)))\n" - , "#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10)))\n" + [ "#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2)))\n" + , "#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3)))\n" + , "#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4)))\n" + , "#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5)))\n" + , "#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6)))\n" + , "#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7)))\n" + , "#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8)))\n" + , "#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9)))\n" + , "#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10)))\n" ] , "#define TUP2_1(x) ((x).d1)\n" ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -394,8 +394,8 @@ genPrim prof ty op = case op of WordNeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .!==. y) WordLtOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .<. y) WordLeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .<=. y) - WordToDoubleOp -> \[r] [x] -> PrimInline $ r |= (Add (BAnd x (Int 0x7FFFFFFF)) (x .>>>. (Int 31))) `Mul` Int 2147483648 - WordToFloatOp -> \[r] [x] -> PrimInline $ r |= (Add (BAnd x (Int 0x7FFFFFFF)) (x .>>>. (Int 31))) `Mul` Int 2147483648 + WordToDoubleOp -> \[r] [x] -> PrimInline $ r |= x + WordToFloatOp -> \[r] [x] -> PrimInline $ r |= math_fround [x] PopCnt8Op -> \[r] [x] -> PrimInline $ r |= var "h$popCntTab" .! (mask8 x) PopCnt16Op -> \[r] [x] -> PrimInline $ r |= Add (var "h$popCntTab" .! (mask8 x)) (var "h$popCntTab" .! (mask8 (x .>>>. Int 8))) ===================================== rts/include/js/rts.h ===================================== @@ -8,25 +8,25 @@ */ #ifdef GHCJS_PROF -#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) +#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) #else -#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziZLz2cUZR_con_e,(x1),(x2))) -#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziZLz2cUz2cUZR_con_e,(x1),(x2),(x3))) -#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4))) -#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5))) -#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6))) -#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7))) -#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8))) -#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9))) -#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10))) +#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2))) +#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3))) +#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4))) +#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5))) +#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6))) +#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7))) +#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8))) +#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9))) +#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10))) #endif #define TUP2_1(x) ((x).d1) ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -128,7 +128,11 @@ test('conc017a', normal, compile_and_run, ['']) test('conc018', normal, compile_and_run, ['']) test('conc019', extra_run_opts('+RTS -K16m -RTS'), compile_and_run, ['']) test('conc020', normal, compile_and_run, ['']) -test('conc021', [ omit_ways(['ghci']), exit_code(1) ], compile_and_run, ['']) +test('conc021', + [ omit_ways(['ghci']), exit_code(1) + , js_skip # foreign exports not supported yet + ], + compile_and_run, ['']) test('conc022', normal, compile_and_run, ['']) test('conc024', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dca7ebbdcde465fe7458c4e14b7b77effbd81d51...4418125058998e6607a4769c07174ca073199ac4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dca7ebbdcde465fe7458c4e14b7b77effbd81d51...4418125058998e6607a4769c07174ca073199ac4 You're receiving 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 Oct 3 15:07:36 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 11:07:36 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Fix InterlockedExchange primops (cgrun080) Message-ID: <633afab83a9f9_2c97575141415617fa@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 8913653a by Sylvain Henry at 2022-10-03T17:10:46+02:00 Fix InterlockedExchange primops (cgrun080) - - - - - 1 changed file: - compiler/GHC/StgToJS/Prim.hs Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1200,14 +1200,28 @@ genPrim prof ty op = case op of FetchOrAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr BOr r a o v FetchXorAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr BXor r a o v - InterlockedExchange_Addr -> \[r_a,r_o] [a1,o1,a2,o2] -> PrimInline $ - mconcat [ r_a |= a1 - , r_o |= o1 - , a1 .! o1 |= a2 .! o2 - , o1 |= o2 - ] + InterlockedExchange_Addr -> \[r_a,r_o] [a1,o1,_a2,o2] -> PrimInline $ + -- this primop can't be implemented + -- correctly because we don't store + -- the array reference part of an Addr#, + -- only the offset part. + -- + -- So let's assume that all the array + -- references are the same... + -- + -- Note: we could generate an assert + -- that checks that a1 === a2. However + -- we can't check that the Addr# read + -- at Addr# a2[o2] also comes from this + -- a1/a2 array. + mconcat [ r_a |= a1 -- might be wrong (see above) + , r_o |= dv_u32 a1 o1 + -- TODO (see above) + -- assert that a1 === a2 + , dv_s_u32 a1 o1 o2 + ] InterlockedExchange_Word -> \[r] [a,o,w] -> PrimInline $ - mconcat [ r |= a .! o + mconcat [ r |= dv_u32 a o , dv_s_u32 a o w ] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8913653ab076b3e1f24dca2e6d276f1d14a2b6f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8913653ab076b3e1f24dca2e6d276f1d14a2b6f5 You're receiving 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 Oct 3 15:18:00 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 11:18:00 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable T12059 Message-ID: <633afd2865ab7_2c975742bcfe2015636be@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 49f30321 by Sylvain Henry at 2022-10-03T17:21:19+02:00 Disable T12059 - - - - - 1 changed file: - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -163,7 +163,10 @@ test('T10521b', normal, compile_and_run, ['']) test('T10870', when(wordsize(32), skip), compile_and_run, ['']) test('PopCnt', [omit_ways(['ghci']), js_skip], multi_compile_and_run, ['PopCnt', [('PopCnt_cmm.cmm', '')], '']) -test('T12059', normal, compile_and_run, ['']) +test('T12059', + [ js_skip # ByteArrays are always pinned with the JS backend + ], + compile_and_run, ['']) test('T12433', normal, compile_and_run, ['']) test('T12622', normal, multimod_compile_and_run, ['T12622', '-O']) test('T12757', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49f3032193f144cd1ab20a5e1d2c47a1b44733bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49f3032193f144cd1ab20a5e1d2c47a1b44733bc You're receiving 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 Oct 3 15:47:36 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 11:47:36 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Implement sqrt/sqrtf (fix T14619) Message-ID: <633b041875f55_2c975751414156636f@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c521d947 by Sylvain Henry at 2022-10-03T17:50:47+02:00 Implement sqrt/sqrtf (fix T14619) - - - - - 1 changed file: - rts/js/arith.js Changes: ===================================== rts/js/arith.js ===================================== @@ -609,6 +609,14 @@ function h$stg_doubleToWord64zh(v) { RETURN_UBX_TUP2(h,l); } +function h$sqrt(x) { + return Math.sqrt(x); +} + +function h$sqrtf(x) { + return Math.fround(Math.sqrt(x)); +} + function h$log1p(x) { return Math.log1p(x); } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c521d9478d02fc2a07b073560339c0cfe16fb9be -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c521d9478d02fc2a07b073560339c0cfe16fb9be You're receiving 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 Oct 3 15:57:03 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 11:57:03 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: Skip more tests Message-ID: <633b064fb0481_2c9757514141566574@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: d2214f04 by Sylvain Henry at 2022-10-03T17:51:29+02:00 Skip more tests - - - - - d488a1fc by Sylvain Henry at 2022-10-03T18:00:23+02:00 Disable conc012 - - - - - 2 changed files: - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/concurrent/should_run/all.T Changes: ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -161,7 +161,10 @@ test('T10414', [only_ways(['threaded2']), extra_ways(['threaded2']), req_smp], test('T10521', normal, compile_and_run, ['']) test('T10521b', normal, compile_and_run, ['']) test('T10870', when(wordsize(32), skip), compile_and_run, ['']) -test('PopCnt', [omit_ways(['ghci']), js_skip], multi_compile_and_run, +test('PopCnt', + [omit_ways(['ghci']) + , js_skip # use Cmm + ], multi_compile_and_run, ['PopCnt', [('PopCnt_cmm.cmm', '')], '']) test('T12059', [ js_skip # ByteArrays are always pinned with the JS backend ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -114,7 +114,9 @@ test('conc010', normal, compile_and_run, ['']) # conc012(ghci) needs a smaller stack, or it takes forever test('conc012', - extra_run_opts('+RTS -K8m -RTS'), + [ extra_run_opts('+RTS -K8m -RTS') + , js_skip # no stack overflow detection with the JS backend (yet) + ], compile_and_run, ['']) test('conc013', normal, compile_and_run, ['']) @@ -185,13 +187,13 @@ test('foreignInterruptible', [when(fast(), skip), test('conc037', only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), compile_and_run, ['']) test('conc038', only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), compile_and_run, ['']) -# Omit for GHCi, uses foreign export +# Omit for GHCi and for the JS backend, uses foreign export # Omit for the threaded ways, because in this case the main thread is allowed to # complete, which causes the child thread to be interrupted. -test('conc039', omit_ways(['ghci'] + threaded_ways), compile_and_run, ['']) +test('conc039', [omit_ways(['ghci'] + threaded_ways), js_skip], compile_and_run, ['']) -# Omit for GHCi, uses foreign export -test('conc040', [exit_code(1), omit_ways(['ghci'])], compile_and_run, ['']) +# Omit for GHCi and for the JS backend, uses foreign export +test('conc040', [exit_code(1), omit_ways(['ghci']), js_skip], compile_and_run, ['']) # STM-related tests. test('conc041', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c521d9478d02fc2a07b073560339c0cfe16fb9be...d488a1fc6e469e754df4d21818a82bd511adc97b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c521d9478d02fc2a07b073560339c0cfe16fb9be...d488a1fc6e469e754df4d21818a82bd511adc97b You're receiving 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 Oct 3 16:04:30 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 03 Oct 2022 12:04:30 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable more Cmm tests Message-ID: <633b080ef95e_2c97575148c156676a@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: ceabd761 by Sylvain Henry at 2022-10-03T18:07:46+02:00 Disable more Cmm tests - - - - - 2 changed files: - testsuite/tests/cmm/should_compile/T21370/all.T - testsuite/tests/cmm/should_compile/all.T Changes: ===================================== testsuite/tests/cmm/should_compile/T21370/all.T ===================================== @@ -1 +1,4 @@ -test('T21370', [extra_files(["subdir", "test.cmm", "test2.cmm", "Main.hs"])] , makefile_test, []) +test('T21370', + [ extra_files(["subdir", "test.cmm", "test2.cmm", "Main.hs"]) + , js_skip # use Cmm + ], makefile_test, []) ===================================== testsuite/tests/cmm/should_compile/all.T ===================================== @@ -1,4 +1,7 @@ -# +setTestOpts( + [ js_skip # Cmm not supported by the JS backend + ]) + test('selfloop', [cmm_src], compile, ['-no-hs-main']) test('cmm_sink_sp', [ only_ways(['optasm']), grep_errmsg('(\[Sp.*\]).*(=).*(\[.*R1.*\]).*;',[1,2,3]), cmm_src], compile, ['-no-hs-main -ddump-cmm -dsuppress-uniques -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ceabd7616a62d757d9f1bb58d71e55de39e4b166 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ceabd7616a62d757d9f1bb58d71e55de39e4b166 You're receiving 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 Oct 3 17:56:40 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 03 Oct 2022 13:56:40 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Hacked further Message-ID: <633b225830e_2c975742bcfe7015671bf@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 1e2de6a7 by Sven Tennie at 2022-10-03T17:56:07+00:00 Hacked further - - - - - 2 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -34,7 +34,12 @@ import GHC.Exts.Heap.StackFFI (bitsInWord) import GHC.Exts.Heap.Closures (closureSize) import System.Mem (performMajorGC) -type StackFrameIter# = (# StackSnapshot#, Word# #) +type StackFrameIter# = (# + -- | StgStack + StackSnapshot#, + -- | offset in machine words + Word# + #) data StackFrameIter = StackFrameIter StackFrameIter# @@ -52,11 +57,27 @@ advanceStackFrameIter (StackFrameIter (# s, i #)) = let (# s', i', hasNext #) = foreign import prim "getInfoTableTypezh" getInfoTableType# :: StackSnapshot# -> Word# -> Word# +foreign import prim "getSmallBitmapzh" getSmallBitmap# :: StackSnapshot# -> Word# -> (# Word#, Word# #) + +data BitmapEntry = BitmapEntry { + closureFrame :: StackFrameIter, + isPrimitive :: Bool + } deriving (Show) + +toBitmapEntries :: StackFrameIter -> Word -> Word -> [BitmapEntry] +toBitmapEntries _ _ 0 = [] +toBitmapEntries sfi@(StackFrameIter(# s, i #) bitmap size = BitmapEntry { + closureFrame = sfi, + isPrimitive = (bitmap .&. 1) == 0 + } : toBitmapEntries (StackFrameIter (# s , i + 1 #)) (bitmap `shiftR` 1) (size - 1) + unpackStackFrameIter :: StackFrameIter -> StackFrame unpackStackFrameIter (StackFrameIter (# s, i #)) = case (toEnum . fromIntegral) (W# (getInfoTableType# s i)) of RET_BCO -> RetBCO - RET_SMALL -> RetSmall None [] + RET_SMALL -> let (# bitmap#, size# #) = getSmallBitmap# s i + in + RetSmall None [] RET_BIG -> RetBig [] RET_FUN -> RetFun UPDATE_FRAME -> UpdateFrame ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -48,7 +48,7 @@ advanceStackFrameIterzh (P_ stack, W_ index) { } } - ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul\n", stack, newStack, frameSize, newIndex, hasNext); + ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul, stackBottom %p\n", stack, newStack, frameSize, newIndex, hasNext, stackBottom); return (newStack, newIndex, hasNext); } @@ -56,7 +56,7 @@ derefStackWordzh (P_ stack, W_ index) { P_ sp; sp = StgStack_sp(stack); - return (W_[sp + index]); + return (W_[sp + WDS(index)]); } getInfoTableTypezh (P_ stack, W_ index) { @@ -69,3 +69,21 @@ getInfoTableTypezh (P_ stack, W_ index) { ccall debugBelch("getInfoTableTypezh - stack %p , index %ul, closure ptr p %p, info ptr %p, itbl type %ul\n", stack, index, p, info, type); return (type); } + +getSmallBitmapzh(P_ stack, W_ index) { + P_ itbl; + itbl = %INFO_PTR(StgStack_sp(stack) + WDS(index)); + + W_ bitmap, size; + (bitmap) = ccall getBitmapWord(itbl); + (size) = ccall getBitmapSize(itbl); + + ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul", bitmap, size); + return (bitmap, size); +} + +unpackClosureFromStackFramezh(P_ stack, W_ index){ + P_ closurePtr; + closurePtr = (StgStack_sp(stack) + WDS(index)); + return (stg_unpackClosurezh(closurePtr)); +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2de6a72d4c5bf12b213239877619d252499837 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e2de6a72d4c5bf12b213239877619d252499837 You're receiving 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 Oct 3 20:51:50 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Oct 2022 16:51:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fix a bug in continuation capture across multiple stack chunks Message-ID: <633b4b66b523c_2c975742bcfe20159195d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - cceea0f1 by Brandon Chinn at 2022-10-02T11:13:38-07:00 Fix docs for pattern synonyms - - - - - acfd1986 by Oleg Grenrus at 2022-10-03T16:51:31-04:00 Use sameByteArray# in sameByteArray - - - - - 6 changed files: - compiler/GHC/Data/OrdList.hs - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - rts/Continuation.c - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs Changes: ===================================== compiler/GHC/Data/OrdList.hs ===================================== @@ -28,6 +28,8 @@ import GHC.Utils.Misc (strictMap) import GHC.Utils.Outputable import GHC.Utils.Panic +import Data.List.NonEmpty (NonEmpty(..)) +import qualified Data.List.NonEmpty as NE import qualified Data.Semigroup as Semigroup infixl 5 `appOL` @@ -37,7 +39,7 @@ infixr 5 `consOL` data OrdList a = None | One a - | Many [a] -- Invariant: non-empty + | Many (NonEmpty a) | Cons a (OrdList a) | Snoc (OrdList a) a | Two (OrdList a) -- Invariant: non-empty @@ -100,8 +102,12 @@ pattern ConsOL :: a -> OrdList a -> OrdList a pattern ConsOL x xs <- (viewCons -> VJust x xs) where ConsOL x xs = consOL x xs {-# COMPLETE NilOL, ConsOL #-} + viewCons :: OrdList a -> VMaybe a (OrdList a) -viewCons (One a) = VJust a NilOL +viewCons None = VNothing +viewCons (One a) = VJust a NilOL +viewCons (Many (a :| [])) = VJust a NilOL +viewCons (Many (a :| b : bs)) = VJust a (Many (b :| bs)) viewCons (Cons a as) = VJust a as viewCons (Snoc as a) = case viewCons as of VJust a' as' -> VJust a' (Snoc as' a) @@ -109,15 +115,18 @@ viewCons (Snoc as a) = case viewCons as of viewCons (Two as1 as2) = case viewCons as1 of VJust a' as1' -> VJust a' (Two as1' as2) VNothing -> viewCons as2 -viewCons _ = VNothing pattern SnocOL :: OrdList a -> a -> OrdList a pattern SnocOL xs x <- (viewSnoc -> VJust xs x) where SnocOL xs x = snocOL xs x {-# COMPLETE NilOL, SnocOL #-} + viewSnoc :: OrdList a -> VMaybe (OrdList a) a -viewSnoc (One a) = VJust NilOL a -viewSnoc (Many (reverse -> a:as)) = VJust (Many (reverse as)) a +viewSnoc None = VNothing +viewSnoc (One a) = VJust NilOL a +viewSnoc (Many as) = (`VJust` NE.last as) $ case NE.init as of + [] -> NilOL + b : bs -> Many (b :| bs) viewSnoc (Snoc as a) = VJust as a viewSnoc (Cons a as) = case viewSnoc as of VJust as' a' -> VJust (Cons a as') a' @@ -125,18 +134,17 @@ viewSnoc (Cons a as) = case viewSnoc as of viewSnoc (Two as1 as2) = case viewSnoc as2 of VJust as2' a' -> VJust (Two as1 as2') a' VNothing -> viewSnoc as1 -viewSnoc _ = VNothing headOL None = panic "headOL" headOL (One a) = a -headOL (Many as) = head as +headOL (Many as) = NE.head as headOL (Cons a _) = a headOL (Snoc as _) = headOL as headOL (Two as _) = headOL as lastOL None = panic "lastOL" lastOL (One a) = a -lastOL (Many as) = last as +lastOL (Many as) = NE.last as lastOL (Cons _ as) = lastOL as lastOL (Snoc _ a) = a lastOL (Two _ as) = lastOL as @@ -164,7 +172,7 @@ fromOL a = go a [] go (Cons a b) acc = a : go b acc go (Snoc a b) acc = go a (b:acc) go (Two a b) acc = go a (go b acc) - go (Many xs) acc = xs ++ acc + go (Many xs) acc = NE.toList xs ++ acc fromOLReverse :: OrdList a -> [a] fromOLReverse a = go a [] @@ -175,7 +183,7 @@ fromOLReverse a = go a [] go (Cons a b) acc = go b (a : acc) go (Snoc a b) acc = b : go a acc go (Two a b) acc = go b (go a acc) - go (Many xs) acc = reverse xs ++ acc + go (Many xs) acc = reverse (NE.toList xs) ++ acc mapOL :: (a -> b) -> OrdList a -> OrdList b mapOL = fmap @@ -192,7 +200,9 @@ mapOL' f (Snoc xs x) = let !x1 = f x mapOL' f (Two b1 b2) = let !b1' = mapOL' f b1 !b2' = mapOL' f b2 in Two b1' b2' -mapOL' f (Many xs) = Many $! strictMap f xs +mapOL' f (Many (x :| xs)) = let !x1 = f x + !xs1 = strictMap f xs + in Many (x1 :| xs1) foldrOL :: (a->b->b) -> b -> OrdList a -> b foldrOL _ z None = z @@ -214,7 +224,7 @@ foldlOL k z (Many xs) = foldl' k z xs toOL :: [a] -> OrdList a toOL [] = None toOL [x] = One x -toOL xs = Many xs +toOL (x : xs) = Many (x :| xs) reverseOL :: OrdList a -> OrdList a reverseOL None = None @@ -222,7 +232,7 @@ reverseOL (One x) = One x reverseOL (Cons a b) = Snoc (reverseOL b) a reverseOL (Snoc a b) = Cons b (reverseOL a) reverseOL (Two a b) = Two (reverseOL b) (reverseOL a) -reverseOL (Many xs) = Many (reverse xs) +reverseOL (Many xs) = Many (NE.reverse xs) -- | Compare not only the values but also the structure of two lists strictlyEqOL :: Eq a => OrdList a -> OrdList a -> Bool ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where ===================================== rts/Continuation.c ===================================== @@ -472,12 +472,14 @@ StgClosure *captureContinuationAndAbort(Capability *cap, StgTSO *tso, StgPromptT stack = pop_stack_chunk(cap, tso); for (StgWord i = 0; i < full_chunks; i++) { - memcpy(cont_stack, stack->sp, stack->stack_size * sizeof(StgWord)); - cont_stack += stack->stack_size; + const size_t chunk_words = stack->stack + stack->stack_size - stack->sp - sizeofW(StgUnderflowFrame); + memcpy(cont_stack, stack->sp, chunk_words * sizeof(StgWord)); + cont_stack += chunk_words; stack = pop_stack_chunk(cap, tso); } memcpy(cont_stack, stack->sp, last_chunk_words * sizeof(StgWord)); + cont_stack += last_chunk_words; stack->sp += last_chunk_words; } ===================================== testsuite/tests/rts/continuations/all.T ===================================== @@ -2,3 +2,4 @@ test('cont_simple_shift', [extra_files(['ContIO.hs'])], multimod_compile_and_run test('cont_exn_masking', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_exn_masking', '']) test('cont_missing_prompt_err', [extra_files(['ContIO.hs']), exit_code(1)], multimod_compile_and_run, ['cont_missing_prompt_err', '']) test('cont_nondet_handler', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_nondet_handler', '']) +test('cont_stack_overflow', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_stack_overflow', '-with-rtsopts "-ki1k -kc2k -kb256"']) ===================================== testsuite/tests/rts/continuations/cont_stack_overflow.hs ===================================== @@ -0,0 +1,32 @@ +-- This test is run with RTS options that instruct GHC to use a small stack +-- chunk size (2k), which ensures this test exercises multi-chunk continuation +-- captures and restores. + +import Control.Monad (unless) +import ContIO + +data Answer + = Done Int + | Yield (IO Int -> IO Answer) + +getAnswer :: Answer -> Int +getAnswer (Done n) = n +getAnswer (Yield _) = error "getAnswer" + +main :: IO () +main = do + tag <- newPromptTag + Yield k <- prompt tag $ + Done <$> buildBigCont tag 6000 + n <- getAnswer <$> k (getAnswer <$> k (pure 0)) + unless (n == 36006000) $ + error $ "produced wrong value: " ++ show n + +buildBigCont :: PromptTag Answer + -> Int + -> IO Int +buildBigCont tag size + | size <= 0 = control0 tag (\k -> pure (Yield k)) + | otherwise = do + n <- buildBigCont tag (size - 1) + pure $! n + size View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2de0bcf0672eda4fc8f701ae53bfecc8524bde48...acfd198662ef745ffa872ed38a6140b9f6a45628 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2de0bcf0672eda4fc8f701ae53bfecc8524bde48...acfd198662ef745ffa872ed38a6140b9f6a45628 You're receiving 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 Oct 4 00:11:59 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Oct 2022 20:11:59 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633b7a4f4613f_2c975742cc31601609268@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2ea44650 by Oleg Grenrus at 2022-10-03T20:11:44-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ea446500de94a2ba40e8d58a810341dfbb40f78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ea446500de94a2ba40e8d58a810341dfbb40f78 You're receiving 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 Oct 4 03:32:12 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Oct 2022 23:32:12 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633ba93c83a08_2c975751400162636f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 99355af5 by Oleg Grenrus at 2022-10-03T23:31:57-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99355af523d7522434060336b1d797ae65582066 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99355af523d7522434060336b1d797ae65582066 You're receiving 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 Oct 4 06:42:30 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 02:42:30 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633bd5d6c8225_2c975742bcfe701646384@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f6623abf by Oleg Grenrus at 2022-10-04T02:42:13-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6623abfabee6cd57eaf70667b4a1823bc3b40ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6623abfabee6cd57eaf70667b4a1823bc3b40ea You're receiving 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 Oct 4 10:02:44 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 06:02:44 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633c04c4a20f7_2c97572ed3bc781684336@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7b54bce2 by Oleg Grenrus at 2022-10-04T06:02:27-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b54bce29765886c98eda95dc9a6915aead956c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b54bce29765886c98eda95dc9a6915aead956c3 You're receiving 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 Oct 4 11:19:24 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Tue, 04 Oct 2022 07:19:24 -0400 Subject: [Git][ghc/ghc][wip/fragile-T7919] Mark T7919 as fragile Message-ID: <633c16bc7e818_2c975742bcfe701702937@gitlab.mail> Bryan R pushed to branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC Commits: 336554c6 by Bryan Richter at 2022-10-04T14:18:42+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. - - - - - 1 changed file: - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/rts/all.T ===================================== @@ -298,9 +298,13 @@ test('T7815', [ multi_cpu_race, test('ffishutdown', [ignore_stderr, only_ways(['threaded1','threaded2'])], compile_and_run, ['']) -# Times out in ghci way -test('T7919', [when(fast(), skip), omit_ways(['ghci'] + prof_ways)], compile_and_run, - [config.ghc_th_way_flags]) +# Times out in ghci way. +# Also times out on x86_64-linux from time to time. +test('T7919', [ when(fast(), skip), + , omit_ways(['ghci'] + prof_ways) + , when(platform('x86_64-unknown-linux'), fragile(7919)) + ] + , compile_and_run, [config.ghc_th_way_flags]) test('T8035', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/336554c60d35014c9e443a17e491cb6326f57800 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/336554c60d35014c9e443a17e491cb6326f57800 You're receiving 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 Oct 4 13:23:33 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 09:23:33 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633c33d585925_2c975742bcfe20172333d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d9fdb1f6 by Oleg Grenrus at 2022-10-04T09:23:17-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9fdb1f672e0860c009d57ce6b32e5a4a99e7041 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9fdb1f672e0860c009d57ce6b32e5a4a99e7041 You're receiving 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 Oct 4 14:15:17 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 04 Oct 2022 10:15:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22241 Message-ID: <633c3ff5712ff_2c9757dfd4017469ba@gitlab.mail> Sebastian Graf pushed new branch wip/T22241 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22241 You're receiving 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 Oct 4 15:29:47 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Tue, 04 Oct 2022 11:29:47 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Fix AtomicPrimops test. Some refactoring in Prim too Message-ID: <633c516b80da8_2c97572ed3bc78175847c@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 82745317 by Sylvain Henry at 2022-10-04T17:32:41+02:00 Fix AtomicPrimops test. Some refactoring in Prim too - - - - - 1 changed file: - compiler/GHC/StgToJS/Prim.hs Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -54,22 +54,22 @@ genPrim prof ty op = case op of Int16ToWord16Op -> \[r] [x] -> PrimInline $ r |= mask16 x Word16ToInt16Op -> \[r] [x] -> PrimInline $ r |= signExtend16 x Int32ToWord32Op -> \[r] [x] -> PrimInline $ r |= x .>>>. zero_ - Word32ToInt32Op -> \[r] [x] -> PrimInline $ r |= i32 x + Word32ToInt32Op -> \[r] [x] -> PrimInline $ r |= toI32 x ------------------------------ Int ---------------------------------------------- - IntAddOp -> \[r] [x,y] -> PrimInline $ r |= i32 (Add x y) - IntSubOp -> \[r] [x,y] -> PrimInline $ r |= i32 (Sub x y) + IntAddOp -> \[r] [x,y] -> PrimInline $ r |= toI32 (Add x y) + IntSubOp -> \[r] [x,y] -> PrimInline $ r |= toI32 (Sub x y) IntMulOp -> \[r] [x,y] -> PrimInline $ r |= app "h$mulInt32" [x, y] IntMul2Op -> \[c,hr,lr] [x,y] -> PrimInline $ appT [c,hr,lr] "h$hs_timesInt2" [x, y] IntMulMayOfloOp -> \[r] [x,y] -> PrimInline $ jVar \tmp -> mconcat [ tmp |= Mul x y - , r |= if01 (tmp .===. i32 tmp) + , r |= if01 (tmp .===. toI32 tmp) ] - IntQuotOp -> \[r] [x,y] -> PrimInline $ r |= i32 (Div x y) + IntQuotOp -> \[r] [x,y] -> PrimInline $ r |= toI32 (Div x y) IntRemOp -> \[r] [x,y] -> PrimInline $ r |= Mod x y IntQuotRemOp -> \[q,r] [x,y] -> PrimInline $ mconcat - [ q |= i32 (Div x y) + [ q |= toI32 (Div x y) , r |= x `Sub` (Mul y q) ] IntAndOp -> \[r] [x,y] -> PrimInline $ r |= BAnd x y @@ -77,18 +77,18 @@ genPrim prof ty op = case op of IntXorOp -> \[r] [x,y] -> PrimInline $ r |= BXor x y IntNotOp -> \[r] [x] -> PrimInline $ r |= BNot x - IntNegOp -> \[r] [x] -> PrimInline $ r |= i32 (Negate x) + IntNegOp -> \[r] [x] -> PrimInline $ r |= toI32 (Negate x) -- add with carry: overflow == 0 iff no overflow IntAddCOp -> \[r,overf] [x,y] -> PrimInline $ jVar \rt -> mconcat [ rt |= Add x y - , r |= i32 rt + , r |= toI32 rt , overf |= if10 (r .!=. rt) ] IntSubCOp -> \[r,overf] [x,y] -> PrimInline $ jVar \rt -> mconcat [ rt |= Sub x y - , r |= i32 rt + , r |= toI32 rt , overf |= if10 (r .!=. rt) ] IntGtOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .>. y) @@ -103,7 +103,7 @@ genPrim prof ty op = case op of IntToDoubleOp -> \[r] [x] -> PrimInline $ r |= x IntSllOp -> \[r] [x,y] -> PrimInline $ r |= x .<<. y IntSraOp -> \[r] [x,y] -> PrimInline $ r |= x .>>. y - IntSrlOp -> \[r] [x,y] -> PrimInline $ r |= i32 (x .>>>. y) + IntSrlOp -> \[r] [x,y] -> PrimInline $ r |= toI32 (x .>>>. y) ------------------------------ Int8 --------------------------------------------- @@ -141,7 +141,7 @@ genPrim prof ty op = case op of Word8QuotOp -> \[r] [x,y] -> PrimInline $ r |= mask8 (Div x y) Word8RemOp -> \[r] [x,y] -> PrimInline $ r |= Mod x y Word8QuotRemOp -> \[r1,r2] [x,y] -> PrimInline $ mconcat - [ r1 |= i32 (Div x y) + [ r1 |= toI32 (Div x y) , r2 |= Mod x y ] Word8EqOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .===. y) @@ -196,7 +196,7 @@ genPrim prof ty op = case op of Word16QuotOp -> \[r] [x,y] -> PrimInline $ r |= mask16 (Div x y) Word16RemOp -> \[r] [x,y] -> PrimInline $ r |= Mod x y Word16QuotRemOp -> \[r1,r2] [x,y] -> PrimInline $ mconcat - [ r1 |= i32 (Div x y) + [ r1 |= toI32 (Div x y) , r2 |= Mod x y ] Word16EqOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .===. y) @@ -267,12 +267,12 @@ genPrim prof ty op = case op of ------------------------------ Int64 -------------------------------------------- - Int64ToIntOp -> \[r] [_h,l] -> PrimInline $ r |= i32 l + Int64ToIntOp -> \[r] [_h,l] -> PrimInline $ r |= toI32 l Int64NegOp -> \[r_h,r_l] [h,l] -> PrimInline $ mconcat - [ r_l |= u32 (BNot l + 1) - , r_h |= i32 (BNot h + Not r_l) + [ r_l |= toU32 (BNot l + 1) + , r_h |= toI32 (BNot h + Not r_l) ] Int64AddOp -> \[hr,lr] [h0,l0,h1,l1] -> PrimInline $ appT [hr,lr] "h$hs_plusInt64" [h0,l0,h1,l1] @@ -287,13 +287,13 @@ genPrim prof ty op = case op of Int64ToWord64Op -> \[r1,r2] [x1,x2] -> PrimInline $ mconcat - [ r1 |= u32 x1 + [ r1 |= toU32 x1 , r2 |= x2 ] IntToInt64Op -> \[r1,r2] [x] -> PrimInline $ mconcat [ r1 |= if_ (x .<. 0) (-1) 0 -- sign-extension - , r2 |= u32 x + , r2 |= toU32 x ] Int64EqOp -> \[r] [h0,l0,h1,l1] -> PrimInline $ r |= if10 (LAnd (l0 .===. l1) (h0 .===. h1)) @@ -315,7 +315,7 @@ genPrim prof ty op = case op of Word64ToInt64Op -> \[r1,r2] [x1,x2] -> PrimInline $ mconcat - [ r1 |= i32 x1 + [ r1 |= toI32 x1 , r2 |= x2 ] @@ -331,26 +331,26 @@ genPrim prof ty op = case op of Word64OrOp -> \[hr,hl] [h0, l0, h1, l1] -> PrimInline $ mconcat - [ hr |= u32 (BOr h0 h1) - , hl |= u32 (BOr l0 l1) + [ hr |= toU32 (BOr h0 h1) + , hl |= toU32 (BOr l0 l1) ] Word64AndOp -> \[hr,hl] [h0, l0, h1, l1] -> PrimInline $ mconcat - [ hr |= u32 (BAnd h0 h1) - , hl |= u32 (BAnd l0 l1) + [ hr |= toU32 (BAnd h0 h1) + , hl |= toU32 (BAnd l0 l1) ] Word64XorOp -> \[hr,hl] [h0, l0, h1, l1] -> PrimInline $ mconcat - [ hr |= u32 (BXor h0 h1) - , hl |= u32 (BXor l0 l1) + [ hr |= toU32 (BXor h0 h1) + , hl |= toU32 (BXor l0 l1) ] Word64NotOp -> \[hr,hl] [h, l] -> PrimInline $ mconcat - [ hr |= u32 (BNot h) - , hl |= u32 (BNot l) + [ hr |= toU32 (BNot h) + , hl |= toU32 (BNot l) ] Word64AddOp -> \[hr,lr] [h0,l0,h1,l1] -> PrimInline $ appT [hr,lr] "h$hs_plusWord64" [h0,l0,h1,l1] @@ -365,29 +365,29 @@ genPrim prof ty op = case op of WordAddCOp -> \[r,c] [x,y] -> PrimInline $ jVar \t -> mconcat [ t |= x `Add` y - , r |= u32 t + , r |= toU32 t , c |= if10 (t .!==. r) ] WordSubCOp -> \[r,c] [x,y] -> PrimInline $ mconcat - [ r |= u32 (Sub x y) + [ r |= toU32 (Sub x y) , c |= if10 (y .>. x) ] WordAdd2Op -> \[h,l] [x,y] -> PrimInline $ appT [h,l] "h$wordAdd2" [x,y] - WordSubOp -> \ [r] [x,y] -> PrimInline $ r |= u32 (Sub x y) + WordSubOp -> \ [r] [x,y] -> PrimInline $ r |= toU32 (Sub x y) WordMulOp -> \ [r] [x,y] -> PrimInline $ r |= app "h$mulWord32" [x, y] WordMul2Op -> \[h,l] [x,y] -> PrimInline $ appT [h,l] "h$mul2Word32" [x,y] WordQuotOp -> \ [q] [x,y] -> PrimInline $ q |= app "h$quotWord32" [x,y] WordRemOp -> \ [r] [x,y] -> PrimInline $ r |= app "h$remWord32" [x,y] WordQuotRemOp -> \[q,r] [x,y] -> PrimInline $ appT [q,r] "h$quotRemWord32" [x,y] WordQuotRem2Op -> \[q,r] [xh,xl,y] -> PrimInline $ appT [q,r] "h$quotRem2Word32" [xh,xl,y] - WordAndOp -> \[r] [x,y] -> PrimInline $ r |= u32 (BAnd x y) - WordOrOp -> \[r] [x,y] -> PrimInline $ r |= u32 (BOr x y) - WordXorOp -> \[r] [x,y] -> PrimInline $ r |= u32 (BXor x y) - WordNotOp -> \[r] [x] -> PrimInline $ r |= u32 (BNot x) - WordSllOp -> \[r] [x,y] -> PrimInline $ r |= u32 (x .<<. y) + WordAndOp -> \[r] [x,y] -> PrimInline $ r |= toU32 (BAnd x y) + WordOrOp -> \[r] [x,y] -> PrimInline $ r |= toU32 (BOr x y) + WordXorOp -> \[r] [x,y] -> PrimInline $ r |= toU32 (BXor x y) + WordNotOp -> \[r] [x] -> PrimInline $ r |= toU32 (BNot x) + WordSllOp -> \[r] [x,y] -> PrimInline $ r |= toU32 (x .<<. y) WordSrlOp -> \[r] [x,y] -> PrimInline $ r |= x .>>>. y - WordToIntOp -> \[r] [x] -> PrimInline $ r |= i32 x + WordToIntOp -> \[r] [x] -> PrimInline $ r |= toI32 x WordGtOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .>. y) WordGeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .>=. y) WordEqOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .===. y) @@ -429,7 +429,7 @@ genPrim prof ty op = case op of r |= BOr ((mask8 x) .<<. (Int 8)) (mask8 (x .>>>. (Int 8))) BSwap32Op -> \[r] [x] -> PrimInline $ - r |= u32 ((x .<<. (Int 24)) + r |= toU32 ((x .<<. (Int 24)) `BOr` ((BAnd x (Int 0xFF00)) .<<. (Int 8)) `BOr` ((BAnd x (Int 0xFF0000)) .>>. (Int 8)) `BOr` (x .>>>. (Int 24))) @@ -446,12 +446,12 @@ genPrim prof ty op = case op of ------------------------------ Narrow ------------------------------------------- - Narrow8IntOp -> \[r] [x] -> PrimInline $ r |= (BAnd x (Int 0x7F )) `Sub` (BAnd x (Int 0x80)) - Narrow16IntOp -> \[r] [x] -> PrimInline $ r |= (BAnd x (Int 0x7FFF)) `Sub` (BAnd x (Int 0x8000)) - Narrow32IntOp -> \[r] [x] -> PrimInline $ r |= i32 x + Narrow8IntOp -> \[r] [x] -> PrimInline $ r |= signExtend8 x + Narrow16IntOp -> \[r] [x] -> PrimInline $ r |= signExtend16 x + Narrow32IntOp -> \[r] [x] -> PrimInline $ r |= toI32 x Narrow8WordOp -> \[r] [x] -> PrimInline $ r |= mask8 x Narrow16WordOp -> \[r] [x] -> PrimInline $ r |= mask16 x - Narrow32WordOp -> \[r] [x] -> PrimInline $ r |= u32 x + Narrow32WordOp -> \[r] [x] -> PrimInline $ r |= toU32 x ------------------------------ Double ------------------------------------------- @@ -467,7 +467,7 @@ genPrim prof ty op = case op of DoubleDivOp -> \[r] [x,y] -> PrimInline $ r |= Div x y DoubleNegOp -> \[r] [x] -> PrimInline $ r |= Negate x DoubleFabsOp -> \[r] [x] -> PrimInline $ r |= math_abs [x] - DoubleToIntOp -> \[r] [x] -> PrimInline $ r |= i32 x + DoubleToIntOp -> \[r] [x] -> PrimInline $ r |= toI32 x DoubleToFloatOp -> \[r] [x] -> PrimInline $ r |= math_fround [x] DoubleExpOp -> \[r] [x] -> PrimInline $ r |= math_exp [x] DoubleExpM1Op -> \[r] [x] -> PrimInline $ r |= math_expm1 [x] @@ -504,7 +504,7 @@ genPrim prof ty op = case op of FloatDivOp -> \[r] [x,y] -> PrimInline $ r |= math_fround [Div x y] FloatNegOp -> \[r] [x] -> PrimInline $ r |= Negate x FloatFabsOp -> \[r] [x] -> PrimInline $ r |= math_abs [x] - FloatToIntOp -> \[r] [x] -> PrimInline $ r |= i32 x + FloatToIntOp -> \[r] [x] -> PrimInline $ r |= toI32 x FloatExpOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_exp [x]] FloatExpM1Op -> \[r] [x] -> PrimInline $ r |= math_fround [math_expm1 [x]] FloatLogOp -> \[r] [x] -> PrimInline $ r |= math_fround [math_log [x]] @@ -610,10 +610,10 @@ genPrim prof ty op = case op of SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= u8_ a i - IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= i32_ a i - IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= i32_ a i - IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= u32_ a i + IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i + IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i IndexByteArrayOp_Addr -> \[r1,r2] [a,i] -> PrimInline $ jVar \t -> mconcat [ t |= a .^ "arr" @@ -626,31 +626,31 @@ genPrim prof ty op = case op of ] ] - IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= f3_ a i - IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= f6_ a i + IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= read_f32 a i + IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= read_f64 a i IndexByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" - , r2 |= i32_ a i + , r2 |= read_i32 a i ] - IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= dv_i8 a i - IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= dv_i16 a (i .<<. one_) - IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= i32_ a i + IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= read_i8 a i + IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= read_i16 a i + IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= i32_ a (Add (i .<<. one_) one_) - , l |= u32_ a (i .<<. one_) + [ h |= read_i32 a (Add (i .<<. one_) one_) + , l |= read_u32 a (i .<<. one_) ] - IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= u8_ a i - IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= dv_u16 a (i .<<. one_) - IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= u32_ a i + IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i + IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= read_u16 a i + IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= u32_ a (Add (i .<<. one_) one_) - , l |= u32_ a (i .<<. one_) + [ h |= read_u32 a (Add (i .<<. one_) one_) + , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= u8_ a i - ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= i32_ a i - ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= i32_ a i - ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= u32_ a i + ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i + ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i ReadByteArrayOp_Addr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -660,64 +660,64 @@ genPrim prof ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= f3_ a i - ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= f6_ a i + ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= read_f32 a i + ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= read_f64 a i ReadByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" - , r2 |= i32_ a i + , r2 |= read_i32 a i ] - ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= dv_i8 a i - ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= dv_i16 a (i .<<. one_) - ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= i32_ a i + ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= read_i8 a i + ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= read_i16 a i + ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= i32_ a (Add (i .<<. one_) one_) - , l |= u32_ a (i .<<. one_) + [ h |= read_i32 a (Add (i .<<. one_) one_) + , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= u8_ a i - ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= u1_ a i - ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= u32_ a i + ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i + ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= read_u16 a i + ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= u32_ a (Add (i .<<. one_) one_) - , l |= u32_ a (i .<<. one_) + [ h |= read_u32 a (Add (i .<<. one_) one_) + , l |= read_u32 a (i .<<. one_) ] - WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline $ u8_ a i |= e - WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline $ i32_ a i |= e - WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline $ i32_ a i |= e - WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline $ i32_ a i |= i32 e + WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline $ write_u8 a i e + WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline $ write_i32 a i e + WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline $ write_i32 a i e + WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline $ write_u32 a i e WriteByteArrayOp_Addr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline $ f3_ a i |= e - WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline $ f6_ a i |= e - WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ i32_ a i |= e2 + WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline $ write_f32 a i e + WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline $ write_f64 a i e + WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ write_i32 a i e2 - WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline $ dv_s_i8 a i e - WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline $ dv_s_i16 a (i .<<. one_) e - WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline $ i32_ a i |= e + WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline $ write_i8 a i e + WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline $ write_i16 a i e + WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline $ write_i32 a i e WriteByteArrayOp_Int64 -> \[] [a,i,e1,e2] -> PrimInline $ mconcat - [ i32_ a (Add (i .<<. one_) one_) |= e1 - , i32_ a (i .<<. one_) |= i32 e2 + [ write_i32 a (Add (i .<<. one_) one_) e1 + , write_u32 a (i .<<. one_) e2 ] - WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline $ u8_ a i |= e - WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline $ u1_ a i |= e - WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline $ i32_ a i |= i32 e + WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline $ write_u8 a i e + WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline $ write_u16 a i e + WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline $ write_u32 a i e WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> PrimInline $ mconcat - [ i32_ a (Add (i .<<. one_) one_) |= i32 h - , i32_ a (i .<<. one_) |= i32 l + [ write_u32 a (Add (i .<<. one_) one_) h + , write_u32 a (i .<<. one_) l ] CompareByteArraysOp -> \[r] [a1,o1,a2,o2,n] -> PrimInline $ r |= app "h$compareByteArrays" [a1,o1,a2,o2,n] CopyByteArrayOp -> \[] [a1,o1,a2,o2,n] -> PrimInline $ loopBlockS (Sub n one_) (.>=. zero_) \i -> - [ u8_ a2 (Add i o2) |= u8_ a1 (Add i o1) + [ write_u8 a2 (Add i o2) (read_u8 a1 (Add i o1)) , postDecrS i ] CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof ty CopyByteArrayOp [] xs @@ -727,18 +727,12 @@ genPrim prof ty op = case op of SetByteArrayOp -> \[] [a,o,n,v] -> PrimInline $ loopBlockS zero_ (.<. n) \i -> - [ u8_ a (Add o i) |= v + [ write_u8 a (Add o i) v , postIncrS i ] - AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= i32_ a i - AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline $ i32_ a i |= v - CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline $ - jVar \t -> mconcat - [ t |= i32_ a i - , r |= t - , ifS (t .===. old) (i32_ a i |= new) mempty - ] + AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline $ write_i32 a i v FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ fetchOpByteArray Add r a i v FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ fetchOpByteArray Sub r a i v FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ fetchOpByteArray BAnd r a i v @@ -762,44 +756,44 @@ genPrim prof ty op = case op of ------------------------------- Addr Indexing: Unboxed Arrays ------------------- - IndexOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= u8_ a (off8 o i) - IndexOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= dv_u32 a (off32 o i) - IndexOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) - IndexOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) + IndexOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) IndexOffAddrOp_Addr -> \[ca,co] [a,o,i] -> PrimInline $ ifBlockS (a .^ "arr " .&&. a .^ "arr" .! (i .<<. two_)) [ ca |= a .^ "arr" .! (off32 o i) .! zero_ - , co |= a .^ "arr" .! (off32 o i) .! one_ + , co |= a .^ "arr" .! (off32 o i) .! one_ ] [ ca |= null_ , co |= zero_ ] - IndexOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= dv_f32 a (off32 o i) - IndexOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= dv_f64 a (off64 o i) + IndexOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f32 a (off32 o i) + IndexOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f64 a (off64 o i) IndexOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat [ c1 |= var "h$stablePtrBuf" - , c2 |= dv_i32 a (off32 o i) + , c2 |= read_boff_i32 a (off32 o i) ] - IndexOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ c |= u8_ a (off8 o i) - IndexOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ c |= dv_i16 a (off16 o i) - IndexOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) - IndexOffAddrOp_Int64 -> \[c1,c2] [a,o,i] -> + IndexOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i8 a (off8 o i) + IndexOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i16 a (off16 o i) + IndexOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat - [ c1 |= dv_i32 a (Add (off64 o i) (Int 4)) - , c2 |= dv_i32 a (off64 o i) + [ h |= read_boff_i32 a (Add (off64 o i) (Int 4)) + , l |= read_boff_u32 a (off64 o i) ] - IndexOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ c |= u8_ a (off8 o i) - IndexOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ c |= dv_u16 a (off16 o i) - IndexOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) - IndexOffAddrOp_Word64 -> \[c1,c2] [a,o,i] -> + IndexOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u16 a (off16 o i) + IndexOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) + IndexOffAddrOp_Word64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat - [ c1 |= dv_i32 a (Add (off64 o i) (Int 4)) - , c2 |= dv_i32 a (off64 o i) + [ h |= read_boff_u32 a (Add (off64 o i) (Int 4)) + , l |= read_boff_u32 a (off64 o i) ] - ReadOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= u8_ a (off8 o i) - ReadOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= dv_u32 a (off32 o i) - ReadOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) - ReadOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= dv_i32 a (off32 o i) + ReadOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) + ReadOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) ReadOffAddrOp_Addr -> \[c1,c2] [a,o,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -811,54 +805,54 @@ genPrim prof ty op = case op of , c2 |= zero_ ] ] - ReadOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= dv_f32 a (off32 o i) - ReadOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= dv_f64 a (off64 o i) + ReadOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f32 a (off32 o i) + ReadOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f64 a (off64 o i) ReadOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat [ c1 |= var "h$stablePtrBuf" - , c2 |= dv_u32 a (off32 o i) + , c2 |= read_boff_u32 a (off32 o i) ] - ReadOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ dv_i8 a (off8 o i) - ReadOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ dv_i16 a (off16 o i) - ReadOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ dv_i32 a (off32 o i) - ReadOffAddrOp_Int64 -> \[c1,c2] [a,o,i] -> + ReadOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i8 a (off8 o i) + ReadOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i16 a (off16 o i) + ReadOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat - [ c1 |= dv_i32 a (Add (off64 o i) (Int 4)) - , c2 |= dv_i32 a (off64 o i) + [ h |= read_i32 a (Add (off64 o i) (Int 4)) + , l |= read_u32 a (off64 o i) ] - ReadOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ u8_ a (off8 o i) - ReadOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ dv_u16 a (off16 o i) - ReadOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ dv_i32 a (off32 o i) + ReadOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_u8 a (off8 o i) + ReadOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_u16 a (off16 o i) + ReadOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i32 a (off32 o i) ReadOffAddrOp_Word64 -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat - [ c1 |= dv_i32 a (Add (off64 o i) (Int 4)) - , c2 |= dv_i32 a (off64 o i) + [ c1 |= read_boff_i32 a (Add (off64 o i) (Int 4)) + , c2 |= read_boff_i32 a (off64 o i) ] - WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline $ u8_ a (off8 o i) |= v - WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline $ dv_s_u32 a (off32 o i) v - WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline $ dv_s_i32 a (off32 o i) v - WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline $ dv_s_i32 a (off32 o i) v + WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v WriteOffAddrOp_Addr -> \[] [a,o,i,va,vo] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , AssignStat (a .^ "arr" .! (off32 o i)) $ ValExpr (JList [va, vo]) ] - WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline $ dv_s_f32 a (off32 o i) v - WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline $ dv_s_f64 a (off64 o i) v - WriteOffAddrOp_StablePtr -> \[] [a,o,i,_v1,v2] -> PrimInline $ dv_s_u32 a (off32 o i) v2 - WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline $ dv_s_i8 a (off8 o i) v - WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline $ dv_s_i16 a (off16 o i) v - WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline $ dv_s_i32 a (off32 o i) v + WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline $ write_boff_f32 a (off32 o i) v + WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline $ write_boff_f64 a (off64 o i) v + WriteOffAddrOp_StablePtr -> \[] [a,o,i,_v1,v2] -> PrimInline $ write_boff_u32 a (off32 o i) v2 + WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i8 a (off8 o i) v + WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i16 a (off16 o i) v + WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v WriteOffAddrOp_Int64 -> \[] [a,o,i,v1,v2] -> PrimInline $ mconcat - [ dv_s_i32 a (Add (off64 o i) (Int 4)) v1 - , dv_s_i32 a (off64 o i) v2 - ] - WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline $ u8_ a (off8 o i) |= v - WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline $ dv_s_u16 a (off16 o i) v - WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline $ dv_s_i32 a (off32 o i) v + [ write_boff_i32 a (Add (off64 o i) (Int 4)) v1 + , write_boff_u32 a (off64 o i) v2 + ] + WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u16 a (off16 o i) v + WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v WriteOffAddrOp_Word64 -> \[] [a,o,i,v1,v2] -> PrimInline $ mconcat - [ dv_s_i32 a (Add (off64 o i) (Int 4)) v1 - , dv_s_i32 a (off64 o i) v2 - ] + [ write_boff_u32 a (Add (off64 o i) (Int 4)) v1 + , write_boff_u32 a (off64 o i) v2 + ] -- Mutable variables NewMutVarOp -> \[r] [x] -> PrimInline $ r |= New (app "h$MutVar" [x]) ReadMutVarOp -> \[r] [m] -> PrimInline $ r |= m .^ "val" @@ -1032,8 +1026,8 @@ genPrim prof ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= dv_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -1043,32 +1037,32 @@ genPrim prof ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= dv_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= dv_f32 a i + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= read_boff_f64 a i IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" - , r2 |= dv_i32 a i + , r2 |= read_boff_i32 a i ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= dv_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= dv_i32 a (Add i (Int 4)) - , l |= dv_u32 a i + [ h |= read_boff_i32 a (Add i (Int 4)) + , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= dv_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= dv_u32 a i + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= dv_u32 a (Add i (Int 4)) - , l |= dv_u32 a i + [ h |= read_boff_u32 a (Add i (Int 4)) + , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= dv_u32 a i + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i - ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= dv_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i + ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_u8 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -1078,78 +1072,73 @@ genPrim prof ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= dv_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= dv_f32 a i + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= read_boff_f64 a i ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" - , r2 |= dv_i32 a i + , r2 |= read_boff_i32 a i ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= dv_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= dv_i32 a (Add i (Int 4)) - , l |= dv_u32 a i + [ h |= read_boff_i32 a (Add i (Int 4)) + , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= dv_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= dv_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= dv_u32 a i + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ mconcat - [ h |= dv_u32 a (Add i (Int 4)) - , l |= dv_u32 a i + [ h |= read_boff_u32 a (Add i (Int 4)) + , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= dv_u32 a i + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i - WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline $ dv_s_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline $ dv_s_i32 a i e + WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline $ write_boff_i8 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline $ dv_s_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline $ dv_s_f32 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ dv_s_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline $ dv_s_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline $ dv_s_i32 a i e + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ write_boff_i32 a i e2 + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i -- then write the higher 4 bytes to i+4 - PrimInline $ mconcat [ dv_s_i32 a (Add i (Int 4)) (i32 h) - , dv_s_u32 a i l + PrimInline $ mconcat [ write_boff_i32 a (Add i (Int 4)) h + , write_boff_u32 a i l ] - -- it is probably strange to be using dv_s_i32, and dv_s_i16 when dv_s_u16 and - -- dv_s_u32 exist. Unfortunately this is a infelicity of the JS Backend. u32_ - -- and friends are only valid for reading. For writing, we use i32 and friends - -- because u32_ uses the i32_ views internally and then coerces the Int32 to a - -- Word32. We must go through this ceremony because JS doesn't really have the - -- concept of a Word32, so we have to cast to Int32 and write using i32_. - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline $ dv_s_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline $ dv_s_i16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline $ dv_s_i32 a i e + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline $ write_boff_u32 a i e WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline $ mconcat [ dv_s_i32 a (Add i (Int 4)) (i32 h) - , dv_s_i32 a i (i32 l) + PrimInline $ mconcat [ write_boff_u32 a (Add i (Int 4)) h + , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline $ dv_s_u32 a i (i32 e) + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline $ write_boff_u32 a i e - CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline $ casOp u8_ r a i old new - CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline $ casOp u1_ r a i old new - CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline $ casOp i32_ r a i old new + CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i8 write_i8 r a i old new + CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i16 write_i16 r a i old new + CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i32 write_i32 r a i old new CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline $ - jVar \t_h t_l -> mconcat [ t_h |= i32_ a (Add (i .<<. one_) one_) - , t_l |= i32_ a (i .<<. one_) + jVar \t_h t_l -> mconcat [ t_h |= read_i32 a (Add (i .<<. one_) one_) + , t_l |= read_u32 a (i .<<. one_) , r_h |= t_h , r_l |= t_l , ifS (t_l .===. old_l) -- small optimization, check low bits first, fail fast (ifBlockS (t_h .===. old_h) -- Pre-Condition is good, do the write - [ i32_ a (Add (i .<<. one_) one_) |= new_h - , i32_ a (i .<<. one_) |= i32 new_l + [ write_i32 a (Add (i .<<. one_) one_) new_h + , write_u32 a (i .<<. one_) new_l ] -- no good, don't write mempty) @@ -1163,31 +1152,17 @@ genPrim prof ty op = case op of , r_a |= a1 , r_o |= o1 ] - CasAddrOp_Word -> \[r] [a,o,old,new] -> PrimInline $ - mconcat [ r |= u32_ a o - , ifS (r .===. old) - -- use i32_ instead of u32_, u32_ cannot be used for writing due to - -- hard coded conversion to word using (.>>>. zero_). You see we still - -- do the same convnersion but on the value to write - (i32_ a o |= (new .>>>. zero_)) - mempty - ] - - CasAddrOp_Word8 -> \[r] [a,o,old,new] -> PrimInline $ casOp u8_ r a o old new - CasAddrOp_Word16 -> \[r] [a,o,old,new] -> PrimInline $ casOp u1_ r a o old new - CasAddrOp_Word32 -> \[r] [a,o,old,new] -> PrimInline $ - mconcat [ r |= u32_ a o - , ifS (r .===. old) - (i32_ a o |= (new .>>>. zero_)) - mempty - ] + CasAddrOp_Word -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u32 write_u32 r a o old new + CasAddrOp_Word8 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u8 write_u8 r a o old new + CasAddrOp_Word16 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u16 write_u16 r a o old new + CasAddrOp_Word32 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u32 write_u32 r a o old new CasAddrOp_Word64 -> \[r_h,r_l] [a,o,old_h,old_l,new_h,new_l] -> PrimInline $ - mconcat [ r_h |= dv_u32 a (Add o (Int 4)) - , r_l |= dv_u32 a o + mconcat [ r_h |= read_u32 a (Add o (Int 4)) + , r_l |= read_u32 a o , ifS (r_l .===. old_l) (ifBlockS (r_h .===. old_h) - [ dv_s_u32 a (Add o (Int 4)) new_h - , dv_s_u32 a o new_l + [ write_u32 a (Add o (Int 4)) new_h + , write_u32 a o new_l ] mempty) mempty @@ -1215,21 +1190,21 @@ genPrim prof ty op = case op of -- at Addr# a2[o2] also comes from this -- a1/a2 array. mconcat [ r_a |= a1 -- might be wrong (see above) - , r_o |= dv_u32 a1 o1 + , r_o |= read_boff_u32 a1 o1 -- TODO (see above) -- assert that a1 === a2 - , dv_s_u32 a1 o1 o2 + , write_boff_u32 a1 o1 o2 ] InterlockedExchange_Word -> \[r] [a,o,w] -> PrimInline $ - mconcat [ r |= dv_u32 a o - , dv_s_u32 a o w + mconcat [ r |= read_boff_u32 a o + , write_boff_u32 a o w ] ShrinkSmallMutableArrayOp_Char -> \[] [a,n] -> PrimInline $ appS "h$shrinkMutableCharArray" [a,n] GetSizeofSmallMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" - AtomicReadAddrOp_Word -> \[r] [a,o] -> PrimInline $ r |= dv_u32 a o - AtomicWriteAddrOp_Word -> \[] [a,o,w] -> PrimInline $ dv_s_u32 a o w + AtomicReadAddrOp_Word -> \[r] [a,o] -> PrimInline $ r |= read_boff_u32 a o + AtomicWriteAddrOp_Word -> \[] [a,o,w] -> PrimInline $ write_boff_u32 a o w ------------------------------ Unhandled primops ------------------- @@ -1331,66 +1306,135 @@ appT (r:rs) f xs = mconcat , mconcat (zipWith (\r ret -> r |= toJExpr ret) rs (enumFrom Ret1)) ] -i32_, u32_, u8_, f6_, f3_, u1_ :: JExpr -> JExpr -> JExpr -i32_ a i = IdxExpr (a .^ "i3") i -u32_ a i = (IdxExpr (a .^ "i3") i) .>>>. zero_ -u8_ a i = IdxExpr (a .^ "u8") i -f6_ a i = IdxExpr (a .^ "f6") i -f3_ a i = IdxExpr (a .^ "f3") i -u1_ a i = IdxExpr (a .^ "u1") i - --- | Data View helper functions. In the JS backend we keep a field @dv@ for each --- ByteArray. The @dv@ field is a JS @DataView@ that is a low level interface --- for reading/writing number types into a JS @ArrayBuffer at . See --- 'h$newByteArray' in 'ghc/rts/js/mem.js' for details. These helper functions --- wrap useful @DataView@ methods for us in PrimOps. The argument list consists --- of the index @i@, the new value to set (in the case of a setter) @v@, and a --- Boolean flag indicating whether the type in question is stored in --- little-endian (True) or big-endian (False) format. -dv_s_i8, dv_s_i16, dv_s_u16, dv_s_i32, dv_s_u32, dv_s_f32, dv_s_f64 :: JExpr -> JExpr -> JExpr -> JStat -dv_s_i8 a i v = ApplStat (a .^ "dv" .^ "setInt8" ) [i, v, true_] -dv_s_u16 a i v = ApplStat (a .^ "dv" .^ "setUint16" ) [i, v, true_] -dv_s_i16 a i v = ApplStat (a .^ "dv" .^ "setInt16" ) [i, v, true_] -dv_s_i32 a i v = ApplStat (a .^ "dv" .^ "setInt32" ) [i, v, true_] -dv_s_u32 a i v = ApplStat (a .^ "dv" .^ "setUint32" ) [i, v, true_] -dv_s_f32 a i v = ApplStat (a .^ "dv" .^ "setFloat32") [i, v, true_] -dv_s_f64 a i v = ApplStat (a .^ "dv" .^ "setFloat64") [i, v, true_] - -dv_i8, dv_u8, dv_i16, dv_u16, dv_i32, dv_u32, dv_f32, dv_f64 :: JExpr -> JExpr -> JExpr -dv_u8 a i = ApplExpr (a .^ "dv" .^ "getUint8" ) [i, true_] -dv_i8 a i = ApplExpr (a .^ "dv" .^ "getInt8" ) [i, true_] -dv_i16 a i = ApplExpr (a .^ "dv" .^ "getInt16" ) [i, true_] -dv_u16 a i = ApplExpr (a .^ "dv" .^ "getUint16" ) [i, true_] -dv_i32 a i = ApplExpr (a .^ "dv" .^ "getInt32" ) [i, true_] -dv_u32 a i = ApplExpr (a .^ "dv" .^ "getUint32" ) [i, true_] -dv_f32 a i = ApplExpr (a .^ "dv" .^ "getFloat32") [i, true_] -dv_f64 a i = ApplExpr (a .^ "dv" .^ "getFloat64") [i, true_] +-------------------------------------------- +-- ByteArray indexing +-------------------------------------------- + +-- For every ByteArray, the RTS creates the following views: +-- i3: Int32 view +-- u8: Word8 view +-- u1: Word16 view +-- f3: Float32 view +-- f6: Float64 view +-- dv: generic DataView +-- It seems a bit weird to mix Int and Word views like this, but perhaps they +-- are the more common. +-- +-- See 'h$newByteArray' in 'ghc/rts/js/mem.js' for details. +-- +-- Note that *byte* indexing can only be done with the generic DataView. Use +-- read_boff_* and write_boff_* for this. +-- +-- Other read_* and write_* helpers directly use the more specific views. +-- Prefer using them over idx_* to make your intent clearer. + +idx_i32, idx_u8, idx_u16, idx_f64, idx_f32 :: JExpr -> JExpr -> JExpr +idx_i32 a i = IdxExpr (a .^ "i3") i +idx_u8 a i = IdxExpr (a .^ "u8") i +idx_u16 a i = IdxExpr (a .^ "u1") i +idx_f64 a i = IdxExpr (a .^ "f6") i +idx_f32 a i = IdxExpr (a .^ "f3") i + +read_u8 :: JExpr -> JExpr -> JExpr +read_u8 a i = idx_u8 a i + +read_u16 :: JExpr -> JExpr -> JExpr +read_u16 a i = idx_u16 a i + +read_u32 :: JExpr -> JExpr -> JExpr +read_u32 a i = toU32 (idx_i32 a i) + +read_i8 :: JExpr -> JExpr -> JExpr +read_i8 a i = signExtend8 (idx_u8 a i) + +read_i16 :: JExpr -> JExpr -> JExpr +read_i16 a i = signExtend16 (idx_u16 a i) + +read_i32 :: JExpr -> JExpr -> JExpr +read_i32 a i = idx_i32 a i + +read_f32 :: JExpr -> JExpr -> JExpr +read_f32 a i = idx_f32 a i + +read_f64 :: JExpr -> JExpr -> JExpr +read_f64 a i = idx_f64 a i + +write_u8 :: JExpr -> JExpr -> JExpr -> JStat +write_u8 a i v = idx_u8 a i |= v + +write_u16 :: JExpr -> JExpr -> JExpr -> JStat +write_u16 a i v = idx_u16 a i |= v + +write_u32 :: JExpr -> JExpr -> JExpr -> JStat +write_u32 a i v = idx_i32 a i |= v + +write_i8 :: JExpr -> JExpr -> JExpr -> JStat +write_i8 a i v = idx_u8 a i |= v + +write_i16 :: JExpr -> JExpr -> JExpr -> JStat +write_i16 a i v = idx_u16 a i |= v + +write_i32 :: JExpr -> JExpr -> JExpr -> JStat +write_i32 a i v = idx_i32 a i |= v + +write_f32 :: JExpr -> JExpr -> JExpr -> JStat +write_f32 a i v = idx_f32 a i |= v + +write_f64 :: JExpr -> JExpr -> JExpr -> JStat +write_f64 a i v = idx_f64 a i |= v + +-- Data View helper functions: byte indexed! +-- +-- The argument list consists of the array @a@, the index @i@, and the new value +-- to set (in the case of a setter) @v at . + +write_boff_i8, write_boff_u8, write_boff_i16, write_boff_u16, write_boff_i32, write_boff_u32, write_boff_f32, write_boff_f64 :: JExpr -> JExpr -> JExpr -> JStat +write_boff_i8 a i v = write_i8 a i v +write_boff_u8 a i v = write_u8 a i v +write_boff_i16 a i v = ApplStat (a .^ "dv" .^ "setInt16" ) [i, v, true_] +write_boff_u16 a i v = ApplStat (a .^ "dv" .^ "setUint16" ) [i, v, true_] +write_boff_i32 a i v = ApplStat (a .^ "dv" .^ "setInt32" ) [i, v, true_] +write_boff_u32 a i v = ApplStat (a .^ "dv" .^ "setUint32" ) [i, v, true_] +write_boff_f32 a i v = ApplStat (a .^ "dv" .^ "setFloat32") [i, v, true_] +write_boff_f64 a i v = ApplStat (a .^ "dv" .^ "setFloat64") [i, v, true_] + +read_boff_i8, read_boff_u8, read_boff_i16, read_boff_u16, read_boff_i32, read_boff_u32, read_boff_f32, read_boff_f64 :: JExpr -> JExpr -> JExpr +read_boff_i8 a i = read_i8 a i +read_boff_u8 a i = read_u8 a i +read_boff_i16 a i = ApplExpr (a .^ "dv" .^ "getInt16" ) [i, true_] +read_boff_u16 a i = ApplExpr (a .^ "dv" .^ "getUint16" ) [i, true_] +read_boff_i32 a i = ApplExpr (a .^ "dv" .^ "getInt32" ) [i, true_] +read_boff_u32 a i = ApplExpr (a .^ "dv" .^ "getUint32" ) [i, true_] +read_boff_f32 a i = ApplExpr (a .^ "dv" .^ "getFloat32") [i, true_] +read_boff_f64 a i = ApplExpr (a .^ "dv" .^ "getFloat64") [i, true_] fetchOpByteArray :: (JExpr -> JExpr -> JExpr) -> JExpr -> JExpr -> JExpr -> JExpr -> JStat fetchOpByteArray op tgt src i v = mconcat - [ tgt |= i32_ src i - , i32_ src i |= op tgt v + [ tgt |= read_i32 src i + , write_i32 src i (op tgt v) ] fetchOpAddr :: (JExpr -> JExpr -> JExpr) -> JExpr -> JExpr -> JExpr -> JExpr -> JStat fetchOpAddr op tgt src i v = mconcat - [ tgt |= src .! i - , src .! i |= op tgt v + [ tgt |= read_boff_u32 src i + , write_boff_u32 src i (op tgt v) ] casOp - :: (JExpr -> JExpr -> JExpr) -- view, the view of the ArrayBuffer to use + :: (JExpr -> JExpr -> JExpr) -- read + -> (JExpr -> JExpr -> JExpr -> JStat) -- write -> JExpr -- target register to store result -> JExpr -- source arrays -> JExpr -- index -> JExpr -- old value to compare -> JExpr -- new value to write -> JStat -casOp view tgt src i old new = mconcat [ tgt |= view src i - , ifS (tgt .===. old) - (view src i |= new) - mempty - ] +casOp read write tgt src i old new = mconcat + [ tgt |= read src i + , ifS (tgt .===. old) + (write src i new) + mempty + ] -------------------------------------------------------------------------------- -- Lifted Arrays @@ -1419,19 +1463,15 @@ newByteArray tgt len = -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. -- So (x|0) * (y|0) can still return values outside of the Int32 range. You have -- been warned! -i32 :: JExpr -> JExpr -i32 e = BOr e zero_ +toI32 :: JExpr -> JExpr +toI32 e = BOr e zero_ -- e>>>0 (32 bit unsigned integer truncation) -- required because of JS numbers. e>>>0 converts e to a Word32 -- so (-2147483648) >>> 0 = 2147483648 -- and ((-2147483648) >>>0) | 0 = -2147483648 --- --- Warning: This function will throw an exception if it ends up on the left side --- of an assignment. The reason it blows up is because of the bit shift (used --- for coercion) is illegal on the LHS of an assignment -u32 :: JExpr -> JExpr -u32 e = e .>>>. zero_ +toU32 :: JExpr -> JExpr +toU32 e = e .>>>. zero_ quotShortInt :: Int -> JExpr -> JExpr -> JExpr quotShortInt bits x y = BAnd (signed x `Div` signed y) mask View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82745317da9dad7a6aa2fee5e36581e14fec683b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82745317da9dad7a6aa2fee5e36581e14fec683b You're receiving 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 Oct 4 15:30:36 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Tue, 04 Oct 2022 11:30:36 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Use GHCJS's signExtend/narrow Message-ID: <633c519c342a5_2c97572ed3bc7817588ab@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 6a0f68a6 by Sylvain Henry at 2022-10-04T17:33:52+02:00 Use GHCJS's signExtend/narrow - - - - - 1 changed file: - compiler/GHC/JS/Make.hs Changes: ===================================== compiler/GHC/JS/Make.hs ===================================== @@ -483,13 +483,13 @@ mask8 x = BAnd x (Int 0xFF) mask16 :: JExpr -> JExpr mask16 x = BAnd x (Int 0xFFFF) --- | Sign-extend a 8-bit value +-- | Sign-extend/narrow a 8-bit value signExtend8 :: JExpr -> JExpr -signExtend8 x = (BAnd x (Int 0xFF) `BXor` 0x80) `Sub` 0x80 +signExtend8 x = (BAnd x (Int 0x7F )) `Sub` (BAnd x (Int 0x80)) --- | Sign-extend a 16-bit value +-- | Sign-extend/narrow a 16-bit value signExtend16 :: JExpr -> JExpr -signExtend16 x = (BAnd x (Int 0xFFFF) `BXor` 0x8000) `Sub` 0x8000 +signExtend16 x = (BAnd x (Int 0x7FFF)) `Sub` (BAnd x (Int 0x8000)) -- | Select a property 'prop', from and object 'obj' -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a0f68a6836cccb6b549c13b0b6ce20e2cceccc5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a0f68a6836cccb6b549c13b0b6ce20e2cceccc5 You're receiving 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 Oct 4 16:03:50 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 12:03:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633c59664f9f7_2c975742bcfe5c1769928@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 19534fa4 by Oleg Grenrus at 2022-10-04T12:03:34-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19534fa4bd2680fdd7972e55b3a75f5fcfdc8ca4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19534fa4bd2680fdd7972e55b3a75f5fcfdc8ca4 You're receiving 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 Oct 4 16:36:10 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 04 Oct 2022 12:36:10 -0400 Subject: [Git][ghc/ghc][wip/T22084] 6 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <633c60fa51e7f_2c975742bd2a1c1777353@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22084 at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 8baf231f by Simon Peyton Jones at 2022-10-03T12:24:37+01:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). It's not a big deal, but it shaves 0.1% off compile times. - - - - - cd65da06 by Simon Peyton Jones at 2022-10-03T12:24:37+01:00 Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. - - - - - 30 changed files: - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Utils/Misc.hs - rts/Continuation.c - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs - + testsuite/tests/simplCore/should_compile/T21148.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9a5a7394d7d7108b827c50441eb48237f75ffea...cd65da060f00bd74351e6324ddf567f19e31def4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9a5a7394d7d7108b827c50441eb48237f75ffea...cd65da060f00bd74351e6324ddf567f19e31def4 You're receiving 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 Oct 4 16:52:54 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 04 Oct 2022 12:52:54 -0400 Subject: [Git][ghc/ghc][wip/T21623] 12 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <633c64e6f644_2c975742bcfe201784196@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - b407013b by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Start work Not ready for review More progress Wibbles Stage1 compiles More wibbles More wibbles More -- almost working Comments Wibbles Wibbles Wibble inlineId Wibbles Infinite loop somewhere More wibbles. Maybe can build stage2 Make FuNCo a thing by itself Wibble Wibble Wibbles Fix OptCoercion Wibble Wibble to optCoercion Replace SORT with TYPE and CONSTRAINT Wibble Delete unused import Delete TypeOrConstraint from ghc-prim:GHC.Types Move from NthCo to SelCo Wibbles Wibbles in RepType Wibble Add mkWpEta Really add mkWpEta Wibble Typeable binds etc Improve error messages More wibbles, mainly to error messages Wibbles Wibbles to errors Wibbles But especially: treat Constraint as Typeable More wibbles More changes * Move role into SelTyCon * Get rid of mkTcSymCo and friends Unused variable Wibbles Wibble Accept error message changes Refactoring... Remove tc functions like tcKind, tcGetTyVar. Move tyConsOfType, occCheckExpand to TyCo.FVs. Introduce GHC.Core.TyCo.Compare Lots of import changes! Update haddock submodule (I hope) Wibbles (notably: actually add GHC.Core.TyCo.Compare) Wibbles Wibble output of T16575 Wibbles More wibbles Remove infinite loop in T1946 See Note [ForAllTy and type equality] Deal with rejigConRes Needs a Note to be written by Richard Some renaming AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag Update haddock submodule Rename TyCoBinder to ForAllTyBinder Wibbles Update haddock Wibble Update unix submodule I think I accidentally got it out of sync with HEAD; this puts it back. Rename TyCoBinder to PiTyBinder Update Haddock submodule Wrap dictionaries in tuples This fixes the kind bugs in arrow desugaring. Needs some Notes, but I want to try CI. More on boxing data cons Rebase and update GHC.Tc.Errors/GHC.Tc.Errors.Ppr Revert accidental changes in SameOccInfo fixes mod180, tcfail182 Wibbles in error messages ..plus eqType comes from GHC.Core.TyCo.Compare Wibbles More wibbles Reaedy for RAE review Fix fragile rule setup in GHC.Float See Note [realToFrac natural-to-float] Wibbles More wibbles Remove unused import Remove another unused import Wibbles Update haddock submodule Respond to Sam's suggestions Wibbles Wibbles - - - - - eece7e62 by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Wibbles - - - - - 10649fe2 by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Unused import - - - - - ac0ab032 by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Better boxingCon_maybe - - - - - b05ed54a by Richard Eisenberg at 2022-10-04T17:54:58+01:00 Improvements to comments, etc., from Richard - - - - - 17b3477a by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Respond to Richard - - - - - 54921b32 by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Improve boxing-data-con API - - - - - b9847abf by Simon Peyton Jones at 2022-10-04T17:54:58+01:00 Update error messages - - - - - 21 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types.hs-boot - compiler/GHC/Builtin/Types/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - − compiler/GHC/Builtin/Types/Prim.hs-boot - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/InstEnv.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/720fa45f07397c22bbd45f20065c0beb3f78d585...b9847abf119c717ac9015c8a67fdff6ccae3e90d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/720fa45f07397c22bbd45f20065c0beb3f78d585...b9847abf119c717ac9015c8a67fdff6ccae3e90d You're receiving 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 Oct 4 17:36:02 2022 From: gitlab at gitlab.haskell.org (Douglas Wilson (@duog)) Date: Tue, 04 Oct 2022 13:36:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/dougwilson/noupdate Message-ID: <633c6f02b5567_2c975742bcfe701787191@gitlab.mail> Douglas Wilson pushed new branch wip/dougwilson/noupdate at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/dougwilson/noupdate You're receiving 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 Oct 4 18:54:05 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 14:54:05 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Use sameByteArray# in sameByteArray Message-ID: <633c814d48aeb_2c97572ed3bc781820434@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 17019caa by Oleg Grenrus at 2022-10-04T14:53:48-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/17019caacfddc5a9f56846cfaa6c8e0bc6c1cc52 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/17019caacfddc5a9f56846cfaa6c8e0bc6c1cc52 You're receiving 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 Oct 4 20:22:57 2022 From: gitlab at gitlab.haskell.org (Douglas Wilson (@duog)) Date: Tue, 04 Oct 2022 16:22:57 -0400 Subject: [Git][ghc/ghc][wip/dougwilson/noupdate] 2 commits: WIP add noupdate magic function Message-ID: <633c96213a4e0_2c97572ed3bc7818349ba@gitlab.mail> Douglas Wilson pushed to branch wip/dougwilson/noupdate at Glasgow Haskell Compiler / GHC Commits: a3218584 by Douglas Wilson at 2022-10-04T20:45:13+01:00 WIP add noupdate magic function - - - - - 4bd0a3cd by Douglas Wilson at 2022-10-04T20:45:13+01:00 wip - - - - - 9 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Driver/Config/Stg/Pipeline.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Stg/Pipeline.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Types/Id/Make.hs - libraries/ghc-prim/GHC/Magic.hs - + noupdate.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -2322,12 +2322,13 @@ rootMainKey, runMainKey :: Unique rootMainKey = mkPreludeMiscIdUnique 101 runMainKey = mkPreludeMiscIdUnique 102 -thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey :: Unique +thenIOIdKey, lazyIdKey, assertErrorIdKey, oneShotKey, runRWKey, noupdateKey :: Unique thenIOIdKey = mkPreludeMiscIdUnique 103 lazyIdKey = mkPreludeMiscIdUnique 104 assertErrorIdKey = mkPreludeMiscIdUnique 105 oneShotKey = mkPreludeMiscIdUnique 106 runRWKey = mkPreludeMiscIdUnique 107 +noupdateKey = mkPreludeMiscIdUnique 119 traceKey :: Unique traceKey = mkPreludeMiscIdUnique 108 ===================================== compiler/GHC/Driver/Config/Stg/Pipeline.hs ===================================== @@ -36,6 +36,7 @@ getStgToDo for_bytecode dflags = -- See Note [StgCse after unarisation] in GHC.Stg.CSE , optional Opt_StgCSE StgCSE , optional Opt_StgLiftLams $ StgLiftLams $ initStgLiftConfig dflags + , mandatory StgNoupdate , runWhen for_bytecode StgBcPrep , optional Opt_StgStats StgStats ] where ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -543,7 +543,7 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg _ -> mkWildValBinder Many ty1 mkCoreAppDs _ (Var f `App` Type _r) arg - | f `hasKey` noinlineIdKey -- See Note [noinlineId magic] in GHC.Types.Id.Make + | f `hasKey` noinlineIdKey || f `hasKey` noupdateKey -- See Note [noinlineId magic] in GHC.Types.Id.Make , (fun, args) <- collectArgs arg , not (null args) = (Var f `App` Type (exprType fun) `App` fun) ===================================== compiler/GHC/Stg/Pipeline.hs ===================================== @@ -7,7 +7,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies, ViewPatterns, LambdaCase, NamedFieldPuns #-} module GHC.Stg.Pipeline ( StgPipelineOpts (..) @@ -20,7 +20,6 @@ import GHC.Prelude import GHC.Driver.Flags import GHC.Stg.Syntax - import GHC.Stg.Lint ( lintStgTopBindings ) import GHC.Stg.Stats ( showStgStats ) import GHC.Stg.FVs ( depSortWithAnnotStgPgm ) @@ -32,6 +31,7 @@ import GHC.Unit.Module ( Module ) import GHC.Utils.Error import GHC.Types.Var +import GHC.Types.Id.Make import GHC.Types.Unique.Supply import GHC.Utils.Outputable import GHC.Utils.Logger @@ -131,6 +131,11 @@ stg2stg logger extra_vars opts this_mod binds liftIO (stg_linter True "Unarise" binds') return binds' + StgNoupdate -> do + let binds' = do_noupdate <$> binds + return binds' + + ppr_opts = stgPipeline_pprOpts opts dump_when flag header binds = putDumpFileMaybe logger flag header FormatSTG (pprStgTopBindings ppr_opts binds) @@ -159,4 +164,34 @@ data StgToDo -- ^ Mandatory when compiling to bytecode | StgDoNothing -- ^ Useful for building up 'getStgToDo' + | StgNoupdate deriving (Show, Read, Eq, Ord) + + +do_noupdate :: StgTopBinding -> StgTopBinding +do_noupdate (StgTopLifted x) = StgTopLifted (do_noupdate_bind x) +do_noupdate x = x + + +do_noupdate_bind :: StgBinding -> StgBinding +do_noupdate_bind (StgNonRec i rhs) = StgNonRec i (do_noupdate_rhs rhs) +do_noupdate_bind (StgRec bs) = StgRec [ (i, do_noupdate_rhs rhs) | (i,rhs) <- bs] + +do_noupdate_rhs :: StgRhs -> StgRhs +do_noupdate_rhs (StgRhsClosure x y Updatable [] body) = case do_noupdate_expr body of + (True, r) -> StgRhsClosure x y ReEntrant [] r + (_, r) -> (StgRhsClosure x y Updatable [] r) +do_noupdate_rhs (StgRhsClosure x y upd_flag args body) = StgRhsClosure x y upd_flag args (snd $ do_noupdate_expr body) +do_noupdate_rhs x = x + +do_noupdate_expr :: StgExpr -> (Bool, StgExpr) +do_noupdate_expr = \case + StgApp (( == noupdateId) -> True) (StgVarArg i : rest) -> (True, StgApp i rest) + StgLet x binds body -> StgLet x (do_noupdate_bind binds) <$> (do_noupdate_expr body) + StgTick ticks x -> StgTick ticks <$> do_noupdate_expr x + StgCase scrut y z alts -> (False, StgCase (snd $ do_noupdate_expr scrut) y z (do_noupdate_alt <$> alts)) + StgLetNoEscape x binds body -> StgLetNoEscape x (do_noupdate_bind binds) <$> (do_noupdate_expr body) + x -> (False, x) + +do_noupdate_alt :: StgAlt -> StgAlt +do_noupdate_alt x at GenStgAlt{alt_rhs} = x{ alt_rhs = snd $ do_noupdate_expr alt_rhs } ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -20,6 +20,8 @@ import GHC.Core.Opt.Arity( isOneShotBndr ) import GHC.Runtime.Heap.Layout import GHC.Unit.Module +import GHC.Types.Id.Make + import GHC.Stg.Syntax import GHC.Platform @@ -59,6 +61,7 @@ import GHC.Types.Tickish ( tickishIsCode ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Trace import GHC.Data.FastString import GHC.Data.List.SetOps @@ -230,6 +233,9 @@ cgRhs id (StgRhsClosure fvs cc upd_flag args body) -- Non-constructor right hand sides ------------------------------------------------------------------------ +strip_ticks :: CgStgExpr -> CgStgExpr +strip_ticks = stripStgTicksTopE (not . tickishIsCode) + mkRhsClosure :: Profile -> Bool -- Omit AP Thunks to improve profiling -> Bool -- Lint tag inference checks @@ -281,14 +287,13 @@ mkRhsClosure profile _ _check_tags bndr _cc upd_flag -- Updatable thunk [] -- A thunk expr - | let strip = stripStgTicksTopE (not . tickishIsCode) - , StgCase (StgApp scrutinee [{-no args-}]) + | StgCase (StgApp scrutinee [{-no args-}]) _ -- ignore bndr (AlgAlt _) [GenStgAlt{ alt_con = DataAlt _ , alt_bndrs = params - , alt_rhs = sel_expr}] <- strip expr - , StgApp selectee [{-no args-}] <- strip sel_expr + , alt_rhs = sel_expr}] <- strip_ticks expr + , StgApp selectee [{-no args-}] <- strip_ticks sel_expr , the_fv == scrutinee -- Scrutinee is the only free variable , let (_, _, params_w_offsets) = mkVirtConstrOffsets profile (addIdReps (assertNonVoidIds params)) ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -1,7 +1,7 @@ {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeFamilies, ViewPatterns #-} ----------------------------------------------------------------------------- -- @@ -17,6 +17,7 @@ import GHC.Prelude hiding ((<*>)) import {-# SOURCE #-} GHC.StgToCmm.Bind ( cgBind ) +import GHC.Types.Id.Make import GHC.StgToCmm.Monad import GHC.StgToCmm.Heap import GHC.StgToCmm.Env @@ -74,6 +75,9 @@ cgExpr (StgApp fun args) = cgIdApp fun args cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = cgIdApp a [] +cgExpr (StgApp ((== noupdateId) -> True) [StgVarArg a]) = + cgIdApp a [] + -- dataToTag# :: a -> Int# -- See Note [dataToTag# magic] in GHC.Core.Opt.ConstantFold -- TODO: There are some more optimization ideas for this code path ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Id.Make ( voidPrimId, voidArgId, nullAddrId, seqId, lazyId, lazyIdKey, coercionTokenId, coerceId, - proxyHashId, noinlineId, noinlineIdName, nospecId, nospecIdName, + proxyHashId, noinlineId, noupdateId, noinlineIdName, nospecId, nospecIdName, coerceName, leftSectionName, rightSectionName, ) where @@ -160,7 +160,7 @@ wiredInIds ++ errorIds -- Defined in GHC.Core.Make magicIds :: [Id] -- See Note [magicIds] -magicIds = [lazyId, oneShotId, noinlineId, nospecId] +magicIds = [lazyId, oneShotId, noinlineId, nospecId, noupdateId] ghcPrimIds :: [Id] -- See Note [ghcPrimIds (aka pseudoops)] ghcPrimIds @@ -1402,9 +1402,10 @@ leftSectionName = mkWiredInIdName gHC_PRIM (fsLit "leftSection") leftSecti rightSectionName = mkWiredInIdName gHC_PRIM (fsLit "rightSection") rightSectionKey rightSectionId -- Names listed in magicIds; see Note [magicIds] -lazyIdName, oneShotName, noinlineIdName, nospecIdName :: Name +lazyIdName, oneShotName, noinlineIdName, nospecIdName, noupdateName :: Name lazyIdName = mkWiredInIdName gHC_MAGIC (fsLit "lazy") lazyIdKey lazyId oneShotName = mkWiredInIdName gHC_MAGIC (fsLit "oneShot") oneShotKey oneShotId +noupdateName = mkWiredInIdName gHC_MAGIC (fsLit "noupdate") noupdateKey noupdateId noinlineIdName = mkWiredInIdName gHC_MAGIC (fsLit "noinline") noinlineIdKey noinlineId nospecIdName = mkWiredInIdName gHC_MAGIC (fsLit "nospec") nospecIdKey nospecId @@ -1480,6 +1481,12 @@ nospecId = pcMiscPrelId nospecIdName ty info info = noCafIdInfo ty = mkSpecForAllTys [alphaTyVar] (mkVisFunTyMany alphaTy alphaTy) +noupdateId :: Id +noupdateId = pcMiscPrelId noupdateName ty info + where + info = noCafIdInfo + ty = mkSpecForAllTys [alphaTyVar] (mkVisFunTyMany alphaTy alphaTy) + oneShotId :: Id -- See Note [The oneShot function] oneShotId = pcMiscPrelId oneShotName ty info where ===================================== libraries/ghc-prim/GHC/Magic.hs ===================================== @@ -23,7 +23,7 @@ -- ----------------------------------------------------------------------------- -module GHC.Magic ( inline, noinline, lazy, oneShot, runRW# ) where +module GHC.Magic ( inline, noinline, noupdate, lazy, oneShot, runRW# ) where -------------------------------------------------- -- See Note [magicIds] in GHC.Types.Id.Make @@ -61,6 +61,10 @@ inline x = x noinline :: a -> a noinline x = x +{-# NOINLINE noupdate #-} +noupdate :: a -> a +noupdate x = x + -- | The 'lazy' function restrains strictness analysis a little. The -- call @lazy e@ means the same as @e@, but 'lazy' has a magical -- property so far as strictness analysis is concerned: it is lazy in ===================================== noupdate.hs ===================================== @@ -0,0 +1,47 @@ +{-# OPTIONS_GHC -O2 -ddump-cmm -ddump-stg-final #-} +import Debug.Trace +import Control.Monad +import GHC.Magic +import Data.Time +import GHC.IO.Unsafe + +main :: IO () +main = do + putStrLn "evaluating a top level updating thunk 2 times:" + replicateM_ 2 $ updatingThunk + putStrLn "evaluating a top level reentrant thunk 2 times:" + replicateM_ 2 $ reentrantThunk + x <- show <$> getCurrentTime + let + updating_local = trace "updating local thunk" $ pure x + reentrant_local = noupdate (trace "reentrant local thunk" (pure x)) + putStrLn "evaluating a top level updating thunk 2 times:" + replicateM_ 2 $ updating_local + putStrLn "evaluating a top level reentrant thunk 2 times:" + replicateM_ 2 $ reentrant_local + let y = bar "dougrulz" + replicateM_ 2 $ print y + + + + + + + +{-# noinline updatingThunk #-} +updatingThunk :: IO Int +updatingThunk = trace "updatingThunk" $ length . show <$> getCurrentTime + +{-# noinline foo #-} +foo () = (trace "reentrantThunk" $ length . show <$> getCurrentTime) + +{-# noinline reentrantThunk #-} +reentrantThunk :: IO Int +reentrantThunk = noupdate foo () + + +{-# noinline bar #-} +bar :: String -> Int +bar s = let + x = noupdate (length s) + in x View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53f74370bee1c4affebcfafc4c4cd10d236fa401...4bd0a3cdc19c46206a2e10ab7af934c934b9d119 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53f74370bee1c4affebcfafc4c4cd10d236fa401...4bd0a3cdc19c46206a2e10ab7af934c934b9d119 You're receiving 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 Oct 4 21:54:20 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 17:54:20 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: chore: extend `.editorconfig` for C files Message-ID: <633cab8cebc71_2c9757514141851142@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 01e0f444 by Nicolas Trangez at 2022-10-04T17:54:01-04:00 chore: extend `.editorconfig` for C files - - - - - 35f741ce by Brandon Chinn at 2022-10-04T17:54:02-04:00 Fix docs for pattern synonyms - - - - - 098f3df7 by Oleg Grenrus at 2022-10-04T17:54:04-04:00 Use sameByteArray# in sameByteArray - - - - - 3 changed files: - .editorconfig - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs Changes: ===================================== .editorconfig ===================================== @@ -12,3 +12,7 @@ end_of_line = lf [Makefile] indent_style = tab + +[*.c] +indent_style = space +indent_size = 2 ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17019caacfddc5a9f56846cfaa6c8e0bc6c1cc52...098f3df749200dd96f8c7be098ff9a839633a2bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17019caacfddc5a9f56846cfaa6c8e0bc6c1cc52...098f3df749200dd96f8c7be098ff9a839633a2bf You're receiving 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 Oct 5 00:34:24 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 20:34:24 -0400 Subject: [Git][ghc/ghc][master] chore: extend `.editorconfig` for C files Message-ID: <633cd110dc0b9_1eea6a51428245ac@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - 1 changed file: - .editorconfig Changes: ===================================== .editorconfig ===================================== @@ -12,3 +12,7 @@ end_of_line = lf [Makefile] indent_style = tab + +[*.c] +indent_style = space +indent_size = 2 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/48ab9ca5abae82c45495c01e7634ff2a92979346 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/48ab9ca5abae82c45495c01e7634ff2a92979346 You're receiving 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 Oct 5 00:35:04 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 20:35:04 -0400 Subject: [Git][ghc/ghc][master] Fix docs for pattern synonyms Message-ID: <633cd138a50d2_1eea6a514142834@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 1 changed file: - docs/users_guide/exts/pattern_synonyms.rst Changes: ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8df5c72185effbe2cca8d6038d2a356690c9d00 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8df5c72185effbe2cca8d6038d2a356690c9d00 You're receiving 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 Oct 5 00:35:39 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Oct 2022 20:35:39 -0400 Subject: [Git][ghc/ghc][master] Use sameByteArray# in sameByteArray Message-ID: <633cd15bd87f1_1eea6a51428319b3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/463ffe0287eab354a438304111041ef82d2ed016 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/463ffe0287eab354a438304111041ef82d2ed016 You're receiving 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 Oct 5 10:37:05 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 05 Oct 2022 06:37:05 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Implement get/set thread label prims Message-ID: <633d5e51cbade_1eea6a5147810533@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 33600658 by Josh Meredith at 2022-10-05T10:36:56+00:00 Implement get/set thread label prims - - - - - 2 changed files: - compiler/GHC/StgToJS/Prim.hs - rts/js/mem.js Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1227,8 +1227,8 @@ genPrim prof ty op = case op of WhereFromOp -> unhandledPrimop op -- should be easily implementable with o.f.n SetThreadAllocationCounter -> unhandledPrimop op - GetThreadLabelOp -> unhandledPrimop op - LabelThreadOp -> unhandledPrimop op -- \[] [t,la,lo] -> PrimInline $ t .^ "label" |= ValExpr (JList [la, lo]) + GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] + LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ------------------------------- Vector ----------------------------------------- -- For now, vectors are unsupported on the JS backend. Simply put, they do not ===================================== rts/js/mem.js ===================================== @@ -1436,3 +1436,11 @@ function h$pext64(src_b, src_a, mask_b, mask_a) { } RETURN_UBX_TUP2(dst_b, dst_a); } + +function h$getThreadLabel(t) { + if (t.label) { + RETURN_UBX_TUP2(1, t.label); + } else { + RETURN_UBX_TUP2(0, 0); + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/33600658f33b3633a14bf6bbd0f2ac3dc97844f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/33600658f33b3633a14bf6bbd0f2ac3dc97844f0 You're receiving 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 Oct 5 13:50:41 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Wed, 05 Oct 2022 09:50:41 -0400 Subject: [Git][ghc/ghc][wip/js-staging] JS: remove Linker.Archive module Message-ID: <633d8bb1113e0_1eea6a51590144847@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 1fa90637 by doyougnu at 2022-10-05T09:50:28-04:00 JS: remove Linker.Archive module - - - - - 2 changed files: - − compiler/GHC/StgToJS/Linker/Archive.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/StgToJS/Linker/Archive.hs deleted ===================================== @@ -1,165 +0,0 @@ -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE LambdaCase #-} - ------------------------------------------------------------------------------ --- | --- Module : GHC.StgToJS.Archive --- Copyright : (c) The University of Glasgow 2001 --- License : BSD-style (see the file LICENSE) --- --- Maintainer : Sylvain Henry --- Jeffrey Young --- Luite Stegeman --- Josh Meredith --- Stability : experimental --- --- Various utilies used in the JS Linker which wrap around ar. --- ------------------------------------------------------------------------------ - -module GHC.StgToJS.Linker.Archive - ( Entry(..), Index, IndexEntry(..), Meta(..) - , writeArchive - , readMeta, readIndex - , getArchiveEntries - , getArchiveEntry - ) where - -import Prelude -import Data.ByteString (ByteString) -import Data.Word -import Control.Monad - -import GHC.Unit.Module -import GHC.Utils.Binary -import GHC.Utils.Panic -import GHC.Utils.Monad -import GHC.Settings.Constants (hiVersion) - - -type Index = [IndexEntry] - --- | An @IndexEntry@ is a payload and an offset into the archive -data IndexEntry = IndexEntry - { ieEntry :: !Entry -- ^ Entry identifier - , ieOffset :: !(Bin ByteString) -- ^ Offset in the archive - } deriving (Show) - -instance Binary IndexEntry where - put_ bh (IndexEntry a b) = do - put_ bh a - put_ bh b - get bh = IndexEntry <$> get bh <*> get bh - --- | An @Entry@ is either a module or a JavaScript source file. -data Entry - = Object !ModuleName -- ^ A Haskell Module - | JsSource !FilePath -- ^ A JS Source file - deriving (Show) - -instance Binary Entry where - put_ bh = \case - Object m -> putByte bh 0 >> put_ bh m - JsSource p -> putByte bh 1 >> put_ bh p - get bh = getByte bh >>= \case - 0 -> Object <$> get bh - _ -> JsSource <$> get bh - - -data Meta = Meta - { metaCppOptions :: [String] - } - -instance Binary Meta where - put_ bh (Meta a) = put_ bh a - get bh = Meta <$> get bh - --- | A header indicating we are in JS land. -magic :: FixedLengthEncoding Word64 -magic = FixedLengthEncoding 0x435241534a434847 -- "GHCJSARC" - --- | Write payload, entries, to @FilePath@, path, using @Meta@, meta, to --- construct the payload header. -writeArchive :: FilePath -> Meta -> [(Entry, ByteString)] -> IO () -writeArchive path meta entries = do - bh <- openBinMem (4*1024*1000) - put_ bh magic - put_ bh (show hiVersion) - - put_ bh meta - - -- forward put the index - forwardPut_ bh (put_ bh) $ do - idx <- forM entries $ \(e,bs) -> do - p <- tellBin bh - put_ bh bs - pure $ IndexEntry - { ieEntry = e - , ieOffset = p - } - pure idx - - writeBinMem bh path - -data Header = Header - { hdrMeta :: !Meta - , hdrIndex :: !Index - , hdrHandle :: !BinHandle - } - --- | Given a binary handle, retrieve the header from the archive. Note this --- function is unsafe and may panic. -getArchiveHeader :: BinHandle -> IO Header -getArchiveHeader bh = do - is_magic <- (== magic) <$> get bh - unless is_magic $ panic "getArchiveHeader: invalid magic header" - - is_correct_version <- ((== hiVersion) . read) <$> get bh - unless is_correct_version $ panic "getArchiveHeader: invalid header version" - - meta <- get bh - idx <- forwardGet bh (get bh) - pure $ Header - { hdrMeta = meta - , hdrIndex = idx - , hdrHandle = bh - } - --- | Read the meta data from an archive pointed to by 'file'. -readMeta :: FilePath -> IO Meta -readMeta file = do - bh <- readBinMem file - hdr <- getArchiveHeader bh - pure $! hdrMeta hdr - --- | Read the index from an archive pointed to by 'file'. -readIndex :: FilePath -> IO Index -readIndex file = do - bh <- readBinMem file - hdr <- getArchiveHeader bh - pure $! hdrIndex hdr - --- | Read the all payloads that satisfy the input predicate, 'pred', in the --- archive pointed to by 'hdr'. -getArchiveEntries :: Header -> (Entry -> Bool) -> IO [ByteString] -getArchiveEntries hdr pred = mapMaybeM read_entry (hdrIndex hdr) - where - bh = hdrHandle hdr - read_entry (IndexEntry e offset) - | pred e = do - seekBin bh offset - Just <$> get bh - | otherwise = pure Nothing - --- | Get a single payload by searching @IndexEntry at s in 'hdr', returns the first --- entry that satisfies the input predicate, 'pred', in the archive pointed to --- by 'hdr'. Returns Nothing if 'pred' fails for all entries. -getArchiveEntry :: Header -> (Entry -> Bool) -> IO (Maybe ByteString) -getArchiveEntry hdr pred = go (hdrIndex hdr) - where - bh = hdrHandle hdr - go = \case - (IndexEntry e offset:es) - | pred e -> seekBin bh offset >> (Just <$> get bh) - | otherwise -> go es - [] -> pure Nothing ===================================== compiler/ghc.cabal.in ===================================== @@ -666,7 +666,6 @@ Library GHC.StgToJS.Linker.Linker GHC.StgToJS.Linker.Types GHC.StgToJS.Linker.Utils - GHC.StgToJS.Linker.Archive GHC.StgToJS.Linker.Shims GHC.Stg.Unarise GHC.SysTools View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1fa9063721320cd2c2689cac7c71c3f37bead070 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1fa9063721320cd2c2689cac7c71c3f37bead070 You're receiving 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 Oct 5 14:31:41 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Wed, 05 Oct 2022 10:31:41 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Start disabling tests that use TH/interpreter Message-ID: <633d954d3375a_1eea6a51450153195@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: cab01a42 by Sylvain Henry at 2022-10-05T16:34:59+02:00 Start disabling tests that use TH/interpreter - - - - - 6 changed files: - testsuite/driver/testlib.py - testsuite/tests/codeGen/should_compile/T17904.hs - testsuite/tests/corelint/all.T - testsuite/tests/dependent/should_compile/all.T - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/driver/all.T Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -255,6 +255,8 @@ def req_dynamic_hs( name, opts ): def req_interp( name, opts ): if not config.have_interp: opts.expect = 'fail' + # JS backend doesn't provide an interpreter yet + js_skip(name, opts) def req_rts_linker( name, opts ): if not config.have_RTS_linker: ===================================== testsuite/tests/codeGen/should_compile/T17904.hs ===================================== @@ -13,8 +13,6 @@ module T17904 import GHC.Exts ( TYPE, Int (..) ) import Prelude hiding (lookup) -{-# ANN module ("HLint: ignore Eta reduce" :: String) #-} - class Hashable a where hashWithSalt :: Int -> a -> Int ===================================== testsuite/tests/corelint/all.T ===================================== @@ -1,6 +1,6 @@ test('T21115', normal, compile_fail, ['']) -test('T21115b', normal, compile_fail, ['-dsuppress-uniques -dsuppress-all']) +test('T21115b', req_th, compile_fail, ['-dsuppress-uniques -dsuppress-all']) test('T21152', normal, compile, ['-g3']) ## Tests which use the GHC API. ===================================== testsuite/tests/dependent/should_compile/all.T ===================================== @@ -2,9 +2,9 @@ test('Dep1', only_ways(['normal']), compile, ['']) test('Dep2', only_ways(['normal']), compile, ['']) test('Dep3', only_ways(['normal']), compile, ['']) test('KindEqualities', only_ways(['normal']), compile, ['']) -test('KindEqualities2', only_ways(['normal']), compile, ['']) -test('Rae31', only_ways(['normal']), compile, ['']) -test('RAE_T32b', only_ways(['normal']), compile, ['']) +test('KindEqualities2', [req_th,only_ways(['normal'])], compile, ['']) +test('Rae31', [req_th,only_ways(['normal'])], compile, ['']) +test('RAE_T32b', [req_th,only_ways(['normal'])], compile, ['']) test('KindLevels', normal, compile, ['']) test('RaeBlogPost', normal, compile, ['']) test('mkGADTVars', normal, compile, ['']) @@ -44,7 +44,7 @@ test('T12742', normal, compile, ['']) # (1) Use -fexternal-interpreter, or # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. -test('T13910', [omit_ways(['profasm'])], compile, ['']) +test('T13910', [req_th, omit_ways(['profasm'])], compile, ['']) test('T13938', [req_th, extra_files(['T13938a.hs'])], makefile_test, ['T13938']) test('T14556', normal, compile, ['']) test('T14720', normal, compile, ['']) ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -128,7 +128,7 @@ test('T17339', normal, compile, ['-ddump-simpl -dsuppress-idinfo -dno-typeable-binds']) test('T17880', normal, compile, ['']) test('T18055', normal, compile, ['']) -test('T18321', normal, compile, ['']) +test('T18321', req_th, compile, ['']) test('T18914', normal, compile, ['']) # We need to find derived instances in the Tc trace dump. # They are printed in tcDeriv beginning with "rnd" line ===================================== testsuite/tests/driver/all.T ===================================== @@ -291,7 +291,7 @@ test('T17786', unless(opsys('mingw32'), skip), makefile_test, []) test('T18369', normal, compile, ['-O']) test('T21682', normal, compile_fail, ['-Werror=unrecognised-warning-flags -Wfoo']) test('FullGHCVersion', normal, compile_and_run, ['-package ghc-boot']) -test('OneShotTH', normal, makefile_test, []) +test('OneShotTH', req_th, makefile_test, []) test('T17481', normal, makefile_test, []) test('T20084', normal, makefile_test, []) test('RunMode', extra_files(['RunMode/Test.hs']), run_command, ['{compiler} --run -iRunMode/ -ignore-dot-ghci RunMode.hs -- hello']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cab01a427b87bf7391336a62948d2f01d2a2f094 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cab01a427b87bf7391336a62948d2f01d2a2f094 You're receiving 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 Oct 5 15:41:00 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 05 Oct 2022 11:41:00 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/opt-getlevity Message-ID: <633da58c14547_1eea6a5148c17013a@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/opt-getlevity at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/opt-getlevity You're receiving 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 Oct 5 15:42:21 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 05 Oct 2022 11:42:21 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Add flagged bounds checking to JS primops Message-ID: <633da5dda32dd_1eea6a51464172244@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 55473c85 by Josh Meredith at 2022-10-05T15:41:31+00:00 Add flagged bounds checking to JS primops - - - - - 4 changed files: - compiler/GHC/Driver/Config/StgToJS.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/StgToJS/Types.hs Changes: ===================================== compiler/GHC/Driver/Config/StgToJS.hs ===================================== @@ -22,6 +22,7 @@ initStgToJSConfig dflags = StgToJSConfig , csInlineAlloc = False , csTraceRts = False , csAssertRts = False + , csBoundsCheck = gopt Opt_DoBoundsChecking dflags , csDebugAlloc = False , csTraceForeign = False , csProf = ways dflags `hasWay` WayProf ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -1038,7 +1038,8 @@ genPrimOp :: ExprCtx -> PrimOp -> [StgArg] -> Type -> G (JStat, ExprResult) genPrimOp ctx op args t = do as <- concatMapM genArg args prof <- csProf <$> getSettings + bound <- csBoundsCheck <$> getSettings -- fixme: should we preserve/check the primreps? - return $ case genPrim prof t op (concatMap typex_expr $ ctxTarget ctx) as of + return $ case genPrim prof bound t op (concatMap typex_expr $ ctxTarget ctx) as of PrimInline s -> (s, ExprInline Nothing) PRPrimCall s -> (s, ExprCont) ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -35,12 +35,13 @@ import Data.Maybe genPrim :: Bool -- ^ Profiling (cost-centres) enabled + -> Bool -- ^ Array bounds-checking enabled -> Type -> PrimOp -- ^ the primitive operation -> [JExpr] -- ^ where to store the result -> [JExpr] -- ^ arguments -> PrimRes -genPrim prof ty op = case op of +genPrim prof bound ty op = case op of CharGtOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .>. y) CharGeOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .>=. y) CharEqOp -> \[r] [x,y] -> PrimInline $ r |= if10 (x .===. y) @@ -219,51 +220,51 @@ genPrim prof ty op = case op of Int32ToIntOp -> \[r] [x] -> PrimInline $ r |= x IntToInt32Op -> \[r] [x] -> PrimInline $ r |= x - Int32NegOp -> \rs xs -> genPrim prof ty IntNegOp rs xs - Int32AddOp -> \rs xs -> genPrim prof ty IntAddOp rs xs - Int32SubOp -> \rs xs -> genPrim prof ty IntSubOp rs xs - Int32MulOp -> \rs xs -> genPrim prof ty IntMulOp rs xs - Int32QuotOp -> \rs xs -> genPrim prof ty IntQuotOp rs xs - Int32RemOp -> \rs xs -> genPrim prof ty IntRemOp rs xs - Int32QuotRemOp -> \rs xs -> genPrim prof ty IntQuotRemOp rs xs - - Int32EqOp -> \rs xs -> genPrim prof ty IntEqOp rs xs - Int32GeOp -> \rs xs -> genPrim prof ty IntGeOp rs xs - Int32GtOp -> \rs xs -> genPrim prof ty IntGtOp rs xs - Int32LeOp -> \rs xs -> genPrim prof ty IntLeOp rs xs - Int32LtOp -> \rs xs -> genPrim prof ty IntLtOp rs xs - Int32NeOp -> \rs xs -> genPrim prof ty IntNeOp rs xs - - Int32SraOp -> \rs xs -> genPrim prof ty IntSraOp rs xs - Int32SrlOp -> \rs xs -> genPrim prof ty IntSrlOp rs xs - Int32SllOp -> \rs xs -> genPrim prof ty IntSllOp rs xs + Int32NegOp -> \rs xs -> genPrim prof bound ty IntNegOp rs xs + Int32AddOp -> \rs xs -> genPrim prof bound ty IntAddOp rs xs + Int32SubOp -> \rs xs -> genPrim prof bound ty IntSubOp rs xs + Int32MulOp -> \rs xs -> genPrim prof bound ty IntMulOp rs xs + Int32QuotOp -> \rs xs -> genPrim prof bound ty IntQuotOp rs xs + Int32RemOp -> \rs xs -> genPrim prof bound ty IntRemOp rs xs + Int32QuotRemOp -> \rs xs -> genPrim prof bound ty IntQuotRemOp rs xs + + Int32EqOp -> \rs xs -> genPrim prof bound ty IntEqOp rs xs + Int32GeOp -> \rs xs -> genPrim prof bound ty IntGeOp rs xs + Int32GtOp -> \rs xs -> genPrim prof bound ty IntGtOp rs xs + Int32LeOp -> \rs xs -> genPrim prof bound ty IntLeOp rs xs + Int32LtOp -> \rs xs -> genPrim prof bound ty IntLtOp rs xs + Int32NeOp -> \rs xs -> genPrim prof bound ty IntNeOp rs xs + + Int32SraOp -> \rs xs -> genPrim prof bound ty IntSraOp rs xs + Int32SrlOp -> \rs xs -> genPrim prof bound ty IntSrlOp rs xs + Int32SllOp -> \rs xs -> genPrim prof bound ty IntSllOp rs xs ------------------------------ Word32 ------------------------------------------- Word32ToWordOp -> \[r] [x] -> PrimInline $ r |= x WordToWord32Op -> \[r] [x] -> PrimInline $ r |= x - Word32AddOp -> \rs xs -> genPrim prof ty WordAddOp rs xs - Word32SubOp -> \rs xs -> genPrim prof ty WordSubOp rs xs - Word32MulOp -> \rs xs -> genPrim prof ty WordMulOp rs xs - Word32QuotOp -> \rs xs -> genPrim prof ty WordQuotOp rs xs - Word32RemOp -> \rs xs -> genPrim prof ty WordRemOp rs xs - Word32QuotRemOp -> \rs xs -> genPrim prof ty WordQuotRemOp rs xs + Word32AddOp -> \rs xs -> genPrim prof bound ty WordAddOp rs xs + Word32SubOp -> \rs xs -> genPrim prof bound ty WordSubOp rs xs + Word32MulOp -> \rs xs -> genPrim prof bound ty WordMulOp rs xs + Word32QuotOp -> \rs xs -> genPrim prof bound ty WordQuotOp rs xs + Word32RemOp -> \rs xs -> genPrim prof bound ty WordRemOp rs xs + Word32QuotRemOp -> \rs xs -> genPrim prof bound ty WordQuotRemOp rs xs - Word32EqOp -> \rs xs -> genPrim prof ty WordEqOp rs xs - Word32GeOp -> \rs xs -> genPrim prof ty WordGeOp rs xs - Word32GtOp -> \rs xs -> genPrim prof ty WordGtOp rs xs - Word32LeOp -> \rs xs -> genPrim prof ty WordLeOp rs xs - Word32LtOp -> \rs xs -> genPrim prof ty WordLtOp rs xs - Word32NeOp -> \rs xs -> genPrim prof ty WordNeOp rs xs + Word32EqOp -> \rs xs -> genPrim prof bound ty WordEqOp rs xs + Word32GeOp -> \rs xs -> genPrim prof bound ty WordGeOp rs xs + Word32GtOp -> \rs xs -> genPrim prof bound ty WordGtOp rs xs + Word32LeOp -> \rs xs -> genPrim prof bound ty WordLeOp rs xs + Word32LtOp -> \rs xs -> genPrim prof bound ty WordLtOp rs xs + Word32NeOp -> \rs xs -> genPrim prof bound ty WordNeOp rs xs - Word32AndOp -> \rs xs -> genPrim prof ty WordAndOp rs xs - Word32OrOp -> \rs xs -> genPrim prof ty WordOrOp rs xs - Word32XorOp -> \rs xs -> genPrim prof ty WordXorOp rs xs - Word32NotOp -> \rs xs -> genPrim prof ty WordNotOp rs xs + Word32AndOp -> \rs xs -> genPrim prof bound ty WordAndOp rs xs + Word32OrOp -> \rs xs -> genPrim prof bound ty WordOrOp rs xs + Word32XorOp -> \rs xs -> genPrim prof bound ty WordXorOp rs xs + Word32NotOp -> \rs xs -> genPrim prof bound ty WordNotOp rs xs - Word32SllOp -> \rs xs -> genPrim prof ty WordSllOp rs xs - Word32SrlOp -> \rs xs -> genPrim prof ty WordSrlOp rs xs + Word32SllOp -> \rs xs -> genPrim prof bound ty WordSllOp rs xs + Word32SrlOp -> \rs xs -> genPrim prof bound ty WordSrlOp rs xs ------------------------------ Int64 -------------------------------------------- @@ -402,17 +403,17 @@ genPrim prof ty op = case op of PopCnt32Op -> \[r] [x] -> PrimInline $ r |= app "h$popCnt32" [x] PopCnt64Op -> \[r] [x1,x2] -> PrimInline $ r |= app "h$popCnt64" [x1,x2] - PopCntOp -> \[r] [x] -> genPrim prof ty PopCnt32Op [r] [x] + PopCntOp -> \[r] [x] -> genPrim prof bound ty PopCnt32Op [r] [x] Pdep8Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pdep8" [s,m] Pdep16Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pdep16" [s,m] Pdep32Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pdep32" [s,m] Pdep64Op -> \[ra,rb] [sa,sb,ma,mb] -> PrimInline $ appT [ra,rb] "h$pdep64" [sa,sb,ma,mb] - PdepOp -> \rs xs -> genPrim prof ty Pdep32Op rs xs + PdepOp -> \rs xs -> genPrim prof bound ty Pdep32Op rs xs Pext8Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pext8" [s,m] Pext16Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pext16" [s,m] Pext32Op -> \[r] [s,m] -> PrimInline $ r |= app "h$pext32" [s,m] Pext64Op -> \[ra,rb] [sa,sb,ma,mb] -> PrimInline $ appT [ra,rb] "h$pext64" [sa,sb,ma,mb] - PextOp -> \rs xs -> genPrim prof ty Pext32Op rs xs + PextOp -> \rs xs -> genPrim prof bound ty Pext32Op rs xs ClzOp -> \[r] [x] -> PrimInline $ r |= app "h$clz32" [x] Clz8Op -> \[r] [x] -> PrimInline $ r |= app "h$clz8" [x] @@ -434,9 +435,9 @@ genPrim prof ty op = case op of `BOr` ((BAnd x (Int 0xFF0000)) .>>. (Int 8)) `BOr` (x .>>>. (Int 24))) BSwap64Op -> \[r1,r2] [x,y] -> PrimInline $ appT [r1,r2] "h$bswap64" [x,y] - BSwapOp -> \[r] [x] -> genPrim prof ty BSwap32Op [r] [x] + BSwapOp -> \[r] [x] -> genPrim prof bound ty BSwap32Op [r] [x] - BRevOp -> \[r] [w] -> genPrim prof ty BRev32Op [r] [w] + BRevOp -> \[r] [w] -> genPrim prof bound ty BRev32Op [r] [w] BRev8Op -> \[r] [w] -> PrimInline $ r |= (app "h$reverseWord" [w] .>>>. 24) BRev16Op -> \[r] [w] -> PrimInline $ r |= (app "h$reverseWord" [w] .>>>. 16) BRev32Op -> \[r] [w] -> PrimInline $ r |= app "h$reverseWord" [w] @@ -529,11 +530,11 @@ genPrim prof ty op = case op of ------------------------------ Arrays ------------------------------------------- NewArrayOp -> \[r] [l,e] -> PrimInline (newArray r l e) - ReadArrayOp -> \[r] [a,i] -> PrimInline $ r |= a .! i - WriteArrayOp -> \[] [a,i,v] -> PrimInline $ a .! i |= v + ReadArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) + WriteArrayOp -> \[] [a,i,v] -> PrimInline $ boundsChecked bound a i (a .! i |= v) SizeofArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" SizeofMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" - IndexArrayOp -> \[r] [a,i] -> PrimInline $ r |= a .! i + IndexArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) UnsafeFreezeArrayOp -> \[r] [a] -> PrimInline $ r |= a UnsafeThawArrayOp -> \[r] [a] -> PrimInline $ r |= a CopyArrayOp -> \[] [a,o1,ma,o2,n] -> @@ -543,7 +544,7 @@ genPrim prof ty op = case op of ] CopyMutableArrayOp -> \[] [a1,o1,a2,o2,n] -> PrimInline $ appS "h$copyMutableArray" [a1,o1,a2,o2,n] CloneArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] - CloneMutableArrayOp -> \[r] [a,start,n] -> genPrim prof ty CloneArrayOp [r] [a,start,n] + CloneMutableArrayOp -> \[r] [a,start,n] -> genPrim prof bound ty CloneArrayOp [r] [a,start,n] FreezeArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] ThawArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] CasArrayOp -> \[s,o] [a,i,old,new] -> PrimInline $ @@ -562,11 +563,11 @@ genPrim prof ty op = case op of ------------------------------ Small Arrays ------------------------------------- NewSmallArrayOp -> \[a] [n,e] -> PrimInline $ a |= app "h$newArray" [n,e] - ReadSmallArrayOp -> \[r] [a,i] -> PrimInline $ r |= a .! i - WriteSmallArrayOp -> \[] [a,i,e] -> PrimInline $ a .! i |= e + ReadSmallArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) + WriteSmallArrayOp -> \[] [a,i,e] -> PrimInline $ boundsChecked bound a i (a .! i |= e) SizeofSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" SizeofSmallMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" - IndexSmallArrayOp -> \[r] [a,i] -> PrimInline $ r |= a .! i + IndexSmallArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) UnsafeFreezeSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a UnsafeThawSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a CopySmallArrayOp -> \[] [s,si,d,di,n] -> PrimInline $ @@ -610,12 +611,12 @@ genPrim prof ty op = case op of SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i - IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i - IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i - IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i + IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i + IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i + IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i + IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u32 a i IndexByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline $ jVar \t -> mconcat + PrimInline . boundsChecked bound a i $ jVar \t -> mconcat [ t |= a .^ "arr" , ifBlockS (t .&&. t .! (i .<<. two_)) [ r1 |= t .! (i .<<. two_) .! zero_ @@ -626,33 +627,33 @@ genPrim prof ty op = case op of ] ] - IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= read_f32 a i - IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= read_f64 a i + IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_f32 a i + IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_f64 a i IndexByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= read_i8 a i - IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= read_i16 a i - IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i - IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ mconcat + IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i + IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i16 a i + IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i + IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a i $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i - IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= read_u16 a i - IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i - IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ mconcat + IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i + IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u16 a i + IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u32 a i + IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a i $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i - ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i - ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i - ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i + ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i + ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i + ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i + ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u32 a i ReadByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline $ jVar \x -> mconcat + PrimInline . boundsChecked bound a i $ jVar \x -> mconcat [ x |= i .<<. two_ , ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ @@ -660,53 +661,53 @@ genPrim prof ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ r |= read_f32 a i - ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ r |= read_f64 a i + ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_f32 a i + ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_f64 a i ReadByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ r |= read_i8 a i - ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ r |= read_i16 a i - ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ r |= read_i32 a i + ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i + ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i16 a i + ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i32 a i ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ r |= read_u8 a i - ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ r |= read_u16 a i - ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ r |= read_u32 a i + ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i + ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u16 a i + ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u32 a i ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline $ write_u8 a i e - WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline $ write_i32 a i e - WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline $ write_i32 a i e - WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline $ write_u32 a i e + WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e + WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i32 a i e + WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i32 a i e + WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u32 a i e WriteByteArrayOp_Addr -> \[] [a,i,e1,e2] -> - PrimInline $ mconcat + PrimInline . boundsChecked bound a i $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline $ write_f32 a i e - WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline $ write_f64 a i e - WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ write_i32 a i e2 + WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_f32 a i e + WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_f64 a i e + WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a i $ write_i32 a i e2 - WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline $ write_i8 a i e - WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline $ write_i16 a i e - WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline $ write_i32 a i e + WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i8 a i e + WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i16 a i e + WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i32 a i e WriteByteArrayOp_Int64 -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ write_i32 a (Add (i .<<. one_) one_) e1 , write_u32 a (i .<<. one_) e2 ] - WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline $ write_u8 a i e - WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline $ write_u16 a i e - WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline $ write_u32 a i e + WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e + WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u16 a i e + WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u32 a i e WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> PrimInline $ mconcat [ write_u32 a (Add (i .<<. one_) one_) h @@ -720,10 +721,10 @@ genPrim prof ty op = case op of [ write_u8 a2 (Add i o2) (read_u8 a1 (Add i o1)) , postDecrS i ] - CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof ty CopyByteArrayOp [] xs - CopyByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof ty CopyByteArrayOp [] xs - CopyMutableByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof ty CopyByteArrayOp [] xs - CopyAddrToByteArrayOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof ty CopyByteArrayOp [] xs + CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyMutableByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyAddrToByteArrayOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs SetByteArrayOp -> \[] [a,o,n,v] -> PrimInline $ loopBlockS zero_ (.<. n) \i -> @@ -756,48 +757,50 @@ genPrim prof ty op = case op of ------------------------------- Addr Indexing: Unboxed Arrays ------------------- - IndexOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) - IndexOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) - IndexOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) - IndexOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) + IndexOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) IndexOffAddrOp_Addr -> \[ca,co] [a,o,i] -> - PrimInline $ ifBlockS (a .^ "arr " .&&. a .^ "arr" .! (i .<<. two_)) + PrimInline . boundsChecked bound (a .^ "arr") (off32 o i) + $ ifBlockS (a .^ "arr " .&&. a .^ "arr" .! (i .<<. two_)) [ ca |= a .^ "arr" .! (off32 o i) .! zero_ , co |= a .^ "arr" .! (off32 o i) .! one_ ] [ ca |= null_ , co |= zero_ ] - IndexOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f32 a (off32 o i) - IndexOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f64 a (off64 o i) - IndexOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat + IndexOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_f32 a (off32 o i) + IndexOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off64 o i) $ c |= read_boff_f64 a (off64 o i) + IndexOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ mconcat [ c1 |= var "h$stablePtrBuf" , c2 |= read_boff_i32 a (off32 o i) ] - IndexOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i8 a (off8 o i) - IndexOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i16 a (off16 o i) - IndexOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_i8 a (off8 o i) + IndexOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ c |= read_boff_i16 a (off16 o i) + IndexOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) IndexOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add (off64 o i) (Int 4)) , l |= read_boff_u32 a (off64 o i) ] - IndexOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) - IndexOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u16 a (off16 o i) - IndexOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) + IndexOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ c |= read_boff_u16 a (off16 o i) + IndexOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) IndexOffAddrOp_Word64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat [ h |= read_boff_u32 a (Add (off64 o i) (Int 4)) , l |= read_boff_u32 a (off64 o i) ] - ReadOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u8 a (off8 o i) - ReadOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) - ReadOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_i32 a (off32 o i) - ReadOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_u32 a (off32 o i) + ReadOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) + ReadOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) ReadOffAddrOp_Addr -> \[c1,c2] [a,o,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , ifBlockS (a .^ "arr" .&&. a .^ "arr" .! (Add o x)) + , boundsChecked bound (a .^ "arr") (Add o x) $ + ifBlockS (a .^ "arr" .&&. a .^ "arr" .! (Add o x)) [ c1 |= a .^ "arr" .! (Add o x) .! zero_ , c2 |= a .^ "arr" .! (Add o x) .! one_ ] @@ -805,51 +808,52 @@ genPrim prof ty op = case op of , c2 |= zero_ ] ] - ReadOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f32 a (off32 o i) - ReadOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline $ c |= read_boff_f64 a (off64 o i) - ReadOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat + ReadOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_f32 a (off32 o i) + ReadOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off64 o i) $ c |= read_boff_f64 a (off64 o i) + ReadOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ mconcat [ c1 |= var "h$stablePtrBuf" , c2 |= read_boff_u32 a (off32 o i) ] - ReadOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i8 a (off8 o i) - ReadOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i16 a (off16 o i) - ReadOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ AssignStat c $ read_boff_i8 a (off8 o i) + ReadOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ AssignStat c $ read_boff_i16 a (off16 o i) + ReadOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ AssignStat c $ read_boff_i32 a (off32 o i) ReadOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ mconcat [ h |= read_i32 a (Add (off64 o i) (Int 4)) , l |= read_u32 a (off64 o i) ] - ReadOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_u8 a (off8 o i) - ReadOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_u16 a (off16 o i) - ReadOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline $ AssignStat c $ read_boff_i32 a (off32 o i) + ReadOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ AssignStat c $ read_boff_u8 a (off8 o i) + ReadOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ AssignStat c $ read_boff_u16 a (off16 o i) + ReadOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ AssignStat c $ read_boff_i32 a (off32 o i) ReadOffAddrOp_Word64 -> \[c1,c2] [a,o,i] -> PrimInline $ mconcat [ c1 |= read_boff_i32 a (Add (off64 o i) (Int 4)) , c2 |= read_boff_i32 a (off64 o i) ] - WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v - WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v + WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v WriteOffAddrOp_Addr -> \[] [a,o,i,va,vo] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , AssignStat (a .^ "arr" .! (off32 o i)) $ ValExpr (JList [va, vo]) + , boundsChecked bound (a .^ "arr") (off32 o i) $ + AssignStat (a .^ "arr" .! (off32 o i)) $ ValExpr (JList [va, vo]) ] - WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline $ write_boff_f32 a (off32 o i) v - WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline $ write_boff_f64 a (off64 o i) v - WriteOffAddrOp_StablePtr -> \[] [a,o,i,_v1,v2] -> PrimInline $ write_boff_u32 a (off32 o i) v2 - WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i8 a (off8 o i) v - WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i16 a (off16 o i) v - WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Int64 -> \[] [a,o,i,v1,v2] -> PrimInline $ mconcat + WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_f32 a (off32 o i) v + WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off64 o i) $ write_boff_f64 a (off64 o i) v + WriteOffAddrOp_StablePtr -> \[] [a,o,i,_v1,v2] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v2 + WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_i8 a (off8 o i) v + WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off16 o i) $ write_boff_i16 a (off16 o i) v + WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Int64 -> \[] [a,o,i,v1,v2] -> PrimInline . boundsChecked bound a (off64 o i) $ mconcat [ write_boff_i32 a (Add (off64 o i) (Int 4)) v1 , write_boff_u32 a (off64 o i) v2 ] - WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v - WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u16 a (off16 o i) v - WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v - WriteOffAddrOp_Word64 -> \[] [a,o,i,v1,v2] -> PrimInline $ mconcat + WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off16 o i) $ write_boff_u16 a (off16 o i) v + WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v + WriteOffAddrOp_Word64 -> \[] [a,o,i,v1,v2] -> PrimInline . boundsChecked bound a (off64 o i) $ mconcat [ write_boff_u32 a (Add (off64 o i) (Int 4)) v1 , write_boff_u32 a (off64 o i) v2 ] @@ -923,6 +927,8 @@ genPrim prof ty op = case op of NoDuplicateOp -> \[] [] -> PrimInline mempty -- don't need to do anything as long as we have eager blackholing ThreadStatusOp -> \[stat,cap,locked] [tid] -> PrimInline $ appT [stat, cap, locked] "h$threadStatus" [tid] ListThreadsOp -> \[r] [] -> PrimInline $ r |= var "h$threads" + GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] + LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ------------------------------- Weak Pointers ----------------------------------- @@ -1026,110 +1032,115 @@ genPrim prof ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , ifS (a .^ "arr" .&&. a .^ "arr" .! x) + , boundsChecked bound (a .^ "arr") x $ + ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= read_boff_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= read_boff_f64 a i + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_f64 a i IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u32 a i IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u32 a i - ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , ifS (a .^ "arr" .&&. a .^ "arr" .! x) + , boundsChecked bound (a .^ "arr") x $ + ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ r |= read_boff_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ r |= read_boff_f64 a i + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_f64 a i ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u32 a i - WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline $ write_boff_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i8 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i32 a i e WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) + , boundsChecked bound (a .^ "arr") (i .<<. two_) $ + a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline $ write_boff_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline $ write_boff_f64 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline $ write_boff_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline $ write_boff_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a i $ write_boff_i32 a i e2 + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i32 a i e WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i -- then write the higher 4 bytes to i+4 - PrimInline $ mconcat [ write_boff_i32 a (Add i (Int 4)) h + PrimInline . boundsChecked bound a i + $ mconcat [ write_boff_i32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline $ write_boff_u16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_u32 a i e WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline $ mconcat [ write_boff_u32 a (Add i (Int 4)) h + PrimInline . boundsChecked bound a i + $ mconcat [ write_boff_u32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_u32 a i e - CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i8 write_i8 r a i old new - CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i16 write_i16 r a i old new - CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i8 write_i8 r a i old new + CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i16 write_i16 r a i old new + CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline $ + CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsChecked bound a (Add (i .<<. one_) one_) $ jVar \t_h t_l -> mconcat [ t_h |= read_i32 a (Add (i .<<. one_) one_) , t_l |= read_u32 a (i .<<. one_) , r_h |= t_h @@ -1227,8 +1238,6 @@ genPrim prof ty op = case op of WhereFromOp -> unhandledPrimop op -- should be easily implementable with o.f.n SetThreadAllocationCounter -> unhandledPrimop op - GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] - LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ------------------------------- Vector ----------------------------------------- -- For now, vectors are unsupported on the JS backend. Simply put, they do not @@ -1458,6 +1467,16 @@ newByteArray :: JExpr -> JExpr -> JStat newByteArray tgt len = tgt |= app "h$newByteArray" [len] +boundsChecked :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsChecked False _ _ r = r +boundsChecked True xs i r = + ifS ((i .<. xs .^ "length") .&&. (i .>=. zero_)) + r + (returnS $ app "h$throwJSException" [ValExpr $ JStr "Array out of bounds"]) -- e|0 (32 bit signed integer truncation) required because of JS numbers. e|0 -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. ===================================== compiler/GHC/StgToJS/Types.hs ===================================== @@ -86,6 +86,7 @@ data StgToJSConfig = StgToJSConfig , csInlineAlloc :: !Bool , csTraceRts :: !Bool , csAssertRts :: !Bool + , csBoundsCheck :: !Bool , csDebugAlloc :: !Bool , csTraceForeign :: !Bool , csProf :: !Bool -- ^ Profiling enabled View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55473c85f4556499845ace1515bc3eeeac3d533a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55473c85f4556499845ace1515bc3eeeac3d533a You're receiving 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 Oct 5 15:45:57 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 05 Oct 2022 11:45:57 -0400 Subject: [Git][ghc/ghc][wip/andreask/opt-getlevity] Optimize getLevity. Message-ID: <633da6b552b1d_1eea6a5143c17248c@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/opt-getlevity at Glasgow Haskell Compiler / GHC Commits: 16aba966 by Andreas Klebinger at 2022-10-05T17:42:15+02:00 Optimize getLevity. Avoid the intermediate data structures allocated by splitTyConApp. This avoids ~0.5% of allocations for a build using -O2. Fixes #22254 - - - - - 1 changed file: - compiler/GHC/Core/Type.hs Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2541,8 +2541,8 @@ getRuntimeRep ty getLevity_maybe :: HasDebugCallStack => Type -> Maybe Type getLevity_maybe ty | Just rep <- getRuntimeRep_maybe ty - , Just (tc, [lev]) <- splitTyConApp_maybe rep - , tc == boxedRepDataConTyCon + , TyConApp tc [lev] <- coreFullView rep + , boxedRepDataConTyCon == tc = Just lev | otherwise = Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16aba9660c2e3a00ae912d7d54b86f741bdcb8f6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/16aba9660c2e3a00ae912d7d54b86f741bdcb8f6 You're receiving 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 Oct 5 16:09:40 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 05 Oct 2022 12:09:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: chore: extend `.editorconfig` for C files Message-ID: <633dac446d0ae_1eea6a514641877f1@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - bf80c106 by Cheng Shao at 2022-10-05T12:09:23-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 7 changed files: - .editorconfig - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - libraries/base/changelog.md - libraries/base/tools/ucd2haskell/ucd.sh - rts/include/Stg.h Changes: ===================================== .editorconfig ===================================== @@ -12,3 +12,7 @@ end_of_line = lf [Makefile] indent_style = tab + +[*.c] +indent_style = space +indent_size = 2 ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -129,6 +129,8 @@ Runtime system ``(<=)`` instead of ``compare`` per CLC proposal: https://github.com/haskell/core-libraries-committee/issues/24 +- Updated to `Unicode 15.0.0 `_. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/exts/pattern_synonyms.rst ===================================== @@ -524,9 +524,9 @@ Pragmas for pattern synonyms ---------------------------- The :ref:`inlinable-pragma`, :ref:`inline-pragma` and :ref:`noinline-pragma` are supported for pattern -synonyms. For example: :: +synonyms as of GHC 9.2. For example: :: - patternInlinablePattern x = [x] + pattern InlinablePattern x = [x] {-# INLINABLE InlinablePattern #-} pattern InlinedPattern x = [x] {-# INLINE InlinedPattern #-} ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -185,8 +185,7 @@ compareByteArraysFromBeginning (ByteArray ba1#) (ByteArray ba2#) (I# n#) -- | Do two byte arrays share the same pointer? sameByteArray :: ByteArray# -> ByteArray# -> Bool sameByteArray ba1 ba2 = - case reallyUnsafePtrEquality# (unsafeCoerce# ba1 :: ()) (unsafeCoerce# ba2 :: ()) of - r -> isTrue# r + case sameByteArray# ba1 ba2 of r -> isTrue# r -- | @since 4.17.0.0 instance Eq ByteArray where ===================================== libraries/base/changelog.md ===================================== @@ -29,7 +29,7 @@ is now exported from `Prelude`. See [CLC #50](https://github.com/haskell/core-libraries-committee/issues/50) for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) - * Update to Unicode 15.0.0. + * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,11 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ - ucd/DerivedCoreProperties.txt:e3eddd7d469cd1b0feed7528defad1a1cc7c6a9ceb0ae4446a6d10921ed2e7bc \ - ucd/DerivedNormalizationProps.txt:b2c444c20730b097787fdf50bd7d6dd3fc5256ab8084f5b35b11c8776eca674c \ - ucd/UnicodeData.txt:36018e68657fdcb3485f636630ffe8c8532e01c977703d2803f5b89d6c5feafb \ - ucd/PropList.txt:6bddfdb850417a5bee6deff19290fd1b138589909afb50f5a049f343bf2c6722 \ - ucd/extracted/DerivedCombiningClass.txt:12b0c3af9b600b49488d66545a3e7844ea980809627201bf9afeebe1c9f16f4e" + ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -39,10 +35,10 @@ download_file() { if test "$__checksum" != "$new_checksum" then echo "sha256sum of the downloaded __file $__file " - echo " [$new_checksum] does not match the expected __checksum [$__checksum]" + echo " [$new_checksum] does not match the expected checksum [$__checksum]" exit 1 else - echo "$__file __checksum ok" + echo "$__file checksum ok" fi fi } ===================================== rts/include/Stg.h ===================================== @@ -263,8 +263,8 @@ typedef StgFunPtr F_; #define EB_(X) extern const char X[] #define IB_(X) static const char X[] /* static (non-heap) closures (requires alignment for pointer tagging): */ -#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) -#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) +#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) /* writable data (does not require alignment): */ #define ERW_(X) extern StgWordArray (X) #define IRW_(X) static StgWordArray (X) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/098f3df749200dd96f8c7be098ff9a839633a2bf...bf80c1065da8e3cc578557de5816ae22767f2f80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/098f3df749200dd96f8c7be098ff9a839633a2bf...bf80c1065da8e3cc578557de5816ae22767f2f80 You're receiving 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 Oct 5 18:30:14 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Wed, 05 Oct 2022 14:30:14 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] 3 commits: convo with Cheng, won't compile Message-ID: <633dcd36b049e_1eea6a514282050bb@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: 5697b10a by Norman Ramsey at 2022-10-05T10:41:32-04:00 convo with Cheng, won't compile - - - - - 88ce88a4 by Norman Ramsey at 2022-10-05T13:14:46-04:00 started migrating to WasmExpr - - - - - 32129de7 by Norman Ramsey at 2022-10-05T14:29:05-04:00 change prototype to use `WasmExpr bool t` with universally quantified stack - - - - - 2 changed files: - compiler/GHC/Wasm/IR.hs - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/IR.hs ===================================== @@ -134,10 +134,6 @@ data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where WasmLocalGet :: WasmTypeTag t -> Int -> WasmIR bool pre (t : pre) WasmLocalSet :: WasmTypeTag t -> Int -> WasmIR bool (t : pre) pre - WasmLift :: (pre' ~ (t : pre), post' ~ (t : post)) => - WasmTypeTag t -> WasmIR bool pre post -> WasmIR bool pre' post' - - data BrTableInterval ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -7,21 +7,39 @@ module GHC.Wasm.Tx ( tx , CG(..) + , WasmExpr(..) ) + where import GHC.Prelude import Data.Type.Equality ---import Data.Kind import qualified GHC.Cmm.Type as CT import GHC.Cmm.Expr ---import GHC.Data.FastString ---import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Wasm.IR +---------------------------------------------------------------- + +newtype WasmExpr bool t = + WasmExpr (forall pre . WasmIR bool pre (t : pre)) + +apply1 :: (forall stack . WasmIR bool (t : stack) (t' : stack)) + -> WasmExpr bool t + -> WasmExpr bool t' +apply1 operator (WasmExpr code) = WasmExpr (code <> operator) + +apply2 :: (forall stack . WasmIR bool (t2 : t1 : stack) (t : stack)) + -> WasmExpr bool t1 + -> WasmExpr bool t2 + -> WasmExpr bool t +apply2 operator (WasmExpr code1) (WasmExpr code2) = + WasmExpr (code1 <> code2 <> operator) + +---------------------------------------------------------------- + class Monad (codegen bool) => CG bool codegen where -- platformWordSize :: m Int -- asType :: WasmTypeTag t -> m () -- check that type is consistent @@ -29,65 +47,90 @@ class Monad (codegen bool) => CG bool codegen where -- asInt :: WasmTypeTag t -> m () -- insist on the platofrm integer type booleanWasmTypeTag :: codegen bool (WasmTypeTag bool) + + tx :: CG bool codegen - => CmmExpr - -> (forall t . WasmTypeTag t -> WasmIR bool '[] (t : '[]) -> codegen bool r) - -> codegen bool r - -- combines type checking and translation + => CmmExpr + -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) + -> codegen bool r + -- combines translation with some type checking + tx expr k = case expr of - CmmLit (CmmInt n w) -> withIntWidthTag w $ \tag -> k tag (WasmInt tag n) - CmmLit (CmmFloat x w) -> withFloatWidthTag w $ \tag -> k tag (WasmFloat tag x) + CmmLit (CmmInt n w) -> wasmNullaryInt w (flip WasmInt n) k + CmmLit (CmmFloat x w) -> wasmNullaryFloat w (flip WasmFloat x) k + + CmmMachOp (MO_Not w) es -> wasmUnary w es WasmNot k CmmMachOp (MO_Add w) es -> wasmBinary w es WasmAdd k CmmMachOp (MO_Sub w) es -> wasmBinary w es WasmSub k CmmMachOp (MO_S_Ge w) es -> wasmCompare w es WasmS_Ge k - CmmMachOp (MO_Not w) es -> wasmUnary w es WasmNot k _ -> panic "unimplemented" -wasmBinary :: CG bool codegen - => CT.Width - -> [CmmExpr] - -> (forall t . WasmTypeTag t -> WasmIR bool (t : t : '[]) (t : '[])) - -> (forall t . WasmTypeTag t -> WasmIR bool '[] (t : '[]) -> codegen bool r) - -> codegen bool r - -wasmCompare :: forall bool codegen r . CG bool codegen - => CT.Width - -> [CmmExpr] - -> (forall t . WasmTypeTag t -> WasmIR bool (t : t : '[]) (bool : '[])) - -> ( WasmTypeTag bool -> WasmIR bool '[] (bool : '[]) -> codegen bool r) - -> codegen bool r +wasmNullaryInt, wasmNullaryFloat :: + CG bool codegen + => CT.Width + -> (forall t stack . WasmTypeTag t -> WasmIR bool (stack) (t : stack)) + -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) + -> codegen bool r wasmUnary :: CG bool codegen => CT.Width -> [CmmExpr] - -> (forall t . WasmTypeTag t -> WasmIR bool (t : '[]) (t : '[])) - -> (forall t . WasmTypeTag t -> WasmIR bool '[] (t : '[]) -> codegen bool r) + -> (forall t pre . WasmTypeTag t -> WasmIR bool (t : pre) (t : pre)) + -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) -> codegen bool r +wasmBinary :: + CG bool codegen + => CT.Width + -> [CmmExpr] + -> (forall t stack . WasmTypeTag t -> WasmIR bool (t : t : stack) (t : stack)) + -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) + -> codegen bool r + + +wasmCompare :: + forall bool codegen r . CG bool codegen + => CT.Width + -> [CmmExpr] + -> (forall t stack . WasmTypeTag t -> WasmIR bool (t : t : stack) (bool : stack)) + -> (WasmTypeTag bool -> WasmExpr bool bool -> codegen bool r) + -> codegen bool r + +---------------------------------------------------------------- + +wasmNullaryInt w operator k = + withIntWidthTag w $ \tag -> k tag (WasmExpr $ operator tag) + + +wasmNullaryFloat w operator k = + withFloatWidthTag w $ \tag -> k tag (WasmExpr $ operator tag) + +wasmUnary w [e] operator k = + tx e $ \tag code -> checkTagWidth tag w $ k tag (apply1 (operator tag) code) +wasmUnary _ _ _ _ = panic "wrong number of operands to unary operator in Cmm" wasmBinary w es operator k = binaryCPS es $ \tag code1 code2 -> checkTagWidth tag w $ -- optional check - k tag (code1 <> WasmLift tag code2 <> operator tag) - + k tag (apply2 (operator tag) code1 code2) wasmCompare w es operator k = binaryCPS es $ \tag code1 code2 -> do bool <- booleanWasmTypeTag checkTagWidth bool w $ - k bool (code1 <> WasmLift tag code2 <> operator tag) + k bool (apply2 (operator tag) code1 code2) binaryCPS :: forall bool codegen a . CG bool codegen => [CmmExpr] -> (forall t . WasmTypeTag t - -> WasmIR bool '[] (t : '[]) - -> WasmIR bool '[] (t : '[]) + -> WasmExpr bool t + -> WasmExpr bool t -> codegen bool a) -> codegen bool a @@ -99,10 +142,6 @@ binaryCPS [e1, e2] k = -- would dearly love to use do notation here Nothing -> panic "ill-typed Cmm" binaryCPS _ _ = panic "wrong number of operands to binary operator in Cmm" -wasmUnary w [e] operator k = - tx e $ \tag code -> checkTagWidth tag w $ k tag (code <> operator tag) -wasmUnary _ _ _ _ = panic "wrong number of operands to unary operator in Cmm" - ---------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/893c276e403e2eddcc458c373d541a4f2a7c80bf...32129de7652567f7cd6867a549af2bd08927bffd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/893c276e403e2eddcc458c373d541a4f2a7c80bf...32129de7652567f7cd6867a549af2bd08927bffd You're receiving 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 Oct 5 19:29:55 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 05 Oct 2022 15:29:55 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] rts: don't enforce aligned((8)) on 32-bit targets Message-ID: <633ddb3348f66_1eea6a5159021661b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d37a28ed by Cheng Shao at 2022-10-05T15:29:39-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 1 changed file: - rts/include/Stg.h Changes: ===================================== rts/include/Stg.h ===================================== @@ -263,8 +263,8 @@ typedef StgFunPtr F_; #define EB_(X) extern const char X[] #define IB_(X) static const char X[] /* static (non-heap) closures (requires alignment for pointer tagging): */ -#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) -#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) +#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) /* writable data (does not require alignment): */ #define ERW_(X) extern StgWordArray (X) #define IRW_(X) static StgWordArray (X) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d37a28ed92d0f540e104ddbc9f13decb5bcb5927 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d37a28ed92d0f540e104ddbc9f13decb5bcb5927 You're receiving 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 Oct 5 22:40:11 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 05 Oct 2022 18:40:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] rts: don't enforce aligned((8)) on 32-bit targets Message-ID: <633e07cbb5c47_1eea6a5141424454f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 92e77807 by Cheng Shao at 2022-10-05T18:39:55-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 1 changed file: - rts/include/Stg.h Changes: ===================================== rts/include/Stg.h ===================================== @@ -263,8 +263,8 @@ typedef StgFunPtr F_; #define EB_(X) extern const char X[] #define IB_(X) static const char X[] /* static (non-heap) closures (requires alignment for pointer tagging): */ -#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) -#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) +#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) /* writable data (does not require alignment): */ #define ERW_(X) extern StgWordArray (X) #define IRW_(X) static StgWordArray (X) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/92e77807cce348eadcecedeec839de54c5d97266 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/92e77807cce348eadcecedeec839de54c5d97266 You're receiving 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 Oct 6 00:40:19 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 05 Oct 2022 20:40:19 -0400 Subject: [Git][ghc/ghc][master] Minor fixes following Unicode 15.0.0 update Message-ID: <633e23f31b3bb_1eea6a515902574c0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 3 changed files: - docs/users_guide/9.6.1-notes.rst - libraries/base/changelog.md - libraries/base/tools/ucd2haskell/ucd.sh Changes: ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -129,6 +129,8 @@ Runtime system ``(<=)`` instead of ``compare`` per CLC proposal: https://github.com/haskell/core-libraries-committee/issues/24 +- Updated to `Unicode 15.0.0 `_. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/changelog.md ===================================== @@ -29,7 +29,7 @@ is now exported from `Prelude`. See [CLC #50](https://github.com/haskell/core-libraries-committee/issues/50) for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) - * Update to Unicode 15.0.0. + * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,11 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ - ucd/DerivedCoreProperties.txt:e3eddd7d469cd1b0feed7528defad1a1cc7c6a9ceb0ae4446a6d10921ed2e7bc \ - ucd/DerivedNormalizationProps.txt:b2c444c20730b097787fdf50bd7d6dd3fc5256ab8084f5b35b11c8776eca674c \ - ucd/UnicodeData.txt:36018e68657fdcb3485f636630ffe8c8532e01c977703d2803f5b89d6c5feafb \ - ucd/PropList.txt:6bddfdb850417a5bee6deff19290fd1b138589909afb50f5a049f343bf2c6722 \ - ucd/extracted/DerivedCombiningClass.txt:12b0c3af9b600b49488d66545a3e7844ea980809627201bf9afeebe1c9f16f4e" + ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -39,10 +35,10 @@ download_file() { if test "$__checksum" != "$new_checksum" then echo "sha256sum of the downloaded __file $__file " - echo " [$new_checksum] does not match the expected __checksum [$__checksum]" + echo " [$new_checksum] does not match the expected checksum [$__checksum]" exit 1 else - echo "$__file __checksum ok" + echo "$__file checksum ok" fi fi } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbe1e86ea5e793533898d6935a3b4e60afbd04a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbe1e86ea5e793533898d6935a3b4e60afbd04a7 You're receiving 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 Oct 6 00:40:55 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 05 Oct 2022 20:40:55 -0400 Subject: [Git][ghc/ghc][master] rts: don't enforce aligned((8)) on 32-bit targets Message-ID: <633e2417aa20c_1eea6a5147826105f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 1 changed file: - rts/include/Stg.h Changes: ===================================== rts/include/Stg.h ===================================== @@ -263,8 +263,8 @@ typedef StgFunPtr F_; #define EB_(X) extern const char X[] #define IB_(X) static const char X[] /* static (non-heap) closures (requires alignment for pointer tagging): */ -#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) -#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) +#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) /* writable data (does not require alignment): */ #define ERW_(X) extern StgWordArray (X) #define IRW_(X) static StgWordArray (X) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a31d02e0b76ea0d279f5c6d74239e6aa45ef631 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a31d02e0b76ea0d279f5c6d74239e6aa45ef631 You're receiving 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 Oct 6 09:17:05 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 05:17:05 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Disable more tests Message-ID: <633e9d11d91f0_1eea6a514503097a2@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 211331f9 by Sylvain Henry at 2022-10-06T11:16:36+02:00 Disable more tests - - - - - 3a983d3a by Sylvain Henry at 2022-10-06T11:16:36+02:00 Disable T1791 - - - - - 71e12d28 by Sylvain Henry at 2022-10-06T11:18:32+02:00 Raise NonTermination as an async exception - - - - - 24 changed files: - rts/js/thread.js - testsuite/tests/driver/T20604/all.T - testsuite/tests/driver/multipleHomeUnits/all.T - testsuite/tests/driver/multipleHomeUnits/th-deps/all.T - testsuite/tests/driver/recompTH/all.T - testsuite/tests/driver/th-new-test/all.T - testsuite/tests/ffi/should_compile/all.T - testsuite/tests/indexed-types/should_fail/all.T - testsuite/tests/linear/should_compile/all.T - testsuite/tests/overloadedrecflds/should_compile/all.T - testsuite/tests/overloadedrecflds/should_fail/all.T - testsuite/tests/overloadedrecflds/should_run/all.T - testsuite/tests/parser/should_compile/all.T - testsuite/tests/parser/unicode/all.T - testsuite/tests/patsyn/should_run/all.T - testsuite/tests/polykinds/all.T - testsuite/tests/qualifieddo/should_run/all.T - testsuite/tests/quotes/TH_spliceViewPat/test.T - testsuite/tests/quotes/all.T - testsuite/tests/rename/should_compile/all.T - testsuite/tests/rename/should_fail/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/rts/T1791/all.T - testsuite/tests/rts/all.T Changes: ===================================== rts/js/thread.js ===================================== @@ -1358,7 +1358,7 @@ function h$blockOnBlackhole(c) { TRACE_SCHEDULER("blackhole, blocking: " + h$collectProps(c)); if(BLACKHOLE_TID(c) === h$currentThread) { TRACE_SCHEDULER("NonTermination"); - return h$throw(h$baseZCControlziExceptionziBasezinonTermination, false); // is this an async exception? + return h$throw(h$baseZCControlziExceptionziBasezinonTermination, true); } TRACE_SCHEDULER("blackhole, blocking thread: " + h$threadString(h$currentThread)); if(BLACKHOLE_QUEUE(c) === null) { ===================================== testsuite/tests/driver/T20604/all.T ===================================== @@ -9,5 +9,6 @@ def normalise_paths(s): return '\n'.join(res) -test('T20604', [extra_files(['A.hs', 'A1.hs']) +test('T20604', [ req_th + , extra_files(['A.hs', 'A1.hs']) , normalise_fun(normalise_paths)], makefile_test, []) ===================================== testsuite/tests/driver/multipleHomeUnits/all.T ===================================== @@ -2,7 +2,7 @@ test('multipleHomeUnits_single1', [extra_files([ 'a/', 'unitA'])], multiunit_com test('multipleHomeUnits_single2', [extra_files([ 'b/', 'unitB'])], multiunit_compile, [['unitB'], '-fhide-source-paths']) test('multipleHomeUnits_single3', [extra_files([ 'c/', 'unitC'])], multiunit_compile, [['unitC'], '-fhide-source-paths']) test('multipleHomeUnits_single4', [extra_files([ 'd/', 'unitD'])], multiunit_compile, [['unitD'], '-fhide-source-paths']) -test('multipleHomeUnits_single5', [extra_files([ 'th/', 'unitTH'])], multiunit_compile, [['unitTH'], '-fhide-source-paths']) +test('multipleHomeUnits_single5', [req_th,extra_files([ 'th/', 'unitTH'])], multiunit_compile, [['unitTH'], '-fhide-source-paths']) test('multipleHomeUnits_cpp', [extra_files([ 'cpp-includes/', 'unitCPPIncludes'])], multiunit_compile, [['unitCPPIncludes'], '-fhide-source-paths']) test('multipleHomeUnits_cfile', [extra_files([ 'c-file/', 'unitCFile'])], multiunit_compile, [['unitCFile'], '-fhide-source-paths']) test('multipleHomeUnits_callstack', [extra_files([ 'callstack/', 'unitCallstack'])], makefile_test, []) ===================================== testsuite/tests/driver/multipleHomeUnits/th-deps/all.T ===================================== @@ -1 +1 @@ -test('multipleHomeUnits_th-deps', [extra_files([ 'p1/', 'p2', 'q', 'unitP1', 'unitP2', 'unitQ'])], multiunit_compile, [['unitP1', 'unitP2', 'unitQ'], '-fhide-source-paths']) +test('multipleHomeUnits_th-deps', [req_th,extra_files([ 'p1/', 'p2', 'q', 'unitP1', 'unitP2', 'unitQ'])], multiunit_compile, [['unitP1', 'unitP2', 'unitQ'], '-fhide-source-paths']) ===================================== testsuite/tests/driver/recompTH/all.T ===================================== @@ -1,4 +1,4 @@ -test('recompTH', [extra_files(['A.hs', 'B1.hs', 'B2.hs' ]), +test('recompTH', [req_th, extra_files(['A.hs', 'B1.hs', 'B2.hs' ]), when(fast(), skip) , normalise_slashes], makefile_test, []) ===================================== testsuite/tests/driver/th-new-test/all.T ===================================== @@ -1,4 +1,4 @@ -test('th-new-test', [extra_files(['A.hs', 'B.hs', 'C.hs', 'D.hs', 'B1.hs', 'D1.hs', 'Main.hs']), +test('th-new-test', [req_th, extra_files(['A.hs', 'B.hs', 'C.hs', 'D.hs', 'B1.hs', 'D1.hs', 'Main.hs']), when(fast(), skip) , normalise_slashes], makefile_test, []) ===================================== testsuite/tests/ffi/should_compile/all.T ===================================== @@ -36,7 +36,7 @@ test('T14125', normal, compile, ['']) test( 'cc017', # We need TH but can't load profiled dynamic objects - when(ghc_dynamic(), omit_ways(['profasm'])), + [req_th,when(ghc_dynamic(), omit_ways(['profasm']))], compile, [ '-optc=-DC -optcxx=-DCXX -optcxx=-std=c++11' ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -111,7 +111,7 @@ test('T21092', normal, compile_fail, ['']) test('T9167', normal, compile_fail, ['']) test('T9171', normal, compile_fail, ['']) test('T9097', normal, compile_fail, ['']) -test('T9160', normal, compile_fail, ['']) +test('T9160', req_th, compile_fail, ['']) test('T9357', normal, compile_fail, ['']) test('T9371', normal, compile_fail, ['']) test('T9433', normal, compile_fail, ['']) ===================================== testsuite/tests/linear/should_compile/all.T ===================================== @@ -33,7 +33,7 @@ test('LinearLetRec', expect_broken(18694), compile, ['-O -dlinear-core-lint']) test('LinearTH1', normal, compile, ['']) test('LinearTH2', normal, compile, ['']) test('LinearTH3', normal, compile, ['']) -test('LinearTH4', normal, compile, ['']) +test('LinearTH4', req_th, compile, ['']) test('LinearHole', normal, compile, ['']) test('LinearDataConSections', normal, compile, ['']) test('T18731', normal, compile, ['']) ===================================== testsuite/tests/overloadedrecflds/should_compile/all.T ===================================== @@ -3,7 +3,7 @@ test('T12609', normal, compile, ['']) test('T16597', [], multimod_compile, ['T16597', '-v0']) test('T17176', normal, compile, ['']) test('DRFPatSynExport', [], makefile_test, ['DRFPatSynExport']) -test('NoFieldSelectors', normal, compile, ['']) +test('NoFieldSelectors', req_interp, compile, ['']) test('NFSDRF', normal, compile, ['']) test('NFSImport', [extra_files(['NFSExport.hs'])], multimod_compile, ['NFSImport NFSExport', '-v0']) test('T18999_NoFieldSelectors', normal, compile, ['']) ===================================== testsuite/tests/overloadedrecflds/should_fail/all.T ===================================== @@ -20,7 +20,7 @@ test('overloadedrecfldsfail14', normal, compile_fail, ['']) test('overloadedlabelsfail01', normal, compile_fail, ['']) test('overloadedlabelsfail02', normal, compile_fail, ['']) test('overloadedlabelsfail03', normal, compile_fail, ['']) -test('T11103', normal, compile_fail, ['']) +test('T11103', req_th, compile_fail, ['']) test('T11167_ambiguous_fixity', [], multimod_compile_fail, ['T11167_ambiguous_fixity', '']) test('T13132_duplicaterecflds', normal, compile_fail, ['']) ===================================== testsuite/tests/overloadedrecflds/should_run/all.T ===================================== @@ -3,14 +3,14 @@ test('overloadedrecfldsrun01', [], multimod_compile_and_run, test('overloadedrecfldsrun02', [extra_files(['OverloadedRecFldsRun02_A.hs'])], multimod_compile_and_run, ['overloadedrecfldsrun02', '']) test('overloadedrecfldsrun03', normal, compile_and_run, ['']) -test('overloadedrecfldsrun04', omit_ways(prof_ways), compile_and_run, ['']) +test('overloadedrecfldsrun04', [req_th,omit_ways(prof_ways)], compile_and_run, ['']) test('overloadedrecfldsrun05', normal, compile_and_run, ['']) test('overloadedrecfldsrun07', normal, compile_and_run, ['']) test('overloadedrecflds_generics', normal, compile_and_run, ['']) test('overloadedlabelsrun01', normal, compile_and_run, ['']) test('overloadedlabelsrun02', normal, compile_and_run, ['']) test('overloadedlabelsrun03', normal, compile_and_run, ['']) -test('overloadedlabelsrun04', [extra_files(['OverloadedLabelsRun04_A.hs']), +test('overloadedlabelsrun04', [req_th, extra_files(['OverloadedLabelsRun04_A.hs']), omit_ways(prof_ways)], multimod_compile_and_run, ['overloadedlabelsrun04', config.ghc_th_way_flags]) test('hasfieldrun01', normal, compile_and_run, ['']) ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -165,7 +165,8 @@ test('NegativeLiteralsNoExt', normal, compile, ['']) # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. test('proposal-229f', - [ extra_files(['proposal-229f.hs', 'Proposal229f_instances.hs']), + [ req_th, + extra_files(['proposal-229f.hs', 'Proposal229f_instances.hs']), omit_ways(['profasm', 'profthreaded']) ], multimod_compile_and_run, ['proposal-229f.hs', '']) ===================================== testsuite/tests/parser/unicode/all.T ===================================== @@ -28,7 +28,7 @@ test('T10907', normal, compile, ['']) test('T7650', normal, compile, ['']) test('brackets', normal, compile, ['']) -test('T18225A', normal, compile, ['']) +test('T18225A', req_th, compile, ['']) test('T18225B', normal, compile_fail, ['']) test('T18158', normal, compile, ['']) ===================================== testsuite/tests/patsyn/should_run/all.T ===================================== @@ -23,7 +23,7 @@ test('T11224', normal, compile_and_run, ['-Wincomplete-patterns -Woverlapping-pa # (1) Use -fexternal-interpreter, or # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. -test('T13688', omit_ways(['profasm', 'profthreaded']), multimod_compile_and_run, ['T13688', '-v0']) +test('T13688', [req_th, omit_ways(['profasm', 'profthreaded'])], multimod_compile_and_run, ['T13688', '-v0']) # Requires UnboxedSums, which GHCi does not support. test('T14228', omit_ways(['ghci']), compile_and_run, ['']) test('records-poly-update', normal, compile_and_run, ['']) ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -55,7 +55,7 @@ test('T6129', normal, compile_fail,['']) test('T7053', normal, compile,['']) test('T7053a', normal, compile,['']) test('T7020', normal, compile,['']) -test('T7022', normal, makefile_test, []) +test('T7022', req_th, makefile_test, []) test('T7073', normal, compile,['']) test('T7128', normal, compile,['']) test('T7151', normal, compile_fail,['']) ===================================== testsuite/tests/qualifieddo/should_run/all.T ===================================== @@ -7,5 +7,5 @@ test('qdorun002', [qextra_files], multimod_compile_and_run, ['qdorun002', '']) test('qdorun003', [qextra_files], multimod_compile_and_run, ['qdorun003', '']) test('qdorun004', normal, compile_and_run, ['']) test('qdorun005', [qextra_files], multimod_compile_and_run, ['qdorun005', '']) -test('qdorun006', [qextra_files], multimod_compile_and_run, ['qdorun006', '']) +test('qdorun006', [req_th,qextra_files], multimod_compile_and_run, ['qdorun006', '']) test('qdorun007', [qextra_files], multimod_compile_and_run, ['qdorun007', '']) ===================================== testsuite/tests/quotes/TH_spliceViewPat/test.T ===================================== @@ -3,6 +3,6 @@ def f(name, opts): setTestOpts(f) -test('TH_spliceViewPat', [extra_files(['A.hs', 'Main.hs']), +test('TH_spliceViewPat', [req_th, extra_files(['A.hs', 'Main.hs']), omit_ways(prof_ways)], multimod_compile_and_run, ['Main', config.ghc_th_way_flags]) ===================================== testsuite/tests/quotes/all.T ===================================== @@ -18,7 +18,7 @@ test('T10384', normal, compile_fail, ['']) test('T16384', req_th, compile, ['']) test('T17857', normal, compile, ['']) test('T18103', normal, compile, ['']) -test('T18263', normal, compile, ['']) +test('T18263', req_th, compile, ['']) test('T18521', normal, compile, ['']) test('TH_tf2', normal, compile, ['-v0']) ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -189,4 +189,4 @@ test('unused_haddock', normal, compile, ['-haddock -Wall']) test('T19984', normal, compile, ['-fwarn-unticked-promoted-constructors']) test('T21654', normal, compile, ['-Wunused-top-binds']) test('T22057', normal, compile, ['-Wall']) -test('T22067', normal, compile, ['-Wall']) +test('T22067', req_th, compile, ['-Wall']) ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -43,7 +43,7 @@ test('rnfail040', [extra_files(['Rnfail040_A.hs']), normalise_version('base')], test('rnfail041', normal, compile_fail, ['']) test('rnfail042', normal, compile_fail, ['']) -test('rnfail043', unless(doing_ghci, skip), compile_fail, ['-v0']) +test('rnfail043', [req_th,unless(doing_ghci, skip)], compile_fail, ['-v0']) test('rnfail044', normal, compile_fail, ['']) test('rnfail045', normal, compile_fail, ['']) test('rnfail046', normal, compile_fail, ['']) @@ -176,4 +176,4 @@ test('T19843l', normal, compile_fail, ['']) test('T19843m', normal, compile_fail, ['']) test('T11167_ambig', normal, compile_fail, ['']) test('T18138', normal, compile_fail, ['']) -test('T20147', normal, compile_fail, ['']) \ No newline at end of file +test('T20147', normal, compile_fail, ['']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -10,7 +10,7 @@ test('T14561b', normal, compile_fail, ['']) test('T14765', normal, compile_fail, ['']) test('T17360', normal, compile_fail, ['']) test('T17817', normal, compile_fail, ['']) -test('T18170a', [extra_files(['T18170c.hs'])], multimod_compile, ['T18170a.hs', '-v0']) +test('T18170a', [req_th,extra_files(['T18170c.hs'])], multimod_compile, ['T18170a.hs', '-v0']) test('T18170b', [extra_files(['T18170c.hs']), expect_broken(19893)], multimod_compile_fail, ['T18170b.hs', '-v0']) # T18170b isn't actually broken, but it causes a Core Lint error # even though the program is (correctly) rejected by the typechecker ===================================== testsuite/tests/rts/T1791/all.T ===================================== @@ -1,4 +1,6 @@ test('T1791', - [ exit_code(0) ], + [ exit_code(0) + , js_skip # The JS backend doesn't detect heap overflows + ], run_command, ['''"$MAKE" -s --no-print-directory T1791 >/dev/null && ./T1791 +RTS -M8M''']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -254,12 +254,14 @@ test('T5250', [extra_files(['spalign.c']), omit_ways(['ghci']) ], compile_and_run, ['spalign.c']) -test('T5423', [], makefile_test, ['T5423']) +test('T5423', [cmm_src], makefile_test, ['T5423']) test('T5993', extra_run_opts('+RTS -k8 -RTS'), compile_and_run, ['']) test('T6006', [ omit_ways(prof_ways + ['ghci']), - pre_cmd('$MAKE -s --no-print-directory T6006_setup') ], + pre_cmd('$MAKE -s --no-print-directory T6006_setup'), + js_skip + ], # The T6006_setup hack is to ensure that we generate # T6006_stub.h before compiling T6006_c.c, which # needs it. @@ -300,7 +302,7 @@ test('ffishutdown', [ignore_stderr, only_ways(['threaded1','threaded2'])], compile_and_run, ['']) # Times out in ghci way -test('T7919', [when(fast(), skip), omit_ways(['ghci'] + prof_ways)], compile_and_run, +test('T7919', [req_th,when(fast(), skip), omit_ways(['ghci'] + prof_ways)], compile_and_run, [config.ghc_th_way_flags]) test('T8035', normal, compile_and_run, ['']) @@ -430,7 +432,10 @@ test('T14702', [ ignore_stdout ] , compile_and_run, ['']) -test('T14900', normal, compile_and_run, ['-package ghc-compact']) +test('T14900', + [ js_skip # Compact regions not supported by the JS backend yet + ], compile_and_run, ['-package ghc-compact']) + test('InternalCounters', normal, makefile_test, ['InternalCounters']) test('alloccounter1', normal, compile_and_run, [ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55473c85f4556499845ace1515bc3eeeac3d533a...71e12d28e9824a94cd00156eaca9b1c172936bb2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55473c85f4556499845ace1515bc3eeeac3d533a...71e12d28e9824a94cd00156eaca9b1c172936bb2 You're receiving 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 Oct 6 09:40:18 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 06 Oct 2022 05:40:18 -0400 Subject: [Git][ghc/ghc][wip/T22227] 7 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <633ea282aa269_1eea6a515543141d@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 20c4b7a6 by Sebastian Graf at 2022-10-06T11:39:16+02:00 Loopification in OccurAnal (#22227, #14068) - - - - - 6bf50c80 by Sebastian Graf at 2022-10-06T11:39:16+02:00 DmdAnal: Look through DataConWrappers (#22241) - - - - - 28ac7b29 by Sebastian Graf at 2022-10-06T11:39:16+02:00 Unloopify in SpecConstr - - - - - 30 changed files: - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Utils/Misc.hs - rts/Continuation.c - testsuite/tests/linear/should_compile/LinearLetRec.hs - testsuite/tests/rts/continuations/all.T - + testsuite/tests/rts/continuations/cont_stack_overflow.hs - + testsuite/tests/simplCore/should_compile/T22227.hs - + testsuite/tests/simplCore/should_compile/T22227.stderr - testsuite/tests/simplCore/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/6ec3df64a0baaf8f161435138448b83ed1d69ebf...28ac7b29f97682e1c08c13c9cfd4ce89c2fd70bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ec3df64a0baaf8f161435138448b83ed1d69ebf...28ac7b29f97682e1c08c13c9cfd4ce89c2fd70bc You're receiving 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 Oct 6 11:49:40 2022 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Thu, 06 Oct 2022 07:49:40 -0400 Subject: [Git][ghc/ghc][wip/clc-85] 23 commits: Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) Message-ID: <633ec0d459d8c_1eea6a514503304bb@gitlab.mail> Ryan Scott pushed to branch wip/clc-85 at Glasgow Haskell Compiler / GHC Commits: aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/Stats.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5ecb4ecebb3b439850c2719f0341109e2d1ffebf...532de36870ed9e880d5f146a478453701e9db25d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5ecb4ecebb3b439850c2719f0341109e2d1ffebf...532de36870ed9e880d5f146a478453701e9db25d You're receiving 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 Oct 6 12:44:30 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 08:44:30 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Expect IOPort test to be broken Message-ID: <633ecdae27e9b_1eea6a51590345242@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: fc02ebca by Sylvain Henry at 2022-10-06T14:47:47+02:00 Expect IOPort test to be broken - - - - - 2 changed files: - testsuite/driver/testlib.py - testsuite/tests/primops/should_run/all.T Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -142,6 +142,13 @@ def js_skip( name, opts ): if arch("js"): skip(name,opts) +# expect broken for the JS backend +def js_broken( bug: IssueNumber ): + if arch("js"): + return expect_broken(bug); + else: + return normal; + def expect_fail( name, opts ): # The compiler, testdriver, OS or platform is missing a certain # feature, and we don't plan to or can't fix it now or in the ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -45,7 +45,7 @@ test('LevPolyPtrEquality2', normal, compile_and_run, ['']) test('UnliftedArray1', normal, compile_and_run, ['']) test('UnliftedArray2', normal, compile_and_run, ['']) test('UnliftedArrayCAS', normal, compile_and_run, ['']) -test('UnliftedIOPort', normal, compile_and_run, ['']) +test('UnliftedIOPort', js_broken(22261), compile_and_run, ['']) test('UnliftedMutVar1', normal, compile_and_run, ['']) test('UnliftedMutVar2', normal, compile_and_run, ['']) test('UnliftedMutVar3', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fc02ebca2e953d4c61817577628d8c5414df0d72 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fc02ebca2e953d4c61817577628d8c5414df0d72 You're receiving 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 Oct 6 12:48:59 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 08:48:59 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: Implement rts_isThreaded (fix jules_xref2) Message-ID: <633ecebb8aa7_1eea6a5143c347473@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 340daf41 by Sylvain Henry at 2022-10-06T14:49:53+02:00 Implement rts_isThreaded (fix jules_xref2) - - - - - 4aa2749c by Sylvain Henry at 2022-10-06T14:51:45+02:00 Disable outofmem2 test - - - - - 2 changed files: - rts/js/thread.js - testsuite/tests/rts/all.T Changes: ===================================== rts/js/thread.js ===================================== @@ -1426,3 +1426,5 @@ function h$makeMVarListener(mv, stopProp, stopImmProp, preventDefault) { function h$rs() { return h$stack[h$sp]; } + +const rts_isThreaded = 0; ===================================== testsuite/tests/rts/all.T ===================================== @@ -100,7 +100,9 @@ test('outofmem', [ when(opsys('darwin'), skip), when(opsys('mingw32'), skip), normalise_errmsg_fun(remove_parenthesis)], makefile_test, ['outofmem']) -test('outofmem2', normal, makefile_test, ['outofmem2']) +test('outofmem2', + [ js_skip # JS backend doesn't detect heap exhaustion + ], makefile_test, ['outofmem2']) test('T2047', [ignore_stdout, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fc02ebca2e953d4c61817577628d8c5414df0d72...4aa2749cfced7c2d07d37dc200e0c1e4584524e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fc02ebca2e953d4c61817577628d8c5414df0d72...4aa2749cfced7c2d07d37dc200e0c1e4584524e2 You're receiving 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 Oct 6 12:51:40 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 08:51:40 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable tests using C files Message-ID: <633ecf5cec608_1eea6a514783476d6@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: e760b667 by Sylvain Henry at 2022-10-06T14:54:49+02:00 Disable tests using C files - - - - - 1 changed file: - testsuite/driver/testlib.py Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -737,6 +737,8 @@ def literate( name, opts ): def c_src( name, opts ): opts.c_src = True + # JS backend doesn't support C (yet) + js_skip(name, opts) def objc_src( name, opts ): opts.objc_src = True View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e760b66750747e021d4af06e70572d61816ea391 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e760b66750747e021d4af06e70572d61816ea391 You're receiving 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 Oct 6 12:54:41 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 08:54:41 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable delimited continuation tests Message-ID: <633ed011372d3_1eea6a5147834785f@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c195dfe3 by Sylvain Henry at 2022-10-06T14:57:58+02:00 Disable delimited continuation tests - - - - - 1 changed file: - testsuite/tests/rts/continuations/all.T Changes: ===================================== testsuite/tests/rts/continuations/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_broken(22261)) + test('cont_simple_shift', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_simple_shift', '']) test('cont_exn_masking', [extra_files(['ContIO.hs'])], multimod_compile_and_run, ['cont_exn_masking', '']) test('cont_missing_prompt_err', [extra_files(['ContIO.hs']), exit_code(1)], multimod_compile_and_run, ['cont_missing_prompt_err', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c195dfe3dcd7847567067d41c45e96455f4ed4b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c195dfe3dcd7847567067d41c45e96455f4ed4b7 You're receiving 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 Oct 6 12:59:41 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 08:59:41 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable native RTS flag tests Message-ID: <633ed13dae51_1eea6a5148c3520ba@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c24c6ad3 by Sylvain Henry at 2022-10-06T15:02:58+02:00 Disable native RTS flag tests - - - - - 1 changed file: - testsuite/tests/rts/flags/all.T Changes: ===================================== testsuite/tests/rts/flags/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_skip) # JS backend doesn't support native RTS flags + # We ignore ways which depend on passing RTS arguments for simplicity and only # run in normal way. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c24c6ad3e2493cea9f502af34314cdd147ee2c38 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c24c6ad3e2493cea9f502af34314cdd147ee2c38 You're receiving 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 Oct 6 13:41:01 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 09:41:01 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: Disable more tests Message-ID: <633edaede98f1_1eea6a514643565f4@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 02127fb6 by Sylvain Henry at 2022-10-06T15:17:47+02:00 Disable more tests - - - - - 67e85d57 by Sylvain Henry at 2022-10-06T15:44:14+02:00 Disable more tests - - - - - 9 changed files: - testsuite/tests/perf/should_run/all.T - testsuite/tests/perf/space_leaks/all.T - testsuite/tests/rts/all.T - testsuite/tests/saks/should_compile/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/tcplugins/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/all.T - testsuite/tests/unboxedsums/all.T Changes: ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -1,3 +1,8 @@ +# disable performance tests for the JS backend +# .stats files aren't generated and the expected allocation metrics (e.g. "bytes +# allocated") can't be reported +setTestOpts(js_skip) + # T12791 and T5835 test that GHC uses top-level instances in places where using # a locally given solution would produce worse code. # See Note [Solving from instances when interacting Dicts] ===================================== testsuite/tests/perf/space_leaks/all.T ===================================== @@ -1,3 +1,4 @@ +setTestOpts(js_skip) test('space_leak_001', # This could potentially be replaced with ===================================== testsuite/tests/rts/all.T ===================================== @@ -97,6 +97,8 @@ test('outofmem', [ when(opsys('darwin'), skip), # windows, to prevent absolute exhaustion of memory # and subsequent termination (and failure) of unrelated # tests. + js_skip, + # similarly for the JS backend when(opsys('mingw32'), skip), normalise_errmsg_fun(remove_parenthesis)], makefile_test, ['outofmem']) ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -43,6 +43,6 @@ test('T16756a', normal, compile, ['']) # (1) Use -fexternal-interpreter, or # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. -test('saks027', omit_ways(['profasm']), compile, ['-v0 -ddump-splices -dsuppress-uniques']) -test('saks028', omit_ways(['profasm']), compile, ['']) -test('T17164', omit_ways(['profasm']), compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('saks027', [req_th,omit_ways(['profasm'])], compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('saks028', [req_th,omit_ways(['profasm'])], compile, ['']) +test('T17164', [req_th,omit_ways(['profasm'])], compile, ['-v0 -ddump-splices -dsuppress-uniques']) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -134,7 +134,7 @@ test('T5366', normal, makefile_test, ['T5366']) test('T7796', [], makefile_test, ['T7796']) -test('T5550', omit_ways(prof_ways), compile, ['']) +test('T5550', [req_interp,omit_ways(prof_ways)], compile, ['']) test('T7865', normal, makefile_test, ['T7865']) # T7785: we want to check that we specialise 'shared'. But Tidy discards the @@ -347,7 +347,7 @@ test('T18747B', normal, compile, ['']) test('T18815', only_ways(['optasm']), makefile_test, ['T18815']) test('T18668', normal, compile, ['-dsuppress-uniques']) test('T18995', [ grep_errmsg(r'print') ], compile, ['-O -ddump-simpl -dsuppress-uniques']) -test('T19168', normal, compile, ['']) +test('T19168', req_interp, compile, ['']) test('T19246', only_ways(['optasm']), multimod_compile, ['T19246', '-v0 -ddump-rules']) test('T19360', only_ways(['optasm']), compile, ['']) @@ -394,7 +394,7 @@ test('OpaqueNoCastWW', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('OpaqueNoRebox', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('OpaqueNoRebox2', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('OpaqueNoRebox3', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) -test('OpaqueNoSpecConstr', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) +test('OpaqueNoSpecConstr', req_interp, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('OpaqueNoSpecialise', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('OpaqueNoStrictArgWW', normal, compile, ['-O -fworker-wrapper-cbv -ddump-simpl -dsuppress-uniques']) test('OpaqueNoWW', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/tcplugins/all.T ===================================== @@ -1,3 +1,4 @@ +setTestOpts(js_broken(22261)) # See NullaryPlugin.hs for a description of this plugin. test('TcPlugin_Nullary' ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -490,7 +490,7 @@ test('T10592', normal, compile, ['']) test('T11305', normal, compile, ['']) test('T11254', normal, compile, ['']) test('T11379', normal, compile, ['']) -test('T11462', normal, multi_compile, +test('T11462', js_broken(22261), multi_compile, [None, [('T11462_Plugin.hs', '-package ghc'), ('T11462.hs', '')], '-dynamic' if have_dynamic() else '']) test('T11480', normal, compile, ['']) @@ -558,7 +558,7 @@ test('T11723', normal, compile, ['']) test('T12987', normal, compile, ['']) test('T11736', normal, compile, ['']) test('T13248', expect_broken(13248), compile, ['']) -test('T11525', normal, multi_compile, +test('T11525', js_broken(22261), multi_compile, [None, [('T11525_Plugin.hs', '-package ghc'), ('T11525.hs', '')], '-dynamic' if have_dynamic() else '']) test('T12923_1', normal, compile, ['']) @@ -632,7 +632,7 @@ test('SplitWD', normal, compile, ['']) # (1) Use -fexternal-interpreter, or # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. -test('T14441', omit_ways(['profasm']), compile, ['']) +test('T14441', [js_broken(22261),omit_ways(['profasm'])], compile, ['']) test('T15079', normal, compile, ['']) test('T15050', normal, compile, ['']) test('T14735', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -497,7 +497,7 @@ test('T15552a', normal, compile_fail, ['']) test('T15592a', normal, compile_fail, ['']) test('T15629', normal, compile_fail, ['']) test('T15767', normal, compile_fail, ['']) -test('T15648', [extra_files(['T15648a.hs'])], multimod_compile_fail, ['T15648', '-v0 -fprint-equality-relations']) +test('T15648', [req_th,extra_files(['T15648a.hs'])], multimod_compile_fail, ['T15648', '-v0 -fprint-equality-relations']) test('T15712', normal, compile_fail, ['']) test('T15793', normal, compile_fail, ['']) test('T15796', normal, compile_fail, ['']) ===================================== testsuite/tests/unboxedsums/all.T ===================================== @@ -17,8 +17,8 @@ test('unboxedsums10', omit_ways(['ghci']), compile_and_run, ['']) test('unboxedsums11', omit_ways(['ghci']), compile_and_run, ['']) test('unboxedsums12', omit_ways(['ghci']), compile, ['']) -test('UnboxedSumsTH', omit_ways(['ghci']), compile, ['']) -test('UnboxedSumsTH_Fail', omit_ways(['ghci']), compile_fail, ['']) +test('UnboxedSumsTH', [req_th,omit_ways(['ghci'])], compile, ['']) +test('UnboxedSumsTH_Fail', [req_th,omit_ways(['ghci'])], compile_fail, ['']) test('ffi1', normal, compile_fail, ['']) test('thunk', only_ways(['normal']), compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c24c6ad3e2493cea9f502af34314cdd147ee2c38...67e85d572bb0c5423039e4dbe9674284df167d45 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c24c6ad3e2493cea9f502af34314cdd147ee2c38...67e85d572bb0c5423039e4dbe9674284df167d45 You're receiving 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 Oct 6 14:23:10 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 10:23:10 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Annotation tests require an interpreter Message-ID: <633ee4ce6167d_1eea6a514643637f4@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 43b4590d by Sylvain Henry at 2022-10-06T16:26:17+02:00 Annotation tests require an interpreter - - - - - 1 changed file: - testsuite/tests/annotations/should_fail/all.T Changes: ===================================== testsuite/tests/annotations/should_fail/all.T ===================================== @@ -1,6 +1,6 @@ -test('annfail01', normal, compile_fail, ['']) -test('annfail02', normal, compile_fail, ['']) +test('annfail01', req_interp, compile_fail, ['']) +test('annfail02', req_interp, compile_fail, ['']) test('annfail03', req_interp, compile_fail, ['']) test('annfail04', [extra_files(['Annfail04_Help.hs']), req_interp], multimod_compile_fail, ['annfail04', '-v0']) @@ -12,12 +12,12 @@ test('annfail07', req_interp, compile_fail, ['']) test('annfail08', req_interp, compile_fail, ['']) test('annfail09', req_interp, compile_fail, ['']) test('annfail10', req_interp, compile_fail, ['']) -test('annfail11', normal, compile_fail, ['']) +test('annfail11', req_interp, compile_fail, ['']) test('annfail12', req_interp, compile_fail, ['-v0']) -test('annfail13', normal, compile_fail, ['']) -test('T10826', normal, compile_fail, ['']) -test('T19374b', normal, compile_fail, ['']) -test('T19374c', normal, compile_fail, ['']) +test('annfail13', req_interp, compile_fail, ['']) +test('T10826', req_interp, compile_fail, ['']) +test('T19374b', req_interp, compile_fail, ['']) +test('T19374c', req_interp, compile_fail, ['']) """" Helpful things to C+P: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43b4590d3a7e787b5b47acd7fa931aea771660b3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43b4590d3a7e787b5b47acd7fa931aea771660b3 You're receiving 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 Oct 6 14:44:46 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Oct 2022 10:44:46 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: rts: don't enforce aligned((8)) on 32-bit targets Message-ID: <633ee9de88f4f_1eea6a514283641d2@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - 3747e5ff by sheaf at 2022-10-06T10:44:21-04:00 Remove mention of make from README.md - - - - - 16 changed files: - README.md - compiler/GHC/Tc/Instance/Class.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - rts/include/Stg.h - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - testsuite/tests/typecheck/should_run/T16646.hs - testsuite/tests/typecheck/should_run/T19667.hs Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -571,15 +571,15 @@ Some further observations about `withDict`: (WD3) As an alternative to `withDict`, one could define functions like `withT` above in terms of `unsafeCoerce`. This is more error-prone, however. -(WD4) In order to define things like `reifySymbol` below: +(WD4) In order to define things like `withKnownNat` below: - reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => r) -> r + withKnownNat :: SNat n -> (KnownNat n => r) -> r `withDict` needs to be instantiated with `Any`, like so: - reifySymbol n k = withDict @(KnownSymbol Any) @String @r n (k @Any) + withKnownNat = withDict @(KnownNat Any) @(SNat Any) @r - The use of `Any` is explained in Note [NOINLINE someNatVal] in + The use of `Any` is explained in Note [NOINLINE withSomeSNat] in base:GHC.TypeNats. (WD5) In earlier implementations, `withDict` was implemented as an identifier ===================================== libraries/base/GHC/TypeLits.hs ===================================== @@ -11,6 +11,10 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE ViewPatterns #-} {-| GHC's @DataKinds@ language extension lifts data constructors, natural @@ -34,15 +38,20 @@ module GHC.TypeLits N.Natural, N.Nat, Symbol -- Symbol is declared in GHC.Types in package ghc-prim -- * Linking type and value level - , N.KnownNat, natVal, natVal' - , KnownSymbol, symbolVal, symbolVal' - , KnownChar, charVal, charVal' + , N.KnownNat(natSing), natVal, natVal' + , KnownSymbol(symbolSing), symbolVal, symbolVal' + , KnownChar(charSing), charVal, charVal' , N.SomeNat(..), SomeSymbol(..), SomeChar(..) , someNatVal, someSymbolVal, someCharVal , N.sameNat, sameSymbol, sameChar , OrderingI(..) , N.cmpNat, cmpSymbol, cmpChar - + -- ** Singleton values + , N.SNat, SSymbol, SChar + , pattern N.SNat, pattern SSymbol, pattern SChar + , fromSNat, fromSSymbol, fromSChar + , withSomeSNat, withSomeSSymbol, withSomeSChar + , N.withKnownNat, withKnownSymbol, withKnownChar -- * Functions on type literals , type (N.<=), type (N.<=?), type (N.+), type (N.*), type (N.^), type (N.-) @@ -58,17 +67,19 @@ module GHC.TypeLits ) where -import GHC.Base(Eq(..), Ord(..), Ordering(..), String, otherwise, withDict) -import GHC.Types(Symbol, Char) +import GHC.Base ( Eq(..), Functor(..), Ord(..), Ordering(..), String + , (.), otherwise, withDict ) +import GHC.Types(Symbol, Char, TYPE) import GHC.TypeError(ErrorMessage(..), TypeError) import GHC.Num(Integer, fromInteger) -import GHC.Show(Show(..)) +import GHC.Show(Show(..), appPrec, appPrec1, showParen, showString) import GHC.Read(Read(..)) import GHC.Real(toInteger) import GHC.Prim(Proxy#) import Data.Maybe(Maybe(..)) import Data.Proxy (Proxy(..)) -import Data.Type.Equality((:~:)(Refl)) +import Data.Type.Coercion (Coercion(..), TestCoercion(..)) +import Data.Type.Equality((:~:)(Refl), TestEquality(..)) import Data.Type.Ord(OrderingI(..)) import Unsafe.Coerce(unsafeCoerce) @@ -91,7 +102,7 @@ natVal p = toInteger (N.natVal p) -- | @since 4.7.0.0 symbolVal :: forall n proxy. KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of - SSymbol x -> x + UnsafeSSymbol x -> x -- | @since 4.8.0.0 natVal' :: forall n. N.KnownNat n => Proxy# n -> Integer @@ -100,7 +111,7 @@ natVal' p = toInteger (N.natVal' p) -- | @since 4.8.0.0 symbolVal' :: forall n. KnownSymbol n => Proxy# n -> String symbolVal' _ = case symbolSing :: SSymbol n of - SSymbol x -> x + UnsafeSSymbol x -> x -- | This type represents unknown type-level symbols. @@ -113,11 +124,11 @@ class KnownChar (n :: Char) where charVal :: forall n proxy. KnownChar n => proxy n -> Char charVal _ = case charSing :: SChar n of - SChar x -> x + UnsafeSChar x -> x charVal' :: forall n. KnownChar n => Proxy# n -> Char charVal' _ = case charSing :: SChar n of - SChar x -> x + UnsafeSChar x -> x data SomeChar = forall n. KnownChar n => SomeChar (Proxy n) @@ -133,10 +144,8 @@ someNatVal n -- -- @since 4.7.0.0 someSymbolVal :: String -> SomeSymbol -someSymbolVal n = withSSymbol SomeSymbol (SSymbol n) Proxy -{-# NOINLINE someSymbolVal #-} --- For details see Note [NOINLINE someNatVal] in "GHC.TypeNats" --- The issue described there applies to `someSymbolVal` as well. +someSymbolVal s = withSomeSSymbol s (\(ss :: SSymbol s) -> + withKnownSymbol ss (SomeSymbol @s Proxy)) -- | @since 4.7.0.0 instance Eq SomeSymbol where @@ -159,8 +168,8 @@ instance Read SomeSymbol where -- -- @since 4.16.0.0 someCharVal :: Char -> SomeChar -someCharVal n = withSChar SomeChar (SChar n) Proxy -{-# NOINLINE someCharVal #-} +someCharVal c = withSomeSChar c (\(sc :: SChar c) -> + withKnownChar sc (SomeChar @c Proxy)) instance Eq SomeChar where SomeChar x == SomeChar y = charVal x == charVal y @@ -210,22 +219,20 @@ type family NatToChar (n :: N.Nat) :: Char -- same type-level symbols, or 'Nothing'. -- -- @since 4.7.0.0 -sameSymbol :: (KnownSymbol a, KnownSymbol b) => +sameSymbol :: forall a b proxy1 proxy2. + (KnownSymbol a, KnownSymbol b) => proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameSymbol x y - | symbolVal x == symbolVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameSymbol _ _ = testEquality (symbolSing @a) (symbolSing @b) -- | We either get evidence that this function was instantiated with the -- same type-level characters, or 'Nothing'. -- -- @since 4.16.0.0 -sameChar :: (KnownChar a, KnownChar b) => - proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameChar x y - | charVal x == charVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameChar :: forall a b proxy1 proxy2. + (KnownChar a, KnownChar b) => + proxy1 a -> proxy2 b -> Maybe (a :~: b) +sameChar _ _ = testEquality (charSing @a) (charSing @b) -- | Like 'sameSymbol', but if the symbols aren't equal, this additionally -- provides proof of LT or GT. @@ -257,20 +264,217 @@ cmpChar x y = case compare (charVal x) (charVal y) of -------------------------------------------------------------------------------- --- PRIVATE: +-- Singleton values + +-- | Return the 'Integer' corresponding to @n@ in an @'SNat' n@ value. +-- The returned 'Integer' is always non-negative. +-- +-- For a version of this function that returns a 'Natural' instead of an +-- 'Integer', see 'N.fromSNat' in "GHC.TypeNats". +-- +-- @since 4.18.0.0 +fromSNat :: N.SNat n -> Integer +fromSNat sn = toInteger (N.fromSNat sn) + +-- | Attempt to convert an 'Integer' into an @'SNat' n@ value, where @n@ is a +-- fresh type-level natural number. If the 'Integer' argument is non-negative, +-- invoke the continuation with @Just sn@, where @sn@ is the @'SNat' n@ value. +-- If the 'Integer' argument is negative, invoke the continuation with +-- 'Nothing'. +-- +-- For a version of this function where the continuation uses @'SNat@ n@ +-- instead of @'Maybe' ('SNat' n)@, see 'N.withSomeSNat' in "GHC.TypeNats". +-- +-- @since 4.18.0.0 +withSomeSNat :: forall rep (r :: TYPE rep). + Integer -> (forall n. Maybe (N.SNat n) -> r) -> r +withSomeSNat n k + | n >= 0 = N.withSomeSNat (fromInteger n) (\sn -> k (Just sn)) + | otherwise = k Nothing + +-- | A value-level witness for a type-level symbol. This is commonly referred +-- to as a /singleton/ type, as for each @s@, there is a single value that +-- inhabits the type @'SSymbol' s@ (aside from bottom). +-- +-- The definition of 'SSymbol' is intentionally left abstract. To obtain an +-- 'SSymbol' value, use one of the following: +-- +-- 1. The 'symbolSing' method of 'KnownSymbol'. +-- +-- 2. The @SSymbol@ pattern synonym. +-- +-- 3. The 'withSomeSSymbol' function, which creates an 'SSymbol' from a +-- 'String'. +-- +-- @since 4.18.0.0 +newtype SSymbol (s :: Symbol) = UnsafeSSymbol String -newtype SSymbol (s :: Symbol) = SSymbol String +-- | A explicitly bidirectional pattern synonym relating an 'SSymbol' to a +-- 'KnownSymbol' constraint. +-- +-- As an __expression__: Constructs an explicit @'SSymbol' s@ value from an +-- implicit @'KnownSymbol' s@ constraint: +-- +-- @ +-- SSymbol @s :: 'KnownSymbol' s => 'SSymbol' s +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SSymbol' s@ value bringing +-- an implicit @'KnownSymbol' s@ constraint into scope: +-- +-- @ +-- f :: 'SSymbol' s -> .. +-- f SSymbol = {- SSymbol s in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SSymbol :: forall s. () => KnownSymbol s => SSymbol s +pattern SSymbol <- (knownSymbolInstance -> KnownSymbolInstance) + where SSymbol = symbolSing + +-- An internal data type that is only used for defining the SSymbol pattern +-- synonym. +data KnownSymbolInstance (s :: Symbol) where + KnownSymbolInstance :: KnownSymbol s => KnownSymbolInstance s + +-- An internal function that is only used for defining the SSymbol pattern +-- synonym. +knownSymbolInstance :: SSymbol s -> KnownSymbolInstance s +knownSymbolInstance ss = withKnownSymbol ss KnownSymbolInstance + +-- | @since 4.18.0.0 +instance Show (SSymbol s) where + showsPrec p (UnsafeSSymbol s) + = showParen (p > appPrec) + ( showString "SSymbol @" + . showsPrec appPrec1 s + ) + +-- | @since 4.18.0.0 +instance TestEquality SSymbol where + testEquality (UnsafeSSymbol x) (UnsafeSSymbol y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SSymbol where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the String corresponding to @s@ in an @'SSymbol' s@ value. +-- +-- @since 4.18.0.0 +fromSSymbol :: SSymbol s -> String +fromSSymbol (UnsafeSSymbol s) = s +-- | Convert an explicit @'SSymbol' s@ value into an implicit @'KnownSymbol' s@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownSymbol :: forall s rep (r :: TYPE rep). + SSymbol s -> (KnownSymbol s => r) -> r +withKnownSymbol = withDict @(KnownSymbol s) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSSymbol :: forall a b. - (KnownSymbol a => Proxy a -> b) - -> SSymbol a -> Proxy a -> b -withSSymbol f x y = withDict @(KnownSymbol a) x f y -newtype SChar (s :: Char) = SChar Char +-- | Convert a 'String' into an @'SSymbol' s@ value, where @s@ is a fresh +-- type-level symbol. +-- +-- @since 4.18.0.0 +withSomeSSymbol :: forall rep (r :: TYPE rep). + String -> (forall s. SSymbol s -> r) -> r +withSomeSSymbol s k = k (UnsafeSSymbol s) +{-# NOINLINE withSomeSSymbol #-} +-- For details see Note [NOINLINE withSomeSNat] in "GHC.TypeNats" +-- The issue described there applies to `withSomeSSymbol` as well. + +-- | A value-level witness for a type-level character. This is commonly referred +-- to as a /singleton/ type, as for each @c@, there is a single value that +-- inhabits the type @'SChar' c@ (aside from bottom). +-- +-- The definition of 'SChar' is intentionally left abstract. To obtain an +-- 'SChar' value, use one of the following: +-- +-- 1. The 'charSing' method of 'KnownChar'. +-- +-- 2. The @SChar@ pattern synonym. +-- +-- 3. The 'withSomeSChar' function, which creates an 'SChar' from a 'Char'. +-- +-- @since 4.18.0.0 +newtype SChar (s :: Char) = UnsafeSChar Char +-- | A explicitly bidirectional pattern synonym relating an 'SChar' to a +-- 'KnownChar' constraint. +-- +-- As an __expression__: Constructs an explicit @'SChar' c@ value from an +-- implicit @'KnownChar' c@ constraint: +-- +-- @ +-- SChar @c :: 'KnownChar' c => 'SChar' c +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SChar' c@ value bringing +-- an implicit @'KnownChar' c@ constraint into scope: +-- +-- @ +-- f :: 'SChar' c -> .. +-- f SChar = {- SChar c in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SChar :: forall c. () => KnownChar c => SChar c +pattern SChar <- (knownCharInstance -> KnownCharInstance) + where SChar = charSing + +-- An internal data type that is only used for defining the SChar pattern +-- synonym. +data KnownCharInstance (n :: Char) where + KnownCharInstance :: KnownChar c => KnownCharInstance c + +-- An internal function that is only used for defining the SChar pattern +-- synonym. +knownCharInstance :: SChar c -> KnownCharInstance c +knownCharInstance sc = withKnownChar sc KnownCharInstance + +-- | @since 4.18.0.0 +instance Show (SChar c) where + showsPrec p (UnsafeSChar c) + = showParen (p > appPrec) + ( showString "SChar @" + . showsPrec appPrec1 c + ) + +-- | @since 4.18.0.0 +instance TestEquality SChar where + testEquality (UnsafeSChar x) (UnsafeSChar y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SChar where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the 'Char' corresponding to @c@ in an @'SChar' c@ value. +-- +-- @since 4.18.0.0 +fromSChar :: SChar c -> Char +fromSChar (UnsafeSChar c) = c + +-- | Convert an explicit @'SChar' c@ value into an implicit @'KnownChar' c@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownChar :: forall c rep (r :: TYPE rep). + SChar c -> (KnownChar c => r) -> r +withKnownChar = withDict @(KnownChar c) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSChar :: forall a b. - (KnownChar a => Proxy a -> b) - -> SChar a -> Proxy a -> b -withSChar f x y = withDict @(KnownChar a) x f y + +-- | Convert a 'Char' into an @'SChar' c@ value, where @c@ is a fresh type-level +-- character. +-- +-- @since 4.18.0.0 +withSomeSChar :: forall rep (r :: TYPE rep). + Char -> (forall c. SChar c -> r) -> r +withSomeSChar c k = k (UnsafeSChar c) +{-# NOINLINE withSomeSChar #-} +-- For details see Note [NOINLINE withSomeSNat] in "GHC.TypeNats" +-- The issue described there applies to `withSomeSChar` as well. ===================================== libraries/base/GHC/TypeNats.hs ===================================== @@ -13,6 +13,9 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE ViewPatterns #-} {-| This module is an internal GHC module. It declares the constants used in the implementation of type-level natural numbers. The programmer interface @@ -26,10 +29,16 @@ module GHC.TypeNats Natural -- declared in GHC.Num.Natural in package ghc-bignum , Nat -- * Linking type and value level - , KnownNat, natVal, natVal' + , KnownNat(natSing), natVal, natVal' , SomeNat(..) , someNatVal , sameNat + -- ** Singleton values + , SNat + , pattern SNat + , fromSNat + , withSomeSNat + , withKnownNat -- * Functions on type literals , type (<=), type (<=?), type (+), type (*), type (^), type (-) @@ -39,15 +48,16 @@ module GHC.TypeNats ) where -import GHC.Base(Eq(..), Ord(..), otherwise, WithDict(..)) +import GHC.Base(Eq(..), Functor(..), Ord(..), WithDict(..), (.), otherwise) import GHC.Types import GHC.Num.Natural(Natural) -import GHC.Show(Show(..)) +import GHC.Show(Show(..), appPrec, appPrec1, showParen, showString) import GHC.Read(Read(..)) import GHC.Prim(Proxy#) import Data.Maybe(Maybe(..)) import Data.Proxy (Proxy(..)) -import Data.Type.Equality((:~:)(Refl)) +import Data.Type.Coercion (Coercion(..), TestCoercion(..)) +import Data.Type.Equality((:~:)(Refl), TestEquality(..)) import Data.Type.Ord(OrderingI(..), type (<=), type (<=?)) import Unsafe.Coerce(unsafeCoerce) @@ -73,12 +83,12 @@ class KnownNat (n :: Nat) where -- | @since 4.10.0.0 natVal :: forall n proxy. KnownNat n => proxy n -> Natural natVal _ = case natSing :: SNat n of - SNat x -> x + UnsafeSNat x -> x -- | @since 4.10.0.0 natVal' :: forall n. KnownNat n => Proxy# n -> Natural natVal' _ = case natSing :: SNat n of - SNat x -> x + UnsafeSNat x -> x -- | This type represents unknown type-level natural numbers. -- @@ -89,66 +99,72 @@ data SomeNat = forall n. KnownNat n => SomeNat (Proxy n) -- -- @since 4.10.0.0 someNatVal :: Natural -> SomeNat -someNatVal n = withSNat SomeNat (SNat n) Proxy -{-# NOINLINE someNatVal #-} -- See Note [NOINLINE someNatVal] +someNatVal n = withSomeSNat n (\(sn :: SNat n) -> + withKnownNat sn (SomeNat @n Proxy)) {- -Note [NOINLINE someNatVal] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -`someNatVal` converts a natural number to an existentially quantified -dictionary for `KnownNat` (aka `SomeNat`). The existential quantification -is very important, as it captures the fact that we don't know the type -statically, although we do know that it exists. Because this type is -fully opaque, we should never be able to prove that it matches anything else. -This is why coherence should still hold: we can manufacture a `KnownNat k` -dictionary, but it can never be confused with a `KnownNat 33` dictionary, -because we should never be able to prove that `k ~ 33`. - -But how to implement `someNatVal`? We can't quite implement it "honestly" -because `SomeNat` needs to "hide" the type of the newly created dictionary, -but we don't know what the actual type is! If `someNatVal` was built into -the language, then we could manufacture a new skolem constant, -which should behave correctly. - -Since extra language constructors have additional maintenance costs, -we use a trick to implement `someNatVal` in the library. The idea is that -instead of generating a "fresh" type for each use of `someNatVal`, we simply -use GHC's placeholder type `Any` (of kind `Nat`). So, the elaborated -version of the code is: - - someNatVal n = withSNat @T (SomeNat @T) (SNat @T n) (Proxy @T) - where type T = Any Nat +Note [NOINLINE withSomeSNat] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The function -After inlining and simplification, this ends up looking something like this: + withSomeSNat :: forall rep (r :: TYPE rep). + Natural -> (forall k. SNat k -> r) -> r - someNatVal n = SomeNat @T (KnownNat @T (SNat @T n)) (Proxy @T) - where type T = Any Nat +converts a `Natural` number to a singleton natural `SNat k`, where the `k` is +locally quantified in a continuation (hence the `forall k`). The local +quantification is important: we can manufacture an `SNat k` value, but it can +never be confused with (say) an `SNat 33` value, because we should never be +able to prove that `k ~ 33`. Moreover, if we call `withSomeSNat` twice, we'll +get an `SNat k1` value and an `SNat k2` value, but again we can't confuse them. +`SNat` is a singleton type! -`KnownNat` is the constructor for dictionaries for the class `KnownNat`. -See Note [withDict] in "GHC.Tc.Instance.Class" for details on how -we actually construct the dictionary. +But how to implement `withSomeSNat`? We have no way to make up a fresh type +variable. To do that we need `runExists`: see #19675. -Note that using `Any Nat` is not really correct, as multiple calls to -`someNatVal` would violate coherence: +Lacking `runExists`, we use a trick to implement `withSomeSNat`: instead of +generating a "fresh" type for each use of `withSomeSNat`, we simply use GHC's +placeholder type `Any` (of kind `Nat`), thus (in Core): - type T = Any Nat + withSomeSNat n f = f @T (UnsafeSNat @T n) + where type T = Any @Nat - x = SomeNat @T (KnownNat @T (SNat @T 1)) (Proxy @T) - y = SomeNat @T (KnownNat @T (SNat @T 2)) (Proxy @T) +*** BUT we must mark `withSomeSNat` as NOINLINE! *** +(And the same for withSomeSSymbol and withSomeSChar in GHC.TypeLits.) -Note that now the code has two dictionaries with the same type, `KnownNat Any`, -but they have different implementations, namely `SNat 1` and `SNat 2`. This -is not good, as GHC assumes coherence, and it is free to interchange -dictionaries of the same type, but in this case this would produce an incorrect -result. See #16586 for examples of this happening. +If we inline it we'll lose the type distinction between separate calls (those +"fresh" type variables just turn into `T`). And that can interact badly with +GHC's type-class specialiser. Consider this definition, where +`foo :: KnownNat n => blah`: -We can avoid this problem by making the definition of `someNatVal` opaque -and we do this by using a `NOINLINE` pragma. This restores coherence, because -GHC can only inspect the result of `someNatVal` by pattern matching on the -existential, which would generate a new type. This restores correctness, -at the cost of having a little more allocation for the `SomeNat` constructors. --} + ex :: Natural + ex = withSomeSNat 1 (\(s1 :: SNat one) -> withKnownNat @one s1 $ + withSomeSNat 2 (\(s2 :: SNat two) -> withKnownNat @two s2 $ + foo @one ... + foo @two ...)) + +In the last line we have in scope two distinct dictionaries of types +`KnownNat one` and `KnownNat two`. The calls `foo @one` and `foo @two` each pick +out one of those dictionaries to pass to `foo`. +But if we inline `withSomeSNat` we'll get (switching to Core): + + ex = withKnownNat @T (UnsafeSNat @T 1) (\(kn1 :: KnownNat T) -> + withKnownNat @T (UnsafeSNat @T 2) (\(kn2 :: KnownNat T) -> + foo @T kn1 ... + foo @T kn2 ...)) + where type T = Any Nat + +We are now treading on thin ice. We have two dictionaries `kn1` and `kn2`, both +of type `KnownNat T`, but with different implementations. GHC may specialise +`foo` at type `T` using one of these dictionaries and use that same +specialisation for the other. See #16586 for more examples of where something +like this has actually happened. + +`KnownNat` should be a singleton type, but if we allow `withSomeSNat` to inline +it won't be a singleton type any more. We have lost the "fresh type variable". + +TL;DR. We avoid this problem by making the definition of `withSomeSNat` opaque, +using an `NOINLINE` pragma. When we get `runExists` (#19675) we will be able to +stop using this hack. +-} -- | @since 4.7.0.0 @@ -218,11 +234,10 @@ type family Log2 (m :: Nat) :: Nat -- same type-level numbers, or 'Nothing'. -- -- @since 4.7.0.0 -sameNat :: (KnownNat a, KnownNat b) => +sameNat :: forall a b proxy1 proxy2. + (KnownNat a, KnownNat b) => proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameNat x y - | natVal x == natVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameNat _ _ = testEquality (natSing @a) (natSing @b) -- | Like 'sameNat', but if the numbers aren't equal, this additionally -- provides proof of LT or GT. @@ -241,12 +256,96 @@ cmpNat x y = case compare (natVal x) (natVal y) of -------------------------------------------------------------------------------- --- PRIVATE: +-- Singleton values -newtype SNat (n :: Nat) = SNat Natural +-- | A value-level witness for a type-level natural number. This is commonly +-- referred to as a /singleton/ type, as for each @n@, there is a single value +-- that inhabits the type @'SNat' n@ (aside from bottom). +-- +-- The definition of 'SNat' is intentionally left abstract. To obtain an 'SNat' +-- value, use one of the following: +-- +-- 1. The 'natSing' method of 'KnownNat'. +-- +-- 2. The @SNat@ pattern synonym. +-- +-- 3. The 'withSomeSNat' function, which creates an 'SNat' from a 'Natural' +-- number. +-- +-- @since 4.18.0.0 +newtype SNat (n :: Nat) = UnsafeSNat Natural +-- | A explicitly bidirectional pattern synonym relating an 'SNat' to a +-- 'KnownNat' constraint. +-- +-- As an __expression__: Constructs an explicit @'SNat' n@ value from an +-- implicit @'KnownNat' n@ constraint: +-- +-- @ +-- SNat @n :: 'KnownNat' n => 'SNat' n +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SNat' n@ value bringing +-- an implicit @'KnownNat' n@ constraint into scope: +-- +-- @ +-- f :: 'SNat' n -> .. +-- f SNat = {- SNat n in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SNat :: forall n. () => KnownNat n => SNat n +pattern SNat <- (knownNatInstance -> KnownNatInstance) + where SNat = natSing + +-- An internal data type that is only used for defining the SNat pattern +-- synonym. +data KnownNatInstance (n :: Nat) where + KnownNatInstance :: KnownNat n => KnownNatInstance n + +-- An internal function that is only used for defining the SNat pattern +-- synonym. +knownNatInstance :: SNat n -> KnownNatInstance n +knownNatInstance sn = withKnownNat sn KnownNatInstance + +-- | @since 4.18.0.0 +instance Show (SNat n) where + showsPrec p (UnsafeSNat n) + = showParen (p > appPrec) + ( showString "SNat @" + . showsPrec appPrec1 n + ) + +-- | @since 4.18.0.0 +instance TestEquality SNat where + testEquality (UnsafeSNat x) (UnsafeSNat y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SNat where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the 'Natural' number corresponding to @n@ in an @'SNat' n@ value. +-- +-- @since 4.18.0.0 +fromSNat :: SNat n -> Natural +fromSNat (UnsafeSNat n) = n + +-- | Convert an explicit @'SNat' n@ value into an implicit @'KnownNat' n@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownNat :: forall n rep (r :: TYPE rep). + SNat n -> (KnownNat n => r) -> r +withKnownNat = withDict @(KnownNat n) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSNat :: forall a b. - (KnownNat a => Proxy a -> b) - -> SNat a -> Proxy a -> b -withSNat f x y = withDict @(KnownNat a) x f y + +-- | Convert a 'Natural' number into an @'SNat' n@ value, where @n@ is a fresh +-- type-level natural number. +-- +-- @since 4.18.0.0 +withSomeSNat :: forall rep (r :: TYPE rep). + Natural -> (forall n. SNat n -> r) -> r +withSomeSNat n k = k (UnsafeSNat n) +{-# NOINLINE withSomeSNat #-} -- See Note [NOINLINE withSomeSNat] ===================================== libraries/base/changelog.md ===================================== @@ -37,6 +37,12 @@ related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/functor-combinator-instances-and-class1s.md). * Add `gcdetails_block_fragmentation_bytes` to `GHC.Stats.GCDetails` to track heap fragmentation. + * `GHC.TypeLits` and `GHC.TypeNats` now export the `natSing`, `symbolSing`, + and `charSing` methods of `KnownNat`, `KnownSymbol`, and `KnownChar`, + respectively. They also export the `SNat`, `SSymbol`, and `SChar` types + that are used in these methods and provide an API to interact with these + types, per + [CLC proposal #85](https://github.com/haskell/core-libraries-committee/issues/85). ## 4.17.0.0 *August 2022* ===================================== libraries/base/tests/T15183.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +module Main (main) where + +import Control.Exception (ArithException(..), throw) +import Data.Proxy (Proxy(..)) +import GHC.TypeLits ( KnownChar, KnownNat, KnownSymbol + , SChar, Nat, SNat, Symbol, SSymbol + , charVal, natVal, symbolVal + , withKnownChar, withKnownNat, withKnownSymbol + , withSomeSChar, withSomeSNat, withSomeSSymbol ) + +-- As found in the `reflection` library +reifyNat :: Integer -> (forall (n :: Nat). KnownNat n => Proxy n -> r) -> r +reifyNat n k = withSomeSNat n $ \(mbSn :: Maybe (SNat n)) -> + case mbSn of + Just sn -> withKnownNat sn $ k @n Proxy + Nothing -> throw Underflow + +reifySymbol :: String -> (forall (s :: Symbol). KnownSymbol s => Proxy s -> r) -> r +reifySymbol s k = withSomeSSymbol s $ \(ss :: SSymbol s) -> + withKnownSymbol ss $ k @s Proxy + +reifyChar :: Char -> (forall (c :: Char). KnownChar c => Proxy c -> r) -> r +reifyChar c k = withSomeSChar c $ \(sc :: SChar c) -> + withKnownChar sc (k @c Proxy) + +main :: IO () +main = do + reifyNat 42 $ \(_ :: Proxy n) -> print $ natVal $ Proxy @n + reifySymbol "hi" $ \(_ :: Proxy s) -> print $ symbolVal $ Proxy @s + reifyChar 'a' $ \(_ :: Proxy c) -> print $ charVal $ Proxy @c ===================================== libraries/base/tests/T15183.stdout ===================================== @@ -0,0 +1,3 @@ +42 +"hi" +'a' ===================================== libraries/base/tests/all.T ===================================== @@ -257,6 +257,7 @@ test('T13167', [when(opsys('mingw32'), only_ways(['winio', 'winio_threaded'])), fragile_for(16536, concurrent_ways)], compile_and_run, ['']) +test('T15183', normal, compile_and_run, ['']) test('T15349', [exit_code(1), expect_broken_for(15349, ['ghci'])], compile_and_run, ['']) test('T16111', exit_code(1), compile_and_run, ['']) test('T16943a', normal, compile_and_run, ['']) ===================================== rts/include/Stg.h ===================================== @@ -263,8 +263,8 @@ typedef StgFunPtr F_; #define EB_(X) extern const char X[] #define IB_(X) static const char X[] /* static (non-heap) closures (requires alignment for pointer tagging): */ -#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) -#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define EC_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) +#define IC_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (SIZEOF_VOID_P)) /* writable data (does not require alignment): */ #define ERW_(X) extern StgWordArray (X) #define IRW_(X) static StgWordArray (X) ===================================== testsuite/tests/dependent/should_compile/RaeJobTalk.hs ===================================== @@ -13,7 +13,7 @@ module RaeJobTalk where import Data.Type.Bool import Data.Type.Equality hiding ((:~~:)(..)) -import GHC.TypeLits +import GHC.TypeLits hiding (SSymbol) import Data.Proxy import GHC.Exts hiding (Lifted, BoxedRep) import Data.Kind ===================================== testsuite/tests/ghci/scripts/T19667Ghci.hs ===================================== @@ -18,7 +18,7 @@ class KnownSymbol (n :: Symbol) where symbolVal :: forall n proxy . KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of SSymbol x -> x --- See Note [NOINLINE someNatVal] in GHC.TypeNats +-- See Note [NOINLINE withSomeSNat] in GHC.TypeNats {-# NOINLINE reifySymbol #-} reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => Proxy n -> r) -> r reifySymbol n k = withDict @(KnownSymbol Any) @(SSymbol Any) (SSymbol n) (k @Any) (Proxy @(Any @Symbol)) ===================================== testsuite/tests/ghci/scripts/T4175.stdout ===================================== @@ -30,10 +30,10 @@ instance Monoid () -- Defined in ‘GHC.Base’ instance Semigroup () -- Defined in ‘GHC.Base’ instance Bounded () -- Defined in ‘GHC.Enum’ instance Enum () -- Defined in ‘GHC.Enum’ -instance Eq () -- Defined in ‘GHC.Classes’ instance Ord () -- Defined in ‘GHC.Classes’ instance Read () -- Defined in ‘GHC.Read’ instance Show () -- Defined in ‘GHC.Show’ +instance Eq () -- Defined in ‘GHC.Classes’ data instance B () = MkB -- Defined at T4175.hs:14:15 type instance D Int () = String -- Defined at T4175.hs:20:10 type instance D () () = Bool -- Defined at T4175.hs:23:10 @@ -49,24 +49,24 @@ instance Monad Maybe -- Defined in ‘GHC.Base’ instance Semigroup a => Monoid (Maybe a) -- Defined in ‘GHC.Base’ instance Semigroup a => Semigroup (Maybe a) -- Defined in ‘GHC.Base’ -instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’ instance Ord a => Ord (Maybe a) -- Defined in ‘GHC.Maybe’ instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’ instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’ +instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’ type instance A (Maybe a) a = a -- Defined at T4175.hs:10:15 type Int :: * data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in ‘GHC.Types’ instance [safe] C Int -- Defined at T4175.hs:19:10 -instance Integral Int -- Defined in ‘GHC.Real’ -instance Num Int -- Defined in ‘GHC.Num’ -instance Real Int -- Defined in ‘GHC.Real’ instance Bounded Int -- Defined in ‘GHC.Enum’ instance Enum Int -- Defined in ‘GHC.Enum’ -instance Eq Int -- Defined in ‘GHC.Classes’ +instance Integral Int -- Defined in ‘GHC.Real’ +instance Num Int -- Defined in ‘GHC.Num’ instance Ord Int -- Defined in ‘GHC.Classes’ instance Read Int -- Defined in ‘GHC.Read’ +instance Real Int -- Defined in ‘GHC.Real’ instance Show Int -- Defined in ‘GHC.Show’ +instance Eq Int -- Defined in ‘GHC.Classes’ type instance A Int Int = () -- Defined at T4175.hs:9:15 type instance D Int () = String -- Defined at T4175.hs:20:10 type Z :: * -> Constraint ===================================== testsuite/tests/ghci/scripts/T9181.stdout ===================================== @@ -16,6 +16,16 @@ class GHC.TypeLits.KnownSymbol n where {-# MINIMAL symbolSing #-} type GHC.TypeLits.NatToChar :: GHC.Num.Natural.Natural -> Char type family GHC.TypeLits.NatToChar a +pattern GHC.TypeLits.SChar + :: () => GHC.TypeLits.KnownChar c => GHC.TypeLits.SChar c +type role GHC.TypeLits.SChar phantom +type GHC.TypeLits.SChar :: Char -> * +newtype GHC.TypeLits.SChar s = GHC.TypeLits.UnsafeSChar Char +pattern GHC.TypeLits.SSymbol + :: () => GHC.TypeLits.KnownSymbol s => GHC.TypeLits.SSymbol s +type role GHC.TypeLits.SSymbol phantom +type GHC.TypeLits.SSymbol :: GHC.Types.Symbol -> * +newtype GHC.TypeLits.SSymbol s = GHC.TypeLits.UnsafeSSymbol String type GHC.TypeLits.SomeChar :: * data GHC.TypeLits.SomeChar = forall (n :: Char). @@ -38,6 +48,9 @@ GHC.TypeLits.cmpChar :: GHC.TypeLits.cmpSymbol :: (GHC.TypeLits.KnownSymbol a, GHC.TypeLits.KnownSymbol b) => proxy1 a -> proxy2 b -> Data.Type.Ord.OrderingI a b +GHC.TypeLits.fromSChar :: GHC.TypeLits.SChar c -> Char +GHC.TypeLits.fromSNat :: GHC.TypeNats.SNat n -> Integer +GHC.TypeLits.fromSSymbol :: GHC.TypeLits.SSymbol s -> String GHC.TypeLits.natVal :: GHC.TypeNats.KnownNat n => proxy n -> Integer GHC.TypeLits.natVal' :: @@ -55,6 +68,21 @@ GHC.TypeLits.symbolVal :: GHC.TypeLits.KnownSymbol n => proxy n -> String GHC.TypeLits.symbolVal' :: GHC.TypeLits.KnownSymbol n => GHC.Prim.Proxy# n -> String +GHC.TypeLits.withKnownChar :: + GHC.TypeLits.SChar c -> (GHC.TypeLits.KnownChar c => r) -> r +GHC.TypeLits.withKnownSymbol :: + GHC.TypeLits.SSymbol s -> (GHC.TypeLits.KnownSymbol s => r) -> r +GHC.TypeLits.withSomeSChar :: + Char -> (forall (c :: Char). GHC.TypeLits.SChar c -> r) -> r +GHC.TypeLits.withSomeSNat :: + Integer + -> (forall (n :: GHC.TypeNats.Nat). + Maybe (GHC.TypeNats.SNat n) -> r) + -> r +GHC.TypeLits.withSomeSSymbol :: + String + -> (forall (s :: GHC.Types.Symbol). GHC.TypeLits.SSymbol s -> r) + -> r type (GHC.TypeNats.*) :: GHC.Num.Natural.Natural -> GHC.Num.Natural.Natural -> GHC.Num.Natural.Natural type family (GHC.TypeNats.*) a b @@ -123,6 +151,12 @@ data Data.Type.Ord.OrderingI a b where Data.Type.Ord.GTI :: forall {k} (a :: k) (b :: k). (Data.Type.Ord.Compare a b ~ 'GT) => Data.Type.Ord.OrderingI a b +pattern GHC.TypeNats.SNat + :: () => GHC.TypeNats.KnownNat n => GHC.TypeNats.SNat n +type role GHC.TypeNats.SNat phantom +type GHC.TypeNats.SNat :: GHC.TypeNats.Nat -> * +newtype GHC.TypeNats.SNat n + = GHC.TypeNats.UnsafeSNat GHC.Num.Natural.Natural type GHC.TypeNats.SomeNat :: * data GHC.TypeNats.SomeNat = forall (n :: GHC.TypeNats.Nat). @@ -142,3 +176,5 @@ GHC.TypeNats.cmpNat :: GHC.TypeNats.sameNat :: (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b) => proxy1 a -> proxy2 b -> Maybe (a Data.Type.Equality.:~: b) +GHC.TypeNats.withKnownNat :: + GHC.TypeNats.SNat n -> (GHC.TypeNats.KnownNat n => r) -> r ===================================== testsuite/tests/ghci/scripts/ghci064.stdout ===================================== @@ -36,14 +36,14 @@ instance Foreign.Storable.Storable Bool -- Defined in ‘Foreign.Storable’ instance GHC.Generics.Generic Bool -- Defined in ‘GHC.Generics’ instance GHC.Bits.Bits Bool -- Defined in ‘GHC.Bits’ -instance GHC.Bits.FiniteBits Bool -- Defined in ‘GHC.Bits’ -instance GHC.Ix.Ix Bool -- Defined in ‘GHC.Ix’ instance Bounded Bool -- Defined in ‘GHC.Enum’ instance Enum Bool -- Defined in ‘GHC.Enum’ -instance Eq Bool -- Defined in ‘GHC.Classes’ +instance GHC.Bits.FiniteBits Bool -- Defined in ‘GHC.Bits’ +instance GHC.Ix.Ix Bool -- Defined in ‘GHC.Ix’ instance Ord Bool -- Defined in ‘GHC.Classes’ instance Read Bool -- Defined in ‘GHC.Read’ instance Show Bool -- Defined in ‘GHC.Show’ +instance Eq Bool -- Defined in ‘GHC.Classes’ instance Traversable ((,) Int) -- Defined in ‘Data.Traversable’ instance Foldable ((,) Int) -- Defined in ‘Data.Foldable’ instance Functor ((,) Int) -- Defined in ‘GHC.Base’ ===================================== testsuite/tests/typecheck/should_run/T16646.hs ===================================== @@ -21,7 +21,7 @@ instance KnownNat n => Reifies n Integer where reflect = natVal reify :: forall a r. a -> (forall (s :: Type). Reifies s a => Proxy s -> r) -> r -{-# NOINLINE reify #-} -- See Note [NOINLINE someNatVal] in GHC.TypeNats +{-# NOINLINE reify #-} -- See Note [NOINLINE withSomeSNat] in GHC.TypeNats reify a k = withDict @(Reifies (Any @Type) a) @(forall (proxy :: Type -> Type). proxy Any -> a) (const a) (k @Any) Proxy ===================================== testsuite/tests/typecheck/should_run/T19667.hs ===================================== @@ -18,7 +18,7 @@ class KnownSymbol (n :: Symbol) where symbolVal :: forall n proxy . KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of SSymbol x -> x --- See Note [NOINLINE someNatVal] in GHC.TypeNats +-- See Note [NOINLINE withSomeSNat] in GHC.TypeNats {-# NOINLINE reifySymbol #-} reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => Proxy n -> r) -> r reifySymbol n k = withDict @(KnownSymbol Any) @(SSymbol Any) (SSymbol n) (k @Any) (Proxy @(Any @Symbol)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92e77807cce348eadcecedeec839de54c5d97266...3747e5fff089a9e67f4468433e026171d91708d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/92e77807cce348eadcecedeec839de54c5d97266...3747e5fff089a9e67f4468433e026171d91708d6 You're receiving 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 Oct 6 14:46:19 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 10:46:19 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Skip more tests Message-ID: <633eea3b2da26_1eea6a5142836951c@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 101c0025 by Sylvain Henry at 2022-10-06T16:49:35+02:00 Skip more tests - - - - - 4 changed files: - testsuite/tests/annotations/should_run/all.T - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/showIface/should_fail/all.T - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== testsuite/tests/annotations/should_run/all.T ===================================== @@ -8,6 +8,7 @@ setTestOpts(when(fast(), skip)) # config.ghc_th_way_flags. test('annrun01', [extra_files(['Annrun01_Help.hs']), + req_interp, pre_cmd('$MAKE -s --no-print-directory config'), omit_ways(['dyn'] + prof_ways)], multimod_compile_and_run, ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -86,15 +86,20 @@ test('threadstatus-9333', [fragile_for(16555, ['ghci', 'profthreaded']), omit_wa test('T9379', normal, compile_and_run, ['']) -test('allocLimit1', exit_code(1), compile_and_run, ['']) -test('allocLimit2', normal, compile_and_run, ['']) +# Skip the allocLimit* tests with the JS backend as it doesn't support +# setThreadAllocationCounter + +test('allocLimit1', [exit_code(1), js_skip], compile_and_run, ['']) +test('allocLimit2', js_skip, compile_and_run, ['']) # The non-threaded RTS on Windows doesn't handle throwing exceptions at I/O # operations very well, and ends up duplicating the I/O, giving wrong results. test('allocLimit3', [ when(opsys('mingw32'), only_ways(threaded_ways)), + js_skip, exit_code(1) ], compile_and_run, ['']) test('allocLimit4', [ extra_run_opts('+RTS -xq300k -RTS'), + js_skip, # ghci consumes part of set limit at startup omit_ways(['ghci']) ], compile_and_run, ['']) ===================================== testsuite/tests/showIface/should_fail/all.T ===================================== @@ -1,9 +1,9 @@ test('THPutDocExternal', - normal, + req_th, multimod_compile_fail, ['THPutDocExternal', '-no-hs-main -haddock -c -v0']) test('THPutDocNonExistent', - normal, + req_th, multimod_compile_fail, ['THPutDocNonExistent', '-no-hs-main -haddock -c -v0']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -441,7 +441,7 @@ test('T12837', normal, compile_fail, ['']) test('T12906', normal, compile_fail, ['']) test('T12918a', normal, compile_fail, ['']) test('T12918b', normal, compile_fail, ['']) -test('T12921', normal, compile_fail, ['']) +test('T12921', req_interp, compile_fail, ['']) test('T12947', normal, compile_fail, ['']) test('StrictBinds', normal, compile_fail, ['']) test('T13068', [extra_files(['T13068.hs', 'T13068a.hs', 'T13068.hs-boot', 'T13068m.hs'])], multimod_compile_fail, ['T13068m', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/101c002512211ce0acf7bb7229625e2eee46cd31 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/101c002512211ce0acf7bb7229625e2eee46cd31 You're receiving 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 Oct 6 14:48:52 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 10:48:52 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable try_putmvar tests that use C files Message-ID: <633eead47e714_1eea6a51590369766@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: bb1c9bba by Sylvain Henry at 2022-10-06T16:52:04+02:00 Disable try_putmvar tests that use C files - - - - - 1 changed file: - testsuite/tests/concurrent/should_run/all.T Changes: ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -247,6 +247,7 @@ test('hs_try_putmvar001', [ when(opsys('mingw32'),skip), # uses pthread APIs in the C code only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), + js_skip ], compile_and_run, ['hs_try_putmvar001_c.c']) @@ -256,6 +257,7 @@ test('hs_try_putmvar001', test('hs_try_putmvar002', [pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar002_setup'), omit_ways(['ghci']), + js_skip, extra_run_opts('1 8 10000')], compile_and_run, ['hs_try_putmvar002_c.c']) @@ -265,6 +267,7 @@ test('hs_try_putmvar003', when(opsys('mingw32'),skip), # uses pthread APIs in the C code pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar003_setup'), only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), + js_skip, extra_run_opts('1 16 32 100'), fragile_for(16361, ['threaded1']) ], View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb1c9bba655242e4ada99c942ba7ee33078b6825 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb1c9bba655242e4ada99c942ba7ee33078b6825 You're receiving 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 Oct 6 15:07:09 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 06 Oct 2022 11:07:09 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable even more tests Message-ID: <633eef1d7ae3d_1eea6a5148c370142@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 14072610 by Sylvain Henry at 2022-10-06T17:10:23+02:00 Disable even more tests - - - - - 2 changed files: - testsuite/tests/ffi/should_run/all.T - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -228,7 +228,7 @@ test('IncallAffinity', test('T19237', normal, compile_and_run, ['T19237_c.c']) -test('T21305', omit_ways(['ghci']), multi_compile_and_run, +test('T21305', [cmm_src,omit_ways(['ghci'])], multi_compile_and_run, ['T21305', [('T21305_cmm.cmm', '')], '']) test('T22159', ===================================== testsuite/tests/rts/all.T ===================================== @@ -346,10 +346,10 @@ test('ListStaticPointers', [when(doing_ghci(), extra_hc_opts('-fobject-code'))], compile_and_run, ['']) # 251 = RTS exit code for "out of memory" -test('overflow1', [ exit_code(251), when(wordsize(32), expect_broken(15255)) ], +test('overflow1', [ js_skip, exit_code(251), when(wordsize(32), expect_broken(15255)) ], compile_and_run, ['']) -test('overflow2', [ exit_code(251) ], compile_and_run, ['']) -test('overflow3', [ exit_code(251) ], compile_and_run, ['']) +test('overflow2', [ js_skip, exit_code(251) ], compile_and_run, ['']) +test('overflow3', [ js_skip, exit_code(251) ], compile_and_run, ['']) def grep_stderr(pattern): def wrapper(cmd, pattern=pattern): View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14072610bc04343e7ade37d999b34de3d6aa3943 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14072610bc04343e7ade37d999b34de3d6aa3943 You're receiving 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 Oct 6 18:04:52 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Oct 2022 14:04:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633f18c410c99_1eea6a514143824e5@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: dbdb015d by sheaf at 2022-10-06T14:04:36-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbdb015dcc7f11055033c522211b0c124c7c03b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbdb015dcc7f11055033c522211b0c124c7c03b5 You're receiving 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 Oct 6 20:35:09 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Oct 2022 16:35:09 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633f3bfd7617_1eea6a5148c401777@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 54563b76 by sheaf at 2022-10-06T16:34:51-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54563b76e315aeb63fa1e2a86ec905630b2e0d1c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54563b76e315aeb63fa1e2a86ec905630b2e0d1c You're receiving 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 Oct 6 21:05:05 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Thu, 06 Oct 2022 17:05:05 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] cleaned up translator Message-ID: <633f4301eefe0_1eea6a514c8406445@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: f8e96ae5 by Norman Ramsey at 2022-10-06T17:04:49-04:00 cleaned up translator - - - - - 1 changed file: - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -7,7 +7,7 @@ module GHC.Wasm.Tx ( tx , CG(..) - , WasmExpr(..) + , WasmExpr ) where @@ -19,41 +19,77 @@ import Data.Type.Equality import qualified GHC.Cmm.Type as CT import GHC.Cmm.Expr import GHC.Utils.Panic +import GHC.Utils.Panic.Plain (assert) import GHC.Wasm.IR ---------------------------------------------------------------- +--- +--- Overview +--- +---------------------------------------------------------------- +-- +-- This module translates Cmm expressions to Wasm instructions while +-- meeting the following goals: +-- * Keep the code compact and readable +-- * Use GADTs to track the stack types of the Wasm code +-- * Check Cmm types only when necessary to prove type correctness +-- of the generated code or when debugging GHC +-- -newtype WasmExpr bool t = - WasmExpr (forall pre . WasmIR bool pre (t : pre)) - -apply1 :: (forall stack . WasmIR bool (t : stack) (t' : stack)) - -> WasmExpr bool t - -> WasmExpr bool t' -apply1 operator (WasmExpr code) = WasmExpr (code <> operator) -apply2 :: (forall stack . WasmIR bool (t2 : t1 : stack) (t : stack)) - -> WasmExpr bool t1 - -> WasmExpr bool t2 - -> WasmExpr bool t -apply2 operator (WasmExpr code1) (WasmExpr code2) = - WasmExpr (code1 <> code2 <> operator) ---------------------------------------------------------------- +-- code-generation monad + +-- This class is a placeholder that expresses the only +-- property used in the prototype: the platform Boolean +-- type is discoverable. class Monad (codegen bool) => CG bool codegen where --- platformWordSize :: m Int --- asType :: WasmTypeTag t -> m () -- check that type is consistent --- -- with platform word size --- asInt :: WasmTypeTag t -> m () -- insist on the platofrm integer type booleanWasmTypeTag :: codegen bool (WasmTypeTag bool) +---------------------------------------------------------------- + +-- Each Cmm expression is translated into a "WebAssembly expression of +-- type t." This is Wasm code that can push a value of type `t` onto +-- *any* evaluation stack. + +type WasmExpr bool t = (forall stack . WasmIR bool stack (t : stack)) + +-- At translation time, the target type `t` is not known. +-- It can be defined by a tag, but we wish to avoid the bookkeeping +-- associated with packing a tag and a translation into existentially +-- quantified pair. Instead, the translator uses continuation-passing +-- style (CPS) to pass a tag and a translation to its continuation. +-- This technique is recommended by Richard Eisenberg, Stitch: The +-- Sound Type-Indexed Type Checker (Functional Pearl), Haskell +-- Symposium 2020 (https://doi.org/10.1145/3406088.3409015). tx :: CG bool codegen => CmmExpr - -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) - -> codegen bool r - -- combines translation with some type checking + -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool a) + -> codegen bool a + -- type `a` is the answer type of the continuation + +-- The translation is organized as follows: +-- +-- * The main translation function `tx` dispatches on the form of a +-- Cmm expression. +-- +-- * For every different type of Cmm operator, `tx` calls a +-- different auxiliary function: `wasmUnary`, `wasmBinary`, +-- `wasmCompare`, and so on. +-- +-- (Since every different type of Cmm operator generates +-- intermediate Wasm code of different types, it seems sensible +-- that each type of operator might require a Haskell translation +-- function of a different type. But it's a bit irksome.) +-- +-- * Each auxiliary function calls back into `tx` to translate +-- operands, if any, then composes the resulting code. +-- +-- All functions are CPS. tx expr k = case expr of @@ -70,6 +106,10 @@ tx expr k = _ -> panic "unimplemented" +------ Types of all the translation functions + +-- | Cmm integer and floating-point literals (with zero operands) + wasmNullaryInt, wasmNullaryFloat :: CG bool codegen => CT.Width @@ -77,6 +117,8 @@ wasmNullaryInt, wasmNullaryFloat :: -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) -> codegen bool r +-- | Cmm unary operators of type `t -> t` + wasmUnary :: CG bool codegen => CT.Width -> [CmmExpr] @@ -84,6 +126,8 @@ wasmUnary :: CG bool codegen -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) -> codegen bool r +-- | Cmm binary operators of type `t -> t -> t` + wasmBinary :: CG bool codegen => CT.Width @@ -93,6 +137,8 @@ wasmBinary :: -> codegen bool r +-- | Cmm binary operators of type `t -> t -> bool` + wasmCompare :: forall bool codegen r . CG bool codegen => CT.Width @@ -101,29 +147,29 @@ wasmCompare :: -> (WasmTypeTag bool -> WasmExpr bool bool -> codegen bool r) -> codegen bool r ----------------------------------------------------------------- +---------- Implementations of the translation functions wasmNullaryInt w operator k = - withIntWidthTag w $ \tag -> k tag (WasmExpr $ operator tag) + withIntWidthTag w $ \tag -> k tag (operator tag) wasmNullaryFloat w operator k = - withFloatWidthTag w $ \tag -> k tag (WasmExpr $ operator tag) + withFloatWidthTag w $ \tag -> k tag (operator tag) wasmUnary w [e] operator k = - tx e $ \tag code -> checkTagWidth tag w $ k tag (apply1 (operator tag) code) + tx e $ \tag code -> assert (tag `hasWidth` w) $ k tag (code <> operator tag) wasmUnary _ _ _ _ = panic "wrong number of operands to unary operator in Cmm" wasmBinary w es operator k = binaryCPS es $ \tag code1 code2 -> - checkTagWidth tag w $ -- optional check - k tag (apply2 (operator tag) code1 code2) + assert (tag `hasWidth` w) $ + k tag (code1 <> code2 <> operator tag) wasmCompare w es operator k = binaryCPS es $ \tag code1 code2 -> do bool <- booleanWasmTypeTag - checkTagWidth bool w $ - k bool (apply2 (operator tag) code1 code2) + assert (bool `hasWidth` w) $ + k bool (code1 <> code2 <> operator tag) binaryCPS :: forall bool codegen a . CG bool codegen @@ -145,12 +191,12 @@ binaryCPS _ _ = panic "wrong number of operands to binary operator in Cmm" ---------------------------------------------------------------- -checkTagWidth :: WasmTypeTag t -> CT.Width -> a -> a -checkTagWidth TagI32 CT.W32 a = a -checkTagWidth TagF32 CT.W32 a = a -checkTagWidth TagI64 CT.W64 a = a -checkTagWidth TagF64 CT.W64 a = a -checkTagWidth _ _ _ = panic "ill-typed Cmm (width mismatch)" +hasWidth :: WasmTypeTag t -> CT.Width -> Bool +hasWidth TagI32 CT.W32 = True +hasWidth TagF32 CT.W32 = True +hasWidth TagI64 CT.W64 = True +hasWidth TagF64 CT.W64 = True +hasWidth _ _ = False withIntWidthTag :: CT.Width -> (forall t . WasmTypeTag t -> a) -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8e96ae56bddd0d22c9fb671b0f03d123cccc233 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8e96ae56bddd0d22c9fb671b0f03d123cccc233 You're receiving 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 Oct 6 21:28:38 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Thu, 06 Oct 2022 17:28:38 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] fix names Message-ID: <633f488661dbb_1eea6a51428408564@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: b8def32f by Norman Ramsey at 2022-10-06T17:28:27-04:00 fix names - - - - - 1 changed file: - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -117,15 +117,17 @@ wasmNullaryInt, wasmNullaryFloat :: -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) -> codegen bool r + -- | Cmm unary operators of type `t -> t` wasmUnary :: CG bool codegen => CT.Width -> [CmmExpr] - -> (forall t pre . WasmTypeTag t -> WasmIR bool (t : pre) (t : pre)) + -> (forall t stack . WasmTypeTag t -> WasmIR bool (t : stack) (t : stack)) -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool r) -> codegen bool r + -- | Cmm binary operators of type `t -> t -> t` wasmBinary :: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8def32f60fce7ab3d36e48881c9974c07c39194 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8def32f60fce7ab3d36e48881c9974c07c39194 You're receiving 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 Oct 6 23:35:19 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Oct 2022 19:35:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633f6637d3842_1eea6a514c84140dd@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e60f246c by sheaf at 2022-10-06T19:35:04-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e60f246c9141abece84af22d145fdeb7339854f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e60f246c9141abece84af22d145fdeb7339854f3 You're receiving 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 Oct 7 02:55:34 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Oct 2022 22:55:34 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633f95268f9de_1eea6a515544395fd@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bf839146 by sheaf at 2022-10-06T22:55:17-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf8391464ae17b81e95ebc077be190dab52a6d0f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf8391464ae17b81e95ebc077be190dab52a6d0f You're receiving 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 Oct 7 06:15:48 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Oct 2022 02:15:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633fc414f2ed9_1eea6a51428460777@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cbb945df by sheaf at 2022-10-07T02:15:33-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cbb945dfd6f65ab094447bbdba9ed543d7429393 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cbb945dfd6f65ab094447bbdba9ed543d7429393 You're receiving 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 Oct 7 08:46:04 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Oct 2022 04:46:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Remove mention of make from README.md Message-ID: <633fe74c1032_1eea6a5142849204f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 29ea1651 by sheaf at 2022-10-07T04:45:47-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29ea16516cd914e7d2941763b0e533b8aa6e04d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29ea16516cd914e7d2941763b0e533b8aa6e04d6 You're receiving 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 Oct 7 10:52:54 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 07 Oct 2022 06:52:54 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable test using Cmm Message-ID: <63400506d44c8_1eea6a5143c523517@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 99736889 by Sylvain Henry at 2022-10-07T12:56:13+02:00 Disable test using Cmm - - - - - 1 changed file: - testsuite/tests/driver/T7835/all.T Changes: ===================================== testsuite/tests/driver/T7835/all.T ===================================== @@ -1,2 +1,2 @@ -test('T7835', [extra_files(['Test.hs', 'TestPrim.hs', 'test-prims.cmm'])], makefile_test, []) +test('T7835', [cmm_src,extra_files(['Test.hs', 'TestPrim.hs', 'test-prims.cmm'])], makefile_test, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99736889a3dc19deea9196ed63cf048511ef4c4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99736889a3dc19deea9196ed63cf048511ef4c4d You're receiving 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 Oct 7 11:36:14 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Oct 2022 07:36:14 -0400 Subject: [Git][ghc/ghc][master] Export symbolSing, SSymbol, and friends (CLC#85) Message-ID: <63400f2ec1eea_1eea6a5147853524e@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - 14 changed files: - compiler/GHC/Tc/Instance/Class.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - testsuite/tests/typecheck/should_run/T16646.hs - testsuite/tests/typecheck/should_run/T19667.hs Changes: ===================================== compiler/GHC/Tc/Instance/Class.hs ===================================== @@ -571,15 +571,15 @@ Some further observations about `withDict`: (WD3) As an alternative to `withDict`, one could define functions like `withT` above in terms of `unsafeCoerce`. This is more error-prone, however. -(WD4) In order to define things like `reifySymbol` below: +(WD4) In order to define things like `withKnownNat` below: - reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => r) -> r + withKnownNat :: SNat n -> (KnownNat n => r) -> r `withDict` needs to be instantiated with `Any`, like so: - reifySymbol n k = withDict @(KnownSymbol Any) @String @r n (k @Any) + withKnownNat = withDict @(KnownNat Any) @(SNat Any) @r - The use of `Any` is explained in Note [NOINLINE someNatVal] in + The use of `Any` is explained in Note [NOINLINE withSomeSNat] in base:GHC.TypeNats. (WD5) In earlier implementations, `withDict` was implemented as an identifier ===================================== libraries/base/GHC/TypeLits.hs ===================================== @@ -11,6 +11,10 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE ViewPatterns #-} {-| GHC's @DataKinds@ language extension lifts data constructors, natural @@ -34,15 +38,20 @@ module GHC.TypeLits N.Natural, N.Nat, Symbol -- Symbol is declared in GHC.Types in package ghc-prim -- * Linking type and value level - , N.KnownNat, natVal, natVal' - , KnownSymbol, symbolVal, symbolVal' - , KnownChar, charVal, charVal' + , N.KnownNat(natSing), natVal, natVal' + , KnownSymbol(symbolSing), symbolVal, symbolVal' + , KnownChar(charSing), charVal, charVal' , N.SomeNat(..), SomeSymbol(..), SomeChar(..) , someNatVal, someSymbolVal, someCharVal , N.sameNat, sameSymbol, sameChar , OrderingI(..) , N.cmpNat, cmpSymbol, cmpChar - + -- ** Singleton values + , N.SNat, SSymbol, SChar + , pattern N.SNat, pattern SSymbol, pattern SChar + , fromSNat, fromSSymbol, fromSChar + , withSomeSNat, withSomeSSymbol, withSomeSChar + , N.withKnownNat, withKnownSymbol, withKnownChar -- * Functions on type literals , type (N.<=), type (N.<=?), type (N.+), type (N.*), type (N.^), type (N.-) @@ -58,17 +67,19 @@ module GHC.TypeLits ) where -import GHC.Base(Eq(..), Ord(..), Ordering(..), String, otherwise, withDict) -import GHC.Types(Symbol, Char) +import GHC.Base ( Eq(..), Functor(..), Ord(..), Ordering(..), String + , (.), otherwise, withDict ) +import GHC.Types(Symbol, Char, TYPE) import GHC.TypeError(ErrorMessage(..), TypeError) import GHC.Num(Integer, fromInteger) -import GHC.Show(Show(..)) +import GHC.Show(Show(..), appPrec, appPrec1, showParen, showString) import GHC.Read(Read(..)) import GHC.Real(toInteger) import GHC.Prim(Proxy#) import Data.Maybe(Maybe(..)) import Data.Proxy (Proxy(..)) -import Data.Type.Equality((:~:)(Refl)) +import Data.Type.Coercion (Coercion(..), TestCoercion(..)) +import Data.Type.Equality((:~:)(Refl), TestEquality(..)) import Data.Type.Ord(OrderingI(..)) import Unsafe.Coerce(unsafeCoerce) @@ -91,7 +102,7 @@ natVal p = toInteger (N.natVal p) -- | @since 4.7.0.0 symbolVal :: forall n proxy. KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of - SSymbol x -> x + UnsafeSSymbol x -> x -- | @since 4.8.0.0 natVal' :: forall n. N.KnownNat n => Proxy# n -> Integer @@ -100,7 +111,7 @@ natVal' p = toInteger (N.natVal' p) -- | @since 4.8.0.0 symbolVal' :: forall n. KnownSymbol n => Proxy# n -> String symbolVal' _ = case symbolSing :: SSymbol n of - SSymbol x -> x + UnsafeSSymbol x -> x -- | This type represents unknown type-level symbols. @@ -113,11 +124,11 @@ class KnownChar (n :: Char) where charVal :: forall n proxy. KnownChar n => proxy n -> Char charVal _ = case charSing :: SChar n of - SChar x -> x + UnsafeSChar x -> x charVal' :: forall n. KnownChar n => Proxy# n -> Char charVal' _ = case charSing :: SChar n of - SChar x -> x + UnsafeSChar x -> x data SomeChar = forall n. KnownChar n => SomeChar (Proxy n) @@ -133,10 +144,8 @@ someNatVal n -- -- @since 4.7.0.0 someSymbolVal :: String -> SomeSymbol -someSymbolVal n = withSSymbol SomeSymbol (SSymbol n) Proxy -{-# NOINLINE someSymbolVal #-} --- For details see Note [NOINLINE someNatVal] in "GHC.TypeNats" --- The issue described there applies to `someSymbolVal` as well. +someSymbolVal s = withSomeSSymbol s (\(ss :: SSymbol s) -> + withKnownSymbol ss (SomeSymbol @s Proxy)) -- | @since 4.7.0.0 instance Eq SomeSymbol where @@ -159,8 +168,8 @@ instance Read SomeSymbol where -- -- @since 4.16.0.0 someCharVal :: Char -> SomeChar -someCharVal n = withSChar SomeChar (SChar n) Proxy -{-# NOINLINE someCharVal #-} +someCharVal c = withSomeSChar c (\(sc :: SChar c) -> + withKnownChar sc (SomeChar @c Proxy)) instance Eq SomeChar where SomeChar x == SomeChar y = charVal x == charVal y @@ -210,22 +219,20 @@ type family NatToChar (n :: N.Nat) :: Char -- same type-level symbols, or 'Nothing'. -- -- @since 4.7.0.0 -sameSymbol :: (KnownSymbol a, KnownSymbol b) => +sameSymbol :: forall a b proxy1 proxy2. + (KnownSymbol a, KnownSymbol b) => proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameSymbol x y - | symbolVal x == symbolVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameSymbol _ _ = testEquality (symbolSing @a) (symbolSing @b) -- | We either get evidence that this function was instantiated with the -- same type-level characters, or 'Nothing'. -- -- @since 4.16.0.0 -sameChar :: (KnownChar a, KnownChar b) => - proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameChar x y - | charVal x == charVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameChar :: forall a b proxy1 proxy2. + (KnownChar a, KnownChar b) => + proxy1 a -> proxy2 b -> Maybe (a :~: b) +sameChar _ _ = testEquality (charSing @a) (charSing @b) -- | Like 'sameSymbol', but if the symbols aren't equal, this additionally -- provides proof of LT or GT. @@ -257,20 +264,217 @@ cmpChar x y = case compare (charVal x) (charVal y) of -------------------------------------------------------------------------------- --- PRIVATE: +-- Singleton values + +-- | Return the 'Integer' corresponding to @n@ in an @'SNat' n@ value. +-- The returned 'Integer' is always non-negative. +-- +-- For a version of this function that returns a 'Natural' instead of an +-- 'Integer', see 'N.fromSNat' in "GHC.TypeNats". +-- +-- @since 4.18.0.0 +fromSNat :: N.SNat n -> Integer +fromSNat sn = toInteger (N.fromSNat sn) + +-- | Attempt to convert an 'Integer' into an @'SNat' n@ value, where @n@ is a +-- fresh type-level natural number. If the 'Integer' argument is non-negative, +-- invoke the continuation with @Just sn@, where @sn@ is the @'SNat' n@ value. +-- If the 'Integer' argument is negative, invoke the continuation with +-- 'Nothing'. +-- +-- For a version of this function where the continuation uses @'SNat@ n@ +-- instead of @'Maybe' ('SNat' n)@, see 'N.withSomeSNat' in "GHC.TypeNats". +-- +-- @since 4.18.0.0 +withSomeSNat :: forall rep (r :: TYPE rep). + Integer -> (forall n. Maybe (N.SNat n) -> r) -> r +withSomeSNat n k + | n >= 0 = N.withSomeSNat (fromInteger n) (\sn -> k (Just sn)) + | otherwise = k Nothing + +-- | A value-level witness for a type-level symbol. This is commonly referred +-- to as a /singleton/ type, as for each @s@, there is a single value that +-- inhabits the type @'SSymbol' s@ (aside from bottom). +-- +-- The definition of 'SSymbol' is intentionally left abstract. To obtain an +-- 'SSymbol' value, use one of the following: +-- +-- 1. The 'symbolSing' method of 'KnownSymbol'. +-- +-- 2. The @SSymbol@ pattern synonym. +-- +-- 3. The 'withSomeSSymbol' function, which creates an 'SSymbol' from a +-- 'String'. +-- +-- @since 4.18.0.0 +newtype SSymbol (s :: Symbol) = UnsafeSSymbol String -newtype SSymbol (s :: Symbol) = SSymbol String +-- | A explicitly bidirectional pattern synonym relating an 'SSymbol' to a +-- 'KnownSymbol' constraint. +-- +-- As an __expression__: Constructs an explicit @'SSymbol' s@ value from an +-- implicit @'KnownSymbol' s@ constraint: +-- +-- @ +-- SSymbol @s :: 'KnownSymbol' s => 'SSymbol' s +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SSymbol' s@ value bringing +-- an implicit @'KnownSymbol' s@ constraint into scope: +-- +-- @ +-- f :: 'SSymbol' s -> .. +-- f SSymbol = {- SSymbol s in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SSymbol :: forall s. () => KnownSymbol s => SSymbol s +pattern SSymbol <- (knownSymbolInstance -> KnownSymbolInstance) + where SSymbol = symbolSing + +-- An internal data type that is only used for defining the SSymbol pattern +-- synonym. +data KnownSymbolInstance (s :: Symbol) where + KnownSymbolInstance :: KnownSymbol s => KnownSymbolInstance s + +-- An internal function that is only used for defining the SSymbol pattern +-- synonym. +knownSymbolInstance :: SSymbol s -> KnownSymbolInstance s +knownSymbolInstance ss = withKnownSymbol ss KnownSymbolInstance + +-- | @since 4.18.0.0 +instance Show (SSymbol s) where + showsPrec p (UnsafeSSymbol s) + = showParen (p > appPrec) + ( showString "SSymbol @" + . showsPrec appPrec1 s + ) + +-- | @since 4.18.0.0 +instance TestEquality SSymbol where + testEquality (UnsafeSSymbol x) (UnsafeSSymbol y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SSymbol where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the String corresponding to @s@ in an @'SSymbol' s@ value. +-- +-- @since 4.18.0.0 +fromSSymbol :: SSymbol s -> String +fromSSymbol (UnsafeSSymbol s) = s +-- | Convert an explicit @'SSymbol' s@ value into an implicit @'KnownSymbol' s@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownSymbol :: forall s rep (r :: TYPE rep). + SSymbol s -> (KnownSymbol s => r) -> r +withKnownSymbol = withDict @(KnownSymbol s) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSSymbol :: forall a b. - (KnownSymbol a => Proxy a -> b) - -> SSymbol a -> Proxy a -> b -withSSymbol f x y = withDict @(KnownSymbol a) x f y -newtype SChar (s :: Char) = SChar Char +-- | Convert a 'String' into an @'SSymbol' s@ value, where @s@ is a fresh +-- type-level symbol. +-- +-- @since 4.18.0.0 +withSomeSSymbol :: forall rep (r :: TYPE rep). + String -> (forall s. SSymbol s -> r) -> r +withSomeSSymbol s k = k (UnsafeSSymbol s) +{-# NOINLINE withSomeSSymbol #-} +-- For details see Note [NOINLINE withSomeSNat] in "GHC.TypeNats" +-- The issue described there applies to `withSomeSSymbol` as well. + +-- | A value-level witness for a type-level character. This is commonly referred +-- to as a /singleton/ type, as for each @c@, there is a single value that +-- inhabits the type @'SChar' c@ (aside from bottom). +-- +-- The definition of 'SChar' is intentionally left abstract. To obtain an +-- 'SChar' value, use one of the following: +-- +-- 1. The 'charSing' method of 'KnownChar'. +-- +-- 2. The @SChar@ pattern synonym. +-- +-- 3. The 'withSomeSChar' function, which creates an 'SChar' from a 'Char'. +-- +-- @since 4.18.0.0 +newtype SChar (s :: Char) = UnsafeSChar Char +-- | A explicitly bidirectional pattern synonym relating an 'SChar' to a +-- 'KnownChar' constraint. +-- +-- As an __expression__: Constructs an explicit @'SChar' c@ value from an +-- implicit @'KnownChar' c@ constraint: +-- +-- @ +-- SChar @c :: 'KnownChar' c => 'SChar' c +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SChar' c@ value bringing +-- an implicit @'KnownChar' c@ constraint into scope: +-- +-- @ +-- f :: 'SChar' c -> .. +-- f SChar = {- SChar c in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SChar :: forall c. () => KnownChar c => SChar c +pattern SChar <- (knownCharInstance -> KnownCharInstance) + where SChar = charSing + +-- An internal data type that is only used for defining the SChar pattern +-- synonym. +data KnownCharInstance (n :: Char) where + KnownCharInstance :: KnownChar c => KnownCharInstance c + +-- An internal function that is only used for defining the SChar pattern +-- synonym. +knownCharInstance :: SChar c -> KnownCharInstance c +knownCharInstance sc = withKnownChar sc KnownCharInstance + +-- | @since 4.18.0.0 +instance Show (SChar c) where + showsPrec p (UnsafeSChar c) + = showParen (p > appPrec) + ( showString "SChar @" + . showsPrec appPrec1 c + ) + +-- | @since 4.18.0.0 +instance TestEquality SChar where + testEquality (UnsafeSChar x) (UnsafeSChar y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SChar where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the 'Char' corresponding to @c@ in an @'SChar' c@ value. +-- +-- @since 4.18.0.0 +fromSChar :: SChar c -> Char +fromSChar (UnsafeSChar c) = c + +-- | Convert an explicit @'SChar' c@ value into an implicit @'KnownChar' c@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownChar :: forall c rep (r :: TYPE rep). + SChar c -> (KnownChar c => r) -> r +withKnownChar = withDict @(KnownChar c) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSChar :: forall a b. - (KnownChar a => Proxy a -> b) - -> SChar a -> Proxy a -> b -withSChar f x y = withDict @(KnownChar a) x f y + +-- | Convert a 'Char' into an @'SChar' c@ value, where @c@ is a fresh type-level +-- character. +-- +-- @since 4.18.0.0 +withSomeSChar :: forall rep (r :: TYPE rep). + Char -> (forall c. SChar c -> r) -> r +withSomeSChar c k = k (UnsafeSChar c) +{-# NOINLINE withSomeSChar #-} +-- For details see Note [NOINLINE withSomeSNat] in "GHC.TypeNats" +-- The issue described there applies to `withSomeSChar` as well. ===================================== libraries/base/GHC/TypeNats.hs ===================================== @@ -13,6 +13,9 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE ViewPatterns #-} {-| This module is an internal GHC module. It declares the constants used in the implementation of type-level natural numbers. The programmer interface @@ -26,10 +29,16 @@ module GHC.TypeNats Natural -- declared in GHC.Num.Natural in package ghc-bignum , Nat -- * Linking type and value level - , KnownNat, natVal, natVal' + , KnownNat(natSing), natVal, natVal' , SomeNat(..) , someNatVal , sameNat + -- ** Singleton values + , SNat + , pattern SNat + , fromSNat + , withSomeSNat + , withKnownNat -- * Functions on type literals , type (<=), type (<=?), type (+), type (*), type (^), type (-) @@ -39,15 +48,16 @@ module GHC.TypeNats ) where -import GHC.Base(Eq(..), Ord(..), otherwise, WithDict(..)) +import GHC.Base(Eq(..), Functor(..), Ord(..), WithDict(..), (.), otherwise) import GHC.Types import GHC.Num.Natural(Natural) -import GHC.Show(Show(..)) +import GHC.Show(Show(..), appPrec, appPrec1, showParen, showString) import GHC.Read(Read(..)) import GHC.Prim(Proxy#) import Data.Maybe(Maybe(..)) import Data.Proxy (Proxy(..)) -import Data.Type.Equality((:~:)(Refl)) +import Data.Type.Coercion (Coercion(..), TestCoercion(..)) +import Data.Type.Equality((:~:)(Refl), TestEquality(..)) import Data.Type.Ord(OrderingI(..), type (<=), type (<=?)) import Unsafe.Coerce(unsafeCoerce) @@ -73,12 +83,12 @@ class KnownNat (n :: Nat) where -- | @since 4.10.0.0 natVal :: forall n proxy. KnownNat n => proxy n -> Natural natVal _ = case natSing :: SNat n of - SNat x -> x + UnsafeSNat x -> x -- | @since 4.10.0.0 natVal' :: forall n. KnownNat n => Proxy# n -> Natural natVal' _ = case natSing :: SNat n of - SNat x -> x + UnsafeSNat x -> x -- | This type represents unknown type-level natural numbers. -- @@ -89,66 +99,72 @@ data SomeNat = forall n. KnownNat n => SomeNat (Proxy n) -- -- @since 4.10.0.0 someNatVal :: Natural -> SomeNat -someNatVal n = withSNat SomeNat (SNat n) Proxy -{-# NOINLINE someNatVal #-} -- See Note [NOINLINE someNatVal] +someNatVal n = withSomeSNat n (\(sn :: SNat n) -> + withKnownNat sn (SomeNat @n Proxy)) {- -Note [NOINLINE someNatVal] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -`someNatVal` converts a natural number to an existentially quantified -dictionary for `KnownNat` (aka `SomeNat`). The existential quantification -is very important, as it captures the fact that we don't know the type -statically, although we do know that it exists. Because this type is -fully opaque, we should never be able to prove that it matches anything else. -This is why coherence should still hold: we can manufacture a `KnownNat k` -dictionary, but it can never be confused with a `KnownNat 33` dictionary, -because we should never be able to prove that `k ~ 33`. - -But how to implement `someNatVal`? We can't quite implement it "honestly" -because `SomeNat` needs to "hide" the type of the newly created dictionary, -but we don't know what the actual type is! If `someNatVal` was built into -the language, then we could manufacture a new skolem constant, -which should behave correctly. - -Since extra language constructors have additional maintenance costs, -we use a trick to implement `someNatVal` in the library. The idea is that -instead of generating a "fresh" type for each use of `someNatVal`, we simply -use GHC's placeholder type `Any` (of kind `Nat`). So, the elaborated -version of the code is: - - someNatVal n = withSNat @T (SomeNat @T) (SNat @T n) (Proxy @T) - where type T = Any Nat +Note [NOINLINE withSomeSNat] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The function -After inlining and simplification, this ends up looking something like this: + withSomeSNat :: forall rep (r :: TYPE rep). + Natural -> (forall k. SNat k -> r) -> r - someNatVal n = SomeNat @T (KnownNat @T (SNat @T n)) (Proxy @T) - where type T = Any Nat +converts a `Natural` number to a singleton natural `SNat k`, where the `k` is +locally quantified in a continuation (hence the `forall k`). The local +quantification is important: we can manufacture an `SNat k` value, but it can +never be confused with (say) an `SNat 33` value, because we should never be +able to prove that `k ~ 33`. Moreover, if we call `withSomeSNat` twice, we'll +get an `SNat k1` value and an `SNat k2` value, but again we can't confuse them. +`SNat` is a singleton type! -`KnownNat` is the constructor for dictionaries for the class `KnownNat`. -See Note [withDict] in "GHC.Tc.Instance.Class" for details on how -we actually construct the dictionary. +But how to implement `withSomeSNat`? We have no way to make up a fresh type +variable. To do that we need `runExists`: see #19675. -Note that using `Any Nat` is not really correct, as multiple calls to -`someNatVal` would violate coherence: +Lacking `runExists`, we use a trick to implement `withSomeSNat`: instead of +generating a "fresh" type for each use of `withSomeSNat`, we simply use GHC's +placeholder type `Any` (of kind `Nat`), thus (in Core): - type T = Any Nat + withSomeSNat n f = f @T (UnsafeSNat @T n) + where type T = Any @Nat - x = SomeNat @T (KnownNat @T (SNat @T 1)) (Proxy @T) - y = SomeNat @T (KnownNat @T (SNat @T 2)) (Proxy @T) +*** BUT we must mark `withSomeSNat` as NOINLINE! *** +(And the same for withSomeSSymbol and withSomeSChar in GHC.TypeLits.) -Note that now the code has two dictionaries with the same type, `KnownNat Any`, -but they have different implementations, namely `SNat 1` and `SNat 2`. This -is not good, as GHC assumes coherence, and it is free to interchange -dictionaries of the same type, but in this case this would produce an incorrect -result. See #16586 for examples of this happening. +If we inline it we'll lose the type distinction between separate calls (those +"fresh" type variables just turn into `T`). And that can interact badly with +GHC's type-class specialiser. Consider this definition, where +`foo :: KnownNat n => blah`: -We can avoid this problem by making the definition of `someNatVal` opaque -and we do this by using a `NOINLINE` pragma. This restores coherence, because -GHC can only inspect the result of `someNatVal` by pattern matching on the -existential, which would generate a new type. This restores correctness, -at the cost of having a little more allocation for the `SomeNat` constructors. --} + ex :: Natural + ex = withSomeSNat 1 (\(s1 :: SNat one) -> withKnownNat @one s1 $ + withSomeSNat 2 (\(s2 :: SNat two) -> withKnownNat @two s2 $ + foo @one ... + foo @two ...)) + +In the last line we have in scope two distinct dictionaries of types +`KnownNat one` and `KnownNat two`. The calls `foo @one` and `foo @two` each pick +out one of those dictionaries to pass to `foo`. +But if we inline `withSomeSNat` we'll get (switching to Core): + + ex = withKnownNat @T (UnsafeSNat @T 1) (\(kn1 :: KnownNat T) -> + withKnownNat @T (UnsafeSNat @T 2) (\(kn2 :: KnownNat T) -> + foo @T kn1 ... + foo @T kn2 ...)) + where type T = Any Nat + +We are now treading on thin ice. We have two dictionaries `kn1` and `kn2`, both +of type `KnownNat T`, but with different implementations. GHC may specialise +`foo` at type `T` using one of these dictionaries and use that same +specialisation for the other. See #16586 for more examples of where something +like this has actually happened. + +`KnownNat` should be a singleton type, but if we allow `withSomeSNat` to inline +it won't be a singleton type any more. We have lost the "fresh type variable". + +TL;DR. We avoid this problem by making the definition of `withSomeSNat` opaque, +using an `NOINLINE` pragma. When we get `runExists` (#19675) we will be able to +stop using this hack. +-} -- | @since 4.7.0.0 @@ -218,11 +234,10 @@ type family Log2 (m :: Nat) :: Nat -- same type-level numbers, or 'Nothing'. -- -- @since 4.7.0.0 -sameNat :: (KnownNat a, KnownNat b) => +sameNat :: forall a b proxy1 proxy2. + (KnownNat a, KnownNat b) => proxy1 a -> proxy2 b -> Maybe (a :~: b) -sameNat x y - | natVal x == natVal y = Just (unsafeCoerce Refl) - | otherwise = Nothing +sameNat _ _ = testEquality (natSing @a) (natSing @b) -- | Like 'sameNat', but if the numbers aren't equal, this additionally -- provides proof of LT or GT. @@ -241,12 +256,96 @@ cmpNat x y = case compare (natVal x) (natVal y) of -------------------------------------------------------------------------------- --- PRIVATE: +-- Singleton values -newtype SNat (n :: Nat) = SNat Natural +-- | A value-level witness for a type-level natural number. This is commonly +-- referred to as a /singleton/ type, as for each @n@, there is a single value +-- that inhabits the type @'SNat' n@ (aside from bottom). +-- +-- The definition of 'SNat' is intentionally left abstract. To obtain an 'SNat' +-- value, use one of the following: +-- +-- 1. The 'natSing' method of 'KnownNat'. +-- +-- 2. The @SNat@ pattern synonym. +-- +-- 3. The 'withSomeSNat' function, which creates an 'SNat' from a 'Natural' +-- number. +-- +-- @since 4.18.0.0 +newtype SNat (n :: Nat) = UnsafeSNat Natural +-- | A explicitly bidirectional pattern synonym relating an 'SNat' to a +-- 'KnownNat' constraint. +-- +-- As an __expression__: Constructs an explicit @'SNat' n@ value from an +-- implicit @'KnownNat' n@ constraint: +-- +-- @ +-- SNat @n :: 'KnownNat' n => 'SNat' n +-- @ +-- +-- As a __pattern__: Matches on an explicit @'SNat' n@ value bringing +-- an implicit @'KnownNat' n@ constraint into scope: +-- +-- @ +-- f :: 'SNat' n -> .. +-- f SNat = {- SNat n in scope -} +-- @ +-- +-- @since 4.18.0.0 +pattern SNat :: forall n. () => KnownNat n => SNat n +pattern SNat <- (knownNatInstance -> KnownNatInstance) + where SNat = natSing + +-- An internal data type that is only used for defining the SNat pattern +-- synonym. +data KnownNatInstance (n :: Nat) where + KnownNatInstance :: KnownNat n => KnownNatInstance n + +-- An internal function that is only used for defining the SNat pattern +-- synonym. +knownNatInstance :: SNat n -> KnownNatInstance n +knownNatInstance sn = withKnownNat sn KnownNatInstance + +-- | @since 4.18.0.0 +instance Show (SNat n) where + showsPrec p (UnsafeSNat n) + = showParen (p > appPrec) + ( showString "SNat @" + . showsPrec appPrec1 n + ) + +-- | @since 4.18.0.0 +instance TestEquality SNat where + testEquality (UnsafeSNat x) (UnsafeSNat y) + | x == y = Just (unsafeCoerce Refl) + | otherwise = Nothing + +-- | @since 4.18.0.0 +instance TestCoercion SNat where + testCoercion x y = fmap (\Refl -> Coercion) (testEquality x y) + +-- | Return the 'Natural' number corresponding to @n@ in an @'SNat' n@ value. +-- +-- @since 4.18.0.0 +fromSNat :: SNat n -> Natural +fromSNat (UnsafeSNat n) = n + +-- | Convert an explicit @'SNat' n@ value into an implicit @'KnownNat' n@ +-- constraint. +-- +-- @since 4.18.0.0 +withKnownNat :: forall n rep (r :: TYPE rep). + SNat n -> (KnownNat n => r) -> r +withKnownNat = withDict @(KnownNat n) -- See Note [withDict] in "GHC.Tc.Instance.Class" in GHC -withSNat :: forall a b. - (KnownNat a => Proxy a -> b) - -> SNat a -> Proxy a -> b -withSNat f x y = withDict @(KnownNat a) x f y + +-- | Convert a 'Natural' number into an @'SNat' n@ value, where @n@ is a fresh +-- type-level natural number. +-- +-- @since 4.18.0.0 +withSomeSNat :: forall rep (r :: TYPE rep). + Natural -> (forall n. SNat n -> r) -> r +withSomeSNat n k = k (UnsafeSNat n) +{-# NOINLINE withSomeSNat #-} -- See Note [NOINLINE withSomeSNat] ===================================== libraries/base/changelog.md ===================================== @@ -37,6 +37,12 @@ related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/functor-combinator-instances-and-class1s.md). * Add `gcdetails_block_fragmentation_bytes` to `GHC.Stats.GCDetails` to track heap fragmentation. + * `GHC.TypeLits` and `GHC.TypeNats` now export the `natSing`, `symbolSing`, + and `charSing` methods of `KnownNat`, `KnownSymbol`, and `KnownChar`, + respectively. They also export the `SNat`, `SSymbol`, and `SChar` types + that are used in these methods and provide an API to interact with these + types, per + [CLC proposal #85](https://github.com/haskell/core-libraries-committee/issues/85). ## 4.17.0.0 *August 2022* ===================================== libraries/base/tests/T15183.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +module Main (main) where + +import Control.Exception (ArithException(..), throw) +import Data.Proxy (Proxy(..)) +import GHC.TypeLits ( KnownChar, KnownNat, KnownSymbol + , SChar, Nat, SNat, Symbol, SSymbol + , charVal, natVal, symbolVal + , withKnownChar, withKnownNat, withKnownSymbol + , withSomeSChar, withSomeSNat, withSomeSSymbol ) + +-- As found in the `reflection` library +reifyNat :: Integer -> (forall (n :: Nat). KnownNat n => Proxy n -> r) -> r +reifyNat n k = withSomeSNat n $ \(mbSn :: Maybe (SNat n)) -> + case mbSn of + Just sn -> withKnownNat sn $ k @n Proxy + Nothing -> throw Underflow + +reifySymbol :: String -> (forall (s :: Symbol). KnownSymbol s => Proxy s -> r) -> r +reifySymbol s k = withSomeSSymbol s $ \(ss :: SSymbol s) -> + withKnownSymbol ss $ k @s Proxy + +reifyChar :: Char -> (forall (c :: Char). KnownChar c => Proxy c -> r) -> r +reifyChar c k = withSomeSChar c $ \(sc :: SChar c) -> + withKnownChar sc (k @c Proxy) + +main :: IO () +main = do + reifyNat 42 $ \(_ :: Proxy n) -> print $ natVal $ Proxy @n + reifySymbol "hi" $ \(_ :: Proxy s) -> print $ symbolVal $ Proxy @s + reifyChar 'a' $ \(_ :: Proxy c) -> print $ charVal $ Proxy @c ===================================== libraries/base/tests/T15183.stdout ===================================== @@ -0,0 +1,3 @@ +42 +"hi" +'a' ===================================== libraries/base/tests/all.T ===================================== @@ -257,6 +257,7 @@ test('T13167', [when(opsys('mingw32'), only_ways(['winio', 'winio_threaded'])), fragile_for(16536, concurrent_ways)], compile_and_run, ['']) +test('T15183', normal, compile_and_run, ['']) test('T15349', [exit_code(1), expect_broken_for(15349, ['ghci'])], compile_and_run, ['']) test('T16111', exit_code(1), compile_and_run, ['']) test('T16943a', normal, compile_and_run, ['']) ===================================== testsuite/tests/dependent/should_compile/RaeJobTalk.hs ===================================== @@ -13,7 +13,7 @@ module RaeJobTalk where import Data.Type.Bool import Data.Type.Equality hiding ((:~~:)(..)) -import GHC.TypeLits +import GHC.TypeLits hiding (SSymbol) import Data.Proxy import GHC.Exts hiding (Lifted, BoxedRep) import Data.Kind ===================================== testsuite/tests/ghci/scripts/T19667Ghci.hs ===================================== @@ -18,7 +18,7 @@ class KnownSymbol (n :: Symbol) where symbolVal :: forall n proxy . KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of SSymbol x -> x --- See Note [NOINLINE someNatVal] in GHC.TypeNats +-- See Note [NOINLINE withSomeSNat] in GHC.TypeNats {-# NOINLINE reifySymbol #-} reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => Proxy n -> r) -> r reifySymbol n k = withDict @(KnownSymbol Any) @(SSymbol Any) (SSymbol n) (k @Any) (Proxy @(Any @Symbol)) ===================================== testsuite/tests/ghci/scripts/T4175.stdout ===================================== @@ -30,10 +30,10 @@ instance Monoid () -- Defined in ‘GHC.Base’ instance Semigroup () -- Defined in ‘GHC.Base’ instance Bounded () -- Defined in ‘GHC.Enum’ instance Enum () -- Defined in ‘GHC.Enum’ -instance Eq () -- Defined in ‘GHC.Classes’ instance Ord () -- Defined in ‘GHC.Classes’ instance Read () -- Defined in ‘GHC.Read’ instance Show () -- Defined in ‘GHC.Show’ +instance Eq () -- Defined in ‘GHC.Classes’ data instance B () = MkB -- Defined at T4175.hs:14:15 type instance D Int () = String -- Defined at T4175.hs:20:10 type instance D () () = Bool -- Defined at T4175.hs:23:10 @@ -49,24 +49,24 @@ instance Monad Maybe -- Defined in ‘GHC.Base’ instance Semigroup a => Monoid (Maybe a) -- Defined in ‘GHC.Base’ instance Semigroup a => Semigroup (Maybe a) -- Defined in ‘GHC.Base’ -instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’ instance Ord a => Ord (Maybe a) -- Defined in ‘GHC.Maybe’ instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’ instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’ +instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’ type instance A (Maybe a) a = a -- Defined at T4175.hs:10:15 type Int :: * data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in ‘GHC.Types’ instance [safe] C Int -- Defined at T4175.hs:19:10 -instance Integral Int -- Defined in ‘GHC.Real’ -instance Num Int -- Defined in ‘GHC.Num’ -instance Real Int -- Defined in ‘GHC.Real’ instance Bounded Int -- Defined in ‘GHC.Enum’ instance Enum Int -- Defined in ‘GHC.Enum’ -instance Eq Int -- Defined in ‘GHC.Classes’ +instance Integral Int -- Defined in ‘GHC.Real’ +instance Num Int -- Defined in ‘GHC.Num’ instance Ord Int -- Defined in ‘GHC.Classes’ instance Read Int -- Defined in ‘GHC.Read’ +instance Real Int -- Defined in ‘GHC.Real’ instance Show Int -- Defined in ‘GHC.Show’ +instance Eq Int -- Defined in ‘GHC.Classes’ type instance A Int Int = () -- Defined at T4175.hs:9:15 type instance D Int () = String -- Defined at T4175.hs:20:10 type Z :: * -> Constraint ===================================== testsuite/tests/ghci/scripts/T9181.stdout ===================================== @@ -16,6 +16,16 @@ class GHC.TypeLits.KnownSymbol n where {-# MINIMAL symbolSing #-} type GHC.TypeLits.NatToChar :: GHC.Num.Natural.Natural -> Char type family GHC.TypeLits.NatToChar a +pattern GHC.TypeLits.SChar + :: () => GHC.TypeLits.KnownChar c => GHC.TypeLits.SChar c +type role GHC.TypeLits.SChar phantom +type GHC.TypeLits.SChar :: Char -> * +newtype GHC.TypeLits.SChar s = GHC.TypeLits.UnsafeSChar Char +pattern GHC.TypeLits.SSymbol + :: () => GHC.TypeLits.KnownSymbol s => GHC.TypeLits.SSymbol s +type role GHC.TypeLits.SSymbol phantom +type GHC.TypeLits.SSymbol :: GHC.Types.Symbol -> * +newtype GHC.TypeLits.SSymbol s = GHC.TypeLits.UnsafeSSymbol String type GHC.TypeLits.SomeChar :: * data GHC.TypeLits.SomeChar = forall (n :: Char). @@ -38,6 +48,9 @@ GHC.TypeLits.cmpChar :: GHC.TypeLits.cmpSymbol :: (GHC.TypeLits.KnownSymbol a, GHC.TypeLits.KnownSymbol b) => proxy1 a -> proxy2 b -> Data.Type.Ord.OrderingI a b +GHC.TypeLits.fromSChar :: GHC.TypeLits.SChar c -> Char +GHC.TypeLits.fromSNat :: GHC.TypeNats.SNat n -> Integer +GHC.TypeLits.fromSSymbol :: GHC.TypeLits.SSymbol s -> String GHC.TypeLits.natVal :: GHC.TypeNats.KnownNat n => proxy n -> Integer GHC.TypeLits.natVal' :: @@ -55,6 +68,21 @@ GHC.TypeLits.symbolVal :: GHC.TypeLits.KnownSymbol n => proxy n -> String GHC.TypeLits.symbolVal' :: GHC.TypeLits.KnownSymbol n => GHC.Prim.Proxy# n -> String +GHC.TypeLits.withKnownChar :: + GHC.TypeLits.SChar c -> (GHC.TypeLits.KnownChar c => r) -> r +GHC.TypeLits.withKnownSymbol :: + GHC.TypeLits.SSymbol s -> (GHC.TypeLits.KnownSymbol s => r) -> r +GHC.TypeLits.withSomeSChar :: + Char -> (forall (c :: Char). GHC.TypeLits.SChar c -> r) -> r +GHC.TypeLits.withSomeSNat :: + Integer + -> (forall (n :: GHC.TypeNats.Nat). + Maybe (GHC.TypeNats.SNat n) -> r) + -> r +GHC.TypeLits.withSomeSSymbol :: + String + -> (forall (s :: GHC.Types.Symbol). GHC.TypeLits.SSymbol s -> r) + -> r type (GHC.TypeNats.*) :: GHC.Num.Natural.Natural -> GHC.Num.Natural.Natural -> GHC.Num.Natural.Natural type family (GHC.TypeNats.*) a b @@ -123,6 +151,12 @@ data Data.Type.Ord.OrderingI a b where Data.Type.Ord.GTI :: forall {k} (a :: k) (b :: k). (Data.Type.Ord.Compare a b ~ 'GT) => Data.Type.Ord.OrderingI a b +pattern GHC.TypeNats.SNat + :: () => GHC.TypeNats.KnownNat n => GHC.TypeNats.SNat n +type role GHC.TypeNats.SNat phantom +type GHC.TypeNats.SNat :: GHC.TypeNats.Nat -> * +newtype GHC.TypeNats.SNat n + = GHC.TypeNats.UnsafeSNat GHC.Num.Natural.Natural type GHC.TypeNats.SomeNat :: * data GHC.TypeNats.SomeNat = forall (n :: GHC.TypeNats.Nat). @@ -142,3 +176,5 @@ GHC.TypeNats.cmpNat :: GHC.TypeNats.sameNat :: (GHC.TypeNats.KnownNat a, GHC.TypeNats.KnownNat b) => proxy1 a -> proxy2 b -> Maybe (a Data.Type.Equality.:~: b) +GHC.TypeNats.withKnownNat :: + GHC.TypeNats.SNat n -> (GHC.TypeNats.KnownNat n => r) -> r ===================================== testsuite/tests/ghci/scripts/ghci064.stdout ===================================== @@ -36,14 +36,14 @@ instance Foreign.Storable.Storable Bool -- Defined in ‘Foreign.Storable’ instance GHC.Generics.Generic Bool -- Defined in ‘GHC.Generics’ instance GHC.Bits.Bits Bool -- Defined in ‘GHC.Bits’ -instance GHC.Bits.FiniteBits Bool -- Defined in ‘GHC.Bits’ -instance GHC.Ix.Ix Bool -- Defined in ‘GHC.Ix’ instance Bounded Bool -- Defined in ‘GHC.Enum’ instance Enum Bool -- Defined in ‘GHC.Enum’ -instance Eq Bool -- Defined in ‘GHC.Classes’ +instance GHC.Bits.FiniteBits Bool -- Defined in ‘GHC.Bits’ +instance GHC.Ix.Ix Bool -- Defined in ‘GHC.Ix’ instance Ord Bool -- Defined in ‘GHC.Classes’ instance Read Bool -- Defined in ‘GHC.Read’ instance Show Bool -- Defined in ‘GHC.Show’ +instance Eq Bool -- Defined in ‘GHC.Classes’ instance Traversable ((,) Int) -- Defined in ‘Data.Traversable’ instance Foldable ((,) Int) -- Defined in ‘Data.Foldable’ instance Functor ((,) Int) -- Defined in ‘GHC.Base’ ===================================== testsuite/tests/typecheck/should_run/T16646.hs ===================================== @@ -21,7 +21,7 @@ instance KnownNat n => Reifies n Integer where reflect = natVal reify :: forall a r. a -> (forall (s :: Type). Reifies s a => Proxy s -> r) -> r -{-# NOINLINE reify #-} -- See Note [NOINLINE someNatVal] in GHC.TypeNats +{-# NOINLINE reify #-} -- See Note [NOINLINE withSomeSNat] in GHC.TypeNats reify a k = withDict @(Reifies (Any @Type) a) @(forall (proxy :: Type -> Type). proxy Any -> a) (const a) (k @Any) Proxy ===================================== testsuite/tests/typecheck/should_run/T19667.hs ===================================== @@ -18,7 +18,7 @@ class KnownSymbol (n :: Symbol) where symbolVal :: forall n proxy . KnownSymbol n => proxy n -> String symbolVal _ = case symbolSing :: SSymbol n of SSymbol x -> x --- See Note [NOINLINE someNatVal] in GHC.TypeNats +-- See Note [NOINLINE withSomeSNat] in GHC.TypeNats {-# NOINLINE reifySymbol #-} reifySymbol :: forall r. String -> (forall (n :: Symbol). KnownSymbol n => Proxy n -> r) -> r reifySymbol n k = withDict @(KnownSymbol Any) @(SSymbol Any) (SSymbol n) (k @Any) (Proxy @(Any @Symbol)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/532de36870ed9e880d5f146a478453701e9db25d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/532de36870ed9e880d5f146a478453701e9db25d You're receiving 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 Oct 7 11:36:43 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Oct 2022 07:36:43 -0400 Subject: [Git][ghc/ghc][master] Remove mention of make from README.md Message-ID: <63400f4b65bd4_1eea6a5159053878d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 1 changed file: - README.md Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d83a92e6b3ac4609fe0e1159ced59f12dcf622bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d83a92e6b3ac4609fe0e1159ced59f12dcf622bc You're receiving 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 Oct 7 12:21:29 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 07 Oct 2022 08:21:29 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 2 commits: More on bitmap decoding Message-ID: <634019c9e4d92_1eea6a514785464ed@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: f9b72237 by Sven Tennie at 2022-10-06T12:40:23+00:00 More on bitmap decoding - - - - - 42318ec6 by Sven Tennie at 2022-10-07T12:20:47+00:00 Decode large bitmap... - - - - - 4 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm - rts/Printer.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -9,30 +9,24 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE BangPatterns #-} -- TODO: Find better place than top level. Re-export from top-level? module GHC.Exts.DecodeStack where +import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) #if MIN_VERSION_base(4,17,0) +import Data.Maybe import Data.Bits import Foreign - +import System.IO.Unsafe import Prelude import GHC.Stack.CloneStack import GHC.Exts.Heap -import GHC.Ptr import Debug.Trace import GHC.Exts -import qualified GHC.Exts.Heap.FFIClosures as FFIClosures -import Numeric import qualified GHC.Exts.Heap.Closures as CL -import GHC.Exts.Heap.StackFFI as StackFFI -import Data.Bits -import GHC.Exts.Heap (Closure) -import GHC.Exts.Heap.StackFFI (bitsInWord) -import GHC.Exts.Heap.Closures (closureSize) -import System.Mem (performMajorGC) type StackFrameIter# = (# -- | StgStack @@ -43,6 +37,10 @@ type StackFrameIter# = (# data StackFrameIter = StackFrameIter StackFrameIter# +-- TODO: Remove this instance (debug only) +instance Show StackFrameIter where + show (StackFrameIter (# _, i# #)) = "StackFrameIter " ++ "(StackSnapshot _" ++ " " ++ show (W# i#) + -- | Get an interator starting with the top-most stack frame stackHead :: StackSnapshot -> StackFrameIter stackHead (StackSnapshot s) = StackFrameIter (# s , 0## #) -- GHC stacks are never empty @@ -51,12 +49,14 @@ foreign import prim "advanceStackFrameIterzh" advanceStackFrameIter# :: StackSna -- | Advance iterator to the next stack frame (if any) advanceStackFrameIter :: StackFrameIter -> Maybe StackFrameIter -advanceStackFrameIter (StackFrameIter (# s, i #)) = let (# s', i', hasNext #) = advanceStackFrameIter# s i in +advanceStackFrameIter (StackFrameIter (# s, i #)) = let !(# s', i', hasNext #) = advanceStackFrameIter# s i in if (I# hasNext) > 0 then Just $ StackFrameIter (# s', i' #) else Nothing foreign import prim "getInfoTableTypezh" getInfoTableType# :: StackSnapshot# -> Word# -> Word# +foreign import prim "getLargeBitmapzh" getLargeBitmap# :: StackSnapshot# -> Word# -> (# ByteArray#, Word# #) + foreign import prim "getSmallBitmapzh" getSmallBitmap# :: StackSnapshot# -> Word# -> (# Word#, Word# #) data BitmapEntry = BitmapEntry { @@ -64,21 +64,63 @@ data BitmapEntry = BitmapEntry { isPrimitive :: Bool } deriving (Show) +wordsToBitmapEntries :: StackFrameIter -> [Word] -> Word -> [BitmapEntry] +wordsToBitmapEntries _ [] 0 = [] +wordsToBitmapEntries _ [] i = error $ "Invalid state: Empty list, size " ++ show i +wordsToBitmapEntries _ l 0 = error $ "Invalid state: Size 0, list " ++ show l +wordsToBitmapEntries sfi (b:bs) size = + let entries = toBitmapEntries sfi b size + mbLastEntry = (listToMaybe . reverse) entries + mbLastFrame = fmap closureFrame mbLastEntry + in + case mbLastFrame of + Just (StackFrameIter (# s'#, i'# #)) -> + entries ++ wordsToBitmapEntries (StackFrameIter (# s'#, plusWord# i'# 1## #)) bs (subtractDecodedBitmapWord size) + Nothing -> error "This should never happen! Recursion ended not in base case." + where + subtractDecodedBitmapWord :: Word -> Word + subtractDecodedBitmapWord size = fromIntegral $ max 0 ((fromIntegral size) - wORD_SIZE_IN_BITS) + toBitmapEntries :: StackFrameIter -> Word -> Word -> [BitmapEntry] toBitmapEntries _ _ 0 = [] -toBitmapEntries sfi@(StackFrameIter(# s, i #) bitmap size = BitmapEntry { +toBitmapEntries sfi@(StackFrameIter(# s, i #)) bitmap size = BitmapEntry { closureFrame = sfi, isPrimitive = (bitmap .&. 1) == 0 - } : toBitmapEntries (StackFrameIter (# s , i + 1 #)) (bitmap `shiftR` 1) (size - 1) + } : toBitmapEntries (StackFrameIter (# s , plusWord# i 1## #)) (bitmap `shiftR` 1) (size - 1) + +toBitmapPayload :: BitmapEntry -> BitmapPayload +toBitmapPayload e | isPrimitive e = Primitive . toWord . closureFrame $ e + where + toWord (StackFrameIter (# s#, i# #)) = W# (derefStackWord# s# i#) +toBitmapPayload e = Closure . unsafePerformIO . toClosure . closureFrame $ e + where + toClosure (StackFrameIter (# s#, i# #)) = + case unpackClosureFromStackFrame# s# i# of + (# infoTableAddr, heapRep, pointersArray #) -> do + let infoTablePtr = Ptr infoTableAddr + ptrList = [case indexArray# pointersArray i of + (# ptr #) -> Box ptr + | I# i <- [0..I# (sizeofArray# pointersArray) - 1] + ] + + getClosureDataFromHeapRep heapRep infoTablePtr ptrList + unpackStackFrameIter :: StackFrameIter -> StackFrame -unpackStackFrameIter (StackFrameIter (# s, i #)) = - case (toEnum . fromIntegral) (W# (getInfoTableType# s i)) of +unpackStackFrameIter (StackFrameIter (# s#, i# #)) = + case (toEnum . fromIntegral) (W# (getInfoTableType# s# i#)) of RET_BCO -> RetBCO - RET_SMALL -> let (# bitmap#, size# #) = getSmallBitmap# s i + RET_SMALL -> let !(# bitmap#, size# #) = getSmallBitmap# s# i# + bes = toBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #))(W# bitmap#) (W# size#) + payloads = map toBitmapPayload bes in - RetSmall None [] - RET_BIG -> RetBig [] + RetSmall None payloads + RET_BIG -> let !(# bitmapArray#, size# #) = getLargeBitmap# s# i# + bitmapWords :: [Word] = foldrByteArray (\w acc -> W# w : acc) [] bitmapArray# + bes = wordsToBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #)) bitmapWords (trace ("XXX size " ++ show (W# size#))(W# size#)) + payloads = map toBitmapPayload bes + in + RetBig payloads RET_FUN -> RetFun UPDATE_FRAME -> UpdateFrame CATCH_FRAME -> CatchFrame @@ -89,10 +131,33 @@ unpackStackFrameIter (StackFrameIter (# s, i #)) = CATCH_STM_FRAME -> CatchStmFrame x -> error $ "Unexpected closure type on stack: " ++ show x +-- | Right-fold over the elements of a 'ByteArray'. +-- Copied from `primitive` +foldrByteArray :: forall b. (Word# -> b -> b) -> b -> ByteArray# -> b +{-# INLINE foldrByteArray #-} +foldrByteArray f z arr = go 0 + where + go i + | i < maxI = f (indexWordArray# arr (toInt# i)) (go (i + 1)) + | otherwise = z + maxI = sizeofByteArray arr `quot` sizeOf (undefined :: Word) + +-- | Size of the byte array in bytes. +-- Copied from `primitive` +sizeofByteArray :: ByteArray# -> Int +{-# INLINE sizeofByteArray #-} +sizeofByteArray arr# = I# (sizeofByteArray# arr#) + +-- | Unbox 'Int#' from 'Int' +toInt# :: Int -> Int# +toInt# (I# i) = i + -- TODO: Is the function type below needed? (Was proposed by Ben) -- derefStackPtr :: StackSnapshot# -> Int# -> a -foreign import prim "derefStackWordzh" derefStackWord# :: StackSnapshot# -> Int# -> Word# +foreign import prim "unpackClosureFromStackFramezh" unpackClosureFromStackFrame# :: StackSnapshot# -> Word# -> (# Addr#, ByteArray#, Array# b #) + +foreign import prim "derefStackWordzh" derefStackWord# :: StackSnapshot# -> Word# -> Word# data BitmapPayload = Closure CL.Closure | Primitive Word ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -1,3 +1,4 @@ +#include "MachDeps.h" #include "Rts.h" #include "rts/Messages.h" #include "rts/storage/ClosureTypes.h" @@ -93,6 +94,31 @@ StgWord getBitmapWord(StgInfoTable *info){ return bitmapWord; } +StgWord getLargeBitmapSize(StgInfoTable *info){ + StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); + return bitmap->size; +} + +#define ROUNDUP_BITS_TO_WDS(n) (((n) + WORD_SIZE_IN_BITS - 1) / WORD_SIZE_IN_BITS ) + +// Copied from Cmm.h +#define SIZEOF_W SIZEOF_VOID_P +#define WDS(n) ((n)*SIZEOF_W) + +StgArrBytes* getLargeBitmaps(Capability *cap, StgInfoTable *info){ + StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); + StgWord neededWords = ROUNDUP_BITS_TO_WDS(bitmap->size); + StgArrBytes* array = allocate(cap, sizeofW(StgArrBytes) + neededWords); + SET_HDR(array, &stg_ARR_WORDS_info, CCCS); + array->bytes = WDS(ROUNDUP_BITS_TO_WDS(bitmap->size)); + + for(int i = 0; i < neededWords; i++) { + array->payload[i] = bitmap->bitmap[i]; + } + + return array; +} + StgLargeBitmap* getLargeBitmapPtr(const StgInfoTable *info) { return GET_LARGE_BITMAP(info); } ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -72,18 +72,31 @@ getInfoTableTypezh (P_ stack, W_ index) { getSmallBitmapzh(P_ stack, W_ index) { P_ itbl; - itbl = %INFO_PTR(StgStack_sp(stack) + WDS(index)); + itbl = %STD_INFO(%INFO_PTR(StgStack_sp(stack) + WDS(index))); W_ bitmap, size; (bitmap) = ccall getBitmapWord(itbl); (size) = ccall getBitmapSize(itbl); - ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul", bitmap, size); + ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul\n", bitmap, size); return (bitmap, size); } unpackClosureFromStackFramezh(P_ stack, W_ index){ P_ closurePtr; closurePtr = (StgStack_sp(stack) + WDS(index)); - return (stg_unpackClosurezh(closurePtr)); + jump stg_unpackClosurezh(closurePtr); +} + +getLargeBitmapzh(P_ stack, W_ index){ + P_ itbl, stgArrBytes; + W_ size; + itbl = %STD_INFO(%INFO_PTR(StgStack_sp(stack) + WDS(index))); + + (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), itbl); + (size) = ccall getLargeBitmapSize(itbl); + + ccall debugBelch("getLargeBitmapzh - size %ul\n", size); + + return (stgArrBytes, size); } ===================================== rts/Printer.c ===================================== @@ -489,7 +489,7 @@ printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, debugBelch("printSmallBitmap - payload %p\n", payload); debugBelch("printSmallBitmap - bitmap "); printBits(sizeof(StgWord), &bitmap); - debugBelch("printSmallBitmap - size %u\n", size); + debugBelch("printSmallBitmap - size %u, bitmap %ul\n", size, bitmap); uint32_t i; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e2de6a72d4c5bf12b213239877619d252499837...42318ec6950af7308ac720087711f8610aeaea48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1e2de6a72d4c5bf12b213239877619d252499837...42318ec6950af7308ac720087711f8610aeaea48 You're receiving 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 Oct 7 14:44:59 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 07 Oct 2022 10:44:59 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 7 commits: Linker: remove dead code (base, compactor) Message-ID: <63403b6bb2c69_1eea6a5143c571135@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 7a38d5e3 by Sylvain Henry at 2022-10-07T13:43:36+02:00 Linker: remove dead code (base, compactor) - - - - - 9e999499 by Sylvain Henry at 2022-10-07T14:01:25+02:00 Better shims linking - - - - - 87cfb9d3 by Sylvain Henry at 2022-10-07T14:20:30+02:00 Make isJsFile a bit faster by only reading the header - - - - - 04f6c81e by Sylvain Henry at 2022-10-07T15:02:24+02:00 Linker: write directly into output file - - - - - 5aa0a13a by Sylvain Henry at 2022-10-07T15:51:09+02:00 Linker: more refactoring - - - - - dd60ba5f by Sylvain Henry at 2022-10-07T16:11:15+02:00 Lazy loading of JStat in object code - - - - - b9333376 by Sylvain Henry at 2022-10-07T16:32:33+02:00 Use Ppr hack to render directly into a file - - - - - 6 changed files: - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Types.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Types.hs - compiler/GHC/Utils/Ppr.hs Changes: ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -446,7 +446,7 @@ link' logger tmpfs dflags unit_env batch_attempt_linking mHscMessager hpt let lc_cfg = mempty let extra_js = mempty let cfg = initStgToJSConfig dflags - jsLinkBinary lc_cfg cfg extra_js logger tmpfs dflags unit_env obj_files pkg_deps + jsLinkBinary lc_cfg cfg extra_js logger dflags unit_env obj_files pkg_deps | otherwise -> linkBinary logger tmpfs dflags unit_env obj_files pkg_deps LinkStaticLib -> linkStaticLib logger dflags unit_env obj_files pkg_deps LinkDynLib -> linkDynLibCheck logger tmpfs dflags unit_env obj_files pkg_deps @@ -572,7 +572,7 @@ doLink hsc_env o_files = do let lc_cfg = mempty let extra_js = mempty let cfg = initStgToJSConfig dflags - jsLinkBinary lc_cfg cfg extra_js logger tmpfs dflags unit_env o_files [] + jsLinkBinary lc_cfg cfg extra_js logger dflags unit_env o_files [] | otherwise -> linkBinary logger tmpfs dflags unit_env o_files [] LinkStaticLib -> linkStaticLib logger dflags unit_env o_files [] LinkDynLib -> linkDynLibCheck logger tmpfs dflags unit_env o_files [] ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -29,93 +29,79 @@ import Prelude import GHC.Platform.Host (hostPlatformArchOS) -import GHC.StgToJS.Linker.Types -import GHC.StgToJS.Linker.Utils -import GHC.StgToJS.Linker.Compactor -import GHC.StgToJS.Linker.Shims +import GHC.JS.Syntax -import GHC.StgToJS.Rts.Rts +import GHC.Driver.Session (DynFlags(..)) +import Language.Haskell.Syntax.Module.Name -import GHC.JS.Syntax +import GHC.Linker.Static.Utils (exeFileName) + +import GHC.StgToJS.Linker.Types +import GHC.StgToJS.Linker.Utils +import GHC.StgToJS.Linker.Compactor +import GHC.StgToJS.Rts.Rts +import GHC.StgToJS.Object +import GHC.StgToJS.Types hiding (LinkableUnit) +import GHC.StgToJS.UnitUtils +import GHC.StgToJS.Printer + +import GHC.Unit.State +import GHC.Unit.Env +import GHC.Unit.Home +import GHC.Unit.Types +import GHC.Unit.Module (moduleStableString) -import GHC.StgToJS.Object -import GHC.StgToJS.Types hiding (LinkableUnit) -import GHC.StgToJS.UnitUtils -import GHC.StgToJS.Printer +import GHC.Utils.Encoding +import GHC.Utils.Outputable hiding ((<>)) +import GHC.Utils.Panic +import GHC.Utils.Error +import GHC.Utils.Logger (Logger, logVerbAtLeast) +import GHC.Utils.Binary +import qualified GHC.Utils.Ppr as Ppr +import GHC.Utils.CliOption +import GHC.Utils.Monad import qualified GHC.SysTools.Ar as Ar -import GHC.Utils.Encoding -import GHC.Utils.Outputable hiding ((<>)) -import GHC.Utils.Panic -import GHC.Unit.State -import GHC.Unit.Env -import GHC.Unit.Home -import GHC.Unit.Types -import GHC.Utils.Error -import GHC.Data.FastString - -import Control.Concurrent.MVar -import Control.Monad - -import Data.Array + +import GHC.Data.FastString + +import Control.Concurrent.MVar +import Control.Monad + +import Data.Array import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy.Char8 as BLC import qualified Data.ByteString.Lazy as BL -import Data.Function (on) -import Data.Int -import Data.IntSet (IntSet) +import Data.Function (on) +import Data.IntSet (IntSet) import qualified Data.IntSet as IS -import Data.IORef -import Data.List ( partition, nub, intercalate, group, sort - , groupBy, intersperse - ) -import Data.Map.Strict (Map) +import Data.IORef +import Data.List ( partition, nub, intercalate, group, sort + , groupBy, intersperse + ) +import Data.Map.Strict (Map) import qualified Data.Map.Strict as M -import Data.Maybe -import Data.Set (Set) +import Data.Maybe +import Data.Set (Set) import qualified Data.Set as S -import Data.Word - -import GHC.Generics (Generic) - -import System.FilePath ((<.>), (), dropExtension) -import System.Directory ( createDirectoryIfMissing - , doesFileExist - , getCurrentDirectory - , Permissions(..) - , setPermissions - , getPermissions - ) - -import GHC.Driver.Session (DynFlags(..)) -import Language.Haskell.Syntax.Module.Name -import GHC.Unit.Module (moduleStableString) -import GHC.Utils.Logger (Logger, logVerbAtLeast) -import GHC.Utils.TmpFs (TmpFs) -import GHC.Utils.Binary -import GHC.Utils.Ppr (Style(..), renderStyle, Mode(..)) -import GHC.Utils.CliOption -import GHC.Utils.Monad - -import GHC.Linker.Static.Utils (exeFileName) - -newtype LinkerStats = LinkerStats - { bytesPerModule :: Map Module Word64 -- ^ number of bytes linked per module +import Data.Word + +import System.IO +import System.FilePath ((<.>), (), dropExtension) +import System.Directory ( createDirectoryIfMissing + , doesFileExist + , getCurrentDirectory + , Permissions(..) + , setPermissions + , getPermissions + ) + +data LinkerStats = LinkerStats + { bytesPerModule :: !(Map Module Word64) -- ^ number of bytes linked per module + , packedMetaDataSize :: !Word64 -- ^ number of bytes for metadata } --- | result of a link pass -data LinkResult = LinkResult - { linkOut :: FilePath -> IO () -- ^ compiled Haskell code - , linkOutStats :: LinkerStats -- ^ statistics about generated code - , linkOutMetaSize :: Int64 -- ^ size of packed metadata in generated code - , linkForeignRefs :: [ForeignJSRef] -- ^ foreign code references in compiled haskell code - , linkLibRTS :: [FilePath] -- ^ library code to load with the RTS - , linkLibA :: [FilePath] -- ^ library code to load after RTS - , linkLibAArch :: [FilePath] -- ^ library code to load from archives after RTS - , linkBase :: Base -- ^ base metadata to use if we want to link incrementally against this result - } deriving (Generic) - newtype ArchiveState = ArchiveState { loadedArchives :: IORef (Map FilePath Ar.Archive) } emptyArchiveState :: IO ArchiveState @@ -126,33 +112,30 @@ jsLinkBinary -> StgToJSConfig -> [FilePath] -> Logger - -> TmpFs -> DynFlags -> UnitEnv -> [FilePath] -> [UnitId] -> IO () -jsLinkBinary lc_cfg cfg js_srcs logger tmpfs dflags u_env objs dep_pkgs = do - -- additional objects to link are passed as FileOption ldInputs... - let cmdline_objs = [ f | FileOption _ f <- ldInputs dflags ] - -- discriminate JavaScript sources from real object files. - (cmdline_js_srcs, cmdline_js_objs) <- partitionM isJsFile cmdline_objs - let - objs' = map ObjFile (objs ++ cmdline_js_objs) - js_srcs' = js_srcs ++ cmdline_js_srcs - isRoot _ = True - exe = jsExeFileName dflags - - env <- newGhcjsEnv - void $ link env lc_cfg cfg logger tmpfs dflags u_env exe mempty dep_pkgs objs' js_srcs' isRoot mempty +jsLinkBinary lc_cfg cfg js_srcs logger dflags u_env objs dep_pkgs + | lcNoJSExecutables lc_cfg = return () + | otherwise = do + -- additional objects to link are passed as FileOption ldInputs... + let cmdline_objs = [ f | FileOption _ f <- ldInputs dflags ] + -- discriminate JavaScript sources from real object files. + (cmdline_js_srcs, cmdline_js_objs) <- partitionM isJsFile cmdline_objs + let + objs' = map ObjFile (objs ++ cmdline_js_objs) + js_srcs' = js_srcs ++ cmdline_js_srcs + isRoot _ = True + exe = jsExeFileName dflags + + void $ link lc_cfg cfg logger u_env exe mempty dep_pkgs objs' js_srcs' isRoot mempty -- | link and write result to disk (jsexe directory) -link :: GhcjsEnv - -> JSLinkConfig +link :: JSLinkConfig -> StgToJSConfig -> Logger - -> TmpFs - -> DynFlags -> UnitEnv -> FilePath -- ^ output file/directory -> [FilePath] -- ^ include path for home package @@ -162,193 +145,153 @@ link :: GhcjsEnv -> (ExportedFun -> Bool) -- ^ functions from the objects to use as roots (include all their deps) -> Set ExportedFun -- ^ extra symbols to link in -> IO () -link env lc_cfg cfg logger tmpfs dflags unit_env out include pkgs objFiles jsFiles isRootFun extraStaticDeps - | lcNoJSExecutables lc_cfg = return () - | otherwise = do - link_res <- link' env lc_cfg cfg logger unit_env out include pkgs objFiles jsFiles - isRootFun extraStaticDeps +link lc_cfg cfg logger unit_env out _include units objFiles jsFiles isRootFun extraStaticDeps = do - let genBase = isJust (lcGenBase lc_cfg) - jsExt | genBase = "base.js" - | otherwise = "js" + -- create output directory createDirectoryIfMissing False out - linkOut link_res (out "out" <.> jsExt) + + ------------------------------------------------------------- + -- link all Haskell code (program + dependencies) into out.js + + -- compute dependencies + (dep_map, dep_units, all_deps, rts_wired_functions, dep_archives) + <- computeLinkDependencies cfg logger out unit_env units objFiles extraStaticDeps isRootFun + + -- retrieve code for dependencies + mods <- collectDeps dep_map dep_units all_deps + + -- LTO + rendering of JS code + link_stats <- withBinaryFile (out "out.js") WriteMode $ \h -> do + (_compactorState, stats) <- renderLinker lc_cfg cfg h emptyCompactorState rts_wired_functions mods jsFiles + pure stats + + ------------------------------------------------------------- -- dump foreign references file (.frefs) unless (lcOnlyOut lc_cfg) $ do - let frefsFile = if genBase then "out.base.frefs" else "out.frefs" - jsonFrefs = mempty + let frefsFile = "out.frefs" + -- frefs = concatMap mc_frefs mods + jsonFrefs = mempty -- FIXME: toJson frefs BL.writeFile (out frefsFile <.> "json") jsonFrefs BL.writeFile (out frefsFile <.> "js") ("h$checkForeignRefs(" <> jsonFrefs <> ");") - -- dump stats - unless (lcNoStats lc_cfg) $ do - let statsFile = if genBase then "out.base.stats" else "out.stats" - let stats = linkerStats (linkOutMetaSize link_res) (linkOutStats link_res) - writeFile (out statsFile) stats - - -- link with the RTS - unless (lcNoRts lc_cfg) $ do - BL.writeFile (out "rts.js") ( BLC.pack rtsDeclsText - <> BLC.pack (rtsText cfg)) - - let all_lib_js = linkLibA link_res - lla' <- streamShims <$> readShimFiles logger tmpfs dflags unit_env all_lib_js - llarch' <- mapM readShimsArchive (linkLibAArch link_res) - let lib_js = BL.fromChunks $! llarch' ++ lla' - BL.writeFile (out "lib" <.> jsExt) lib_js - - if genBase - then panic "support for base bundle not implemented" - -- generateBase out (linkBase link_res) - else when ( not (lcOnlyOut lc_cfg) - && not (lcNoRts lc_cfg) - && not (usingBase lc_cfg) - ) - $ do - _ <- combineFiles lc_cfg out - writeHtml out - writeRunMain out - writeRunner lc_cfg out - writeExterns out - -readShimsArchive :: FilePath -> IO B.ByteString -readShimsArchive ar_file = do - (Ar.Archive entries) <- Ar.loadAr ar_file - jsdata <- catMaybes <$> mapM readEntry entries - return (B.intercalate "\n" jsdata) - where - readEntry :: Ar.ArchiveEntry -> IO (Maybe B.ByteString) - readEntry ar_entry - | isJsArchiveEntry ar_entry = pure $ Just (Ar.filedata ar_entry) - | otherwise = pure Nothing - - - --- | link in memory -link' :: GhcjsEnv - -> JSLinkConfig - -> StgToJSConfig - -> Logger - -> UnitEnv - -> String -- ^ target (for progress message) - -> [FilePath] -- ^ include path for home package - -> [UnitId] -- ^ packages to link - -> [LinkedObj] -- ^ the object files we're linking - -> [FilePath] -- ^ extra js files to include - -> (ExportedFun -> Bool) -- ^ functions from the objects to use as roots (include all their deps) - -> Set ExportedFun -- ^ extra symbols to link in - -> IO LinkResult -link' env lc_cfg cfg logger unit_env target _include pkgs objFiles jsFiles isRootFun extraStaticDeps - = do - let ue_state = ue_units $ unit_env - (objDepsMap, objRequiredUnits) <- loadObjDeps objFiles - - let rootSelector | Just baseMod <- lcGenBase lc_cfg = - \(ExportedFun m _s) -> m == baseMod - | otherwise = isRootFun - roots = S.fromList . filter rootSelector $ concatMap (M.keys . depsHaskellExported . fst) (M.elems objDepsMap) - rootMods = map (moduleNameString . moduleName . head) . group . sort . map funModule . S.toList $ roots - objPkgs = map moduleUnitId $ nub (M.keys objDepsMap) - - when (logVerbAtLeast logger 2) $ void $ - compilationProgressMsg logger . text $ - case lcGenBase lc_cfg of - Just baseMod -> "Linking base bundle " ++ target ++ " (" ++ moduleNameString (moduleName baseMod) ++ ")" - _ -> "Linking " ++ target ++ " (" ++ intercalate "," rootMods ++ ")" - - base <- case lcUseBase lc_cfg of - NoBase -> return emptyBase - BaseFile _file -> panic "support for base bundle not implemented" -- loadBase file - BaseState b -> return b - - let (rts_wired_units, rts_wired_functions) = rtsDeps pkgs - - let preload_units = preloadUnits (ue_units unit_env) - - -- all the units we want to link together, without their dependencies - let root_units = nub (preload_units ++ rts_wired_units ++ reverse objPkgs ++ reverse pkgs) - - -- all the units we want to link together, including their dependencies - let all_units = transitive_units root_units - - -- compute transitive unit dependencies - transitive_units = reverse . transitive_units_ [] - transitive_units_ xs = \case - [] -> xs - (u:us) - | u == mainUnitId -> transitive_units_ (u:xs) us - | otherwise -> case lookupUnitId ue_state u of - Nothing -> unit_not_found u - Just d -> - let deps = unitDepends d - is_new_dep x = x `notElem` xs - new_deps = filter is_new_dep deps - in case new_deps of - [] - | u `elem` xs -> transitive_units_ xs us - | otherwise -> transitive_units_ (u:xs) us - ds -> transitive_units_ xs (ds ++ (u:us)) - - unit_not_found u = throwGhcException (CmdLineError ("unknown unit: " ++ unpackFS (unitIdFS u))) - - let - -- units that weren't already linked in the base bundle - -- (or all of them, if no base bundle) - bundle_diff = filter (not . is_in_bundle) all_units - is_in_bundle uid = uid `elem` basePkgs base - - (archsDepsMap, archsRequiredUnits) <- loadArchiveDeps env =<< getPackageArchives cfg (map snd $ mkPkgLibPaths ue_state all_units) - pkgArchs <- getPackageArchives cfg (map snd $ mkPkgLibPaths ue_state bundle_diff) - - when (logVerbAtLeast logger 2) $ - logInfo logger $ hang (text "Linking with archives:") 2 (vcat (fmap text pkgArchs)) + -- dump stats + unless (lcNoStats lc_cfg) $ do + let statsFile = "out.stats" + writeFile (out statsFile) (renderLinkerStats link_stats) + + -- link generated RTS parts into rts.js + unless (lcNoRts lc_cfg) $ do + BL.writeFile (out "rts.js") ( BLC.pack rtsDeclsText + <> BLC.pack (rtsText cfg)) + + -- link dependencies' JS files into lib.js + withBinaryFile (out "lib.js") WriteMode $ \h -> do + forM_ dep_archives $ \archive_file -> do + Ar.Archive entries <- Ar.loadAr archive_file + forM_ entries $ \entry -> do + case getJsArchiveEntry entry of + Nothing -> return () + Just bs -> do + B.hPut h bs + hPutChar h '\n' + + -- link everything together into all.js + when (generateAllJs lc_cfg) $ do + _ <- combineFiles lc_cfg out + writeHtml out + writeRunMain out + writeRunner lc_cfg out + writeExterns out + + +computeLinkDependencies + :: StgToJSConfig + -> Logger + -> String + -> UnitEnv + -> [UnitId] + -> [LinkedObj] + -> Set ExportedFun + -> (ExportedFun -> Bool) + -> IO (Map Module (Deps, DepsLocation), [UnitId], Set LinkableUnit, Set ExportedFun, [FilePath]) +computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDeps isRootFun = do + env <- newGhcjsEnv + (objDepsMap, objRequiredUnits) <- loadObjDeps objFiles - -- compute dependencies - let dep_units = all_units ++ [homeUnitId (ue_unsafeHomeUnit $ unit_env)] - dep_map = objDepsMap `M.union` archsDepsMap - excluded_units = baseUnits base -- already linked units - dep_fun_roots = roots `S.union` rts_wired_functions `S.union` extraStaticDeps - dep_unit_roots = archsRequiredUnits ++ objRequiredUnits + let roots = S.fromList . filter isRootFun $ concatMap (M.keys . depsHaskellExported . fst) (M.elems objDepsMap) + rootMods = map (moduleNameString . moduleName . head) . group . sort . map funModule . S.toList $ roots + objPkgs = map moduleUnitId $ nub (M.keys objDepsMap) - all_deps <- getDeps (fmap fst dep_map) excluded_units dep_fun_roots dep_unit_roots + when (logVerbAtLeast logger 2) $ void $ + compilationProgressMsg logger $ hcat + [ text "Linking ", text target, text " (", text (intercalate "," rootMods), char ')' ] - when (logVerbAtLeast logger 2) $ - logInfo logger $ hang (text "Units to link:") 2 (vcat (fmap ppr dep_units)) - -- logInfo logger $ hang (text "All deps:") 2 (vcat (fmap ppr (S.toList all_deps))) + let (rts_wired_units, rts_wired_functions) = rtsDeps units - -- retrieve code for dependencies - code <- collectDeps dep_map dep_units all_deps - - (outJs, metaSize, compactorState, stats) <- renderLinker lc_cfg cfg (baseCompactorState base) rts_wired_functions code jsFiles - let base' = Base compactorState (nub $ basePkgs base ++ bundle_diff) - (all_deps `S.union` baseUnits base) - - return $ LinkResult - { linkOut = outJs - , linkOutStats = stats - , linkOutMetaSize = metaSize - , linkForeignRefs = concatMap mc_frefs code - , linkLibRTS = [] -- (filter (`notElem` alreadyLinkedBefore) shimsBefore) - , linkLibA = [] -- (filter (`notElem` alreadyLinkedAfter) shimsAfter) - , linkLibAArch = pkgArchs - , linkBase = base' - } - where + let ue_state = ue_units $ unit_env + let preload_units = preloadUnits (ue_units unit_env) + + -- all the units we want to link together, without their dependencies + let root_units = nub (preload_units ++ rts_wired_units ++ reverse objPkgs ++ reverse units) - mkPkgLibPaths :: UnitState -> [UnitId] -> [(UnitId, ([FilePath],[String]))] - mkPkgLibPaths u_st - = map (\k -> ( k - , (getInstalledPackageLibDirs u_st k - , getInstalledPackageHsLibs u_st k) - )) + -- all the units we want to link together, including their dependencies + let all_units = transitive_units root_units + + -- compute transitive unit dependencies + transitive_units = reverse . transitive_units_ [] + transitive_units_ xs = \case + [] -> xs + (u:us) + | u == mainUnitId -> transitive_units_ (u:xs) us + | otherwise -> case lookupUnitId ue_state u of + Nothing -> unit_not_found u + Just d -> + let deps = unitDepends d + is_new_dep x = x `notElem` xs + new_deps = filter is_new_dep deps + in case new_deps of + [] + | u `elem` xs -> transitive_units_ xs us + | otherwise -> transitive_units_ (u:xs) us + ds -> transitive_units_ xs (ds ++ (u:us)) + + unit_not_found u = throwGhcException (CmdLineError ("unknown unit: " ++ unpackFS (unitIdFS u))) + + mkPkgLibPaths :: UnitState -> [UnitId] -> [(UnitId, ([FilePath],[String]))] + mkPkgLibPaths u_st + = map (\k -> ( k + , (getInstalledPackageLibDirs u_st k + , getInstalledPackageHsLibs u_st k) + )) + + dep_archives <- getPackageArchives cfg (map snd $ mkPkgLibPaths ue_state all_units) + (archsDepsMap, archsRequiredUnits) <- loadArchiveDeps env dep_archives + + when (logVerbAtLeast logger 2) $ + logInfo logger $ hang (text "Linking with archives:") 2 (vcat (fmap text dep_archives)) + + -- compute dependencies + let dep_units = all_units ++ [homeUnitId (ue_unsafeHomeUnit $ unit_env)] + dep_map = objDepsMap `M.union` archsDepsMap + excluded_units = S.empty + dep_fun_roots = roots `S.union` rts_wired_functions `S.union` extraStaticDeps + dep_unit_roots = archsRequiredUnits ++ objRequiredUnits + + all_deps <- getDeps (fmap fst dep_map) excluded_units dep_fun_roots dep_unit_roots + + when (logVerbAtLeast logger 2) $ + logInfo logger $ hang (text "Units to link:") 2 (vcat (fmap ppr dep_units)) + -- logInfo logger $ hang (text "All deps:") 2 (vcat (fmap ppr (S.toList all_deps))) + + return (dep_map, dep_units, all_deps, rts_wired_functions, dep_archives) data ModuleCode = ModuleCode { mc_module :: !Module - , mc_js_code :: !JStat + , mc_js_code :: JStat , mc_exports :: !B.ByteString -- ^ rendered exports , mc_closures :: ![ClosureInfo] , mc_statics :: ![StaticInfo] @@ -358,12 +301,13 @@ data ModuleCode = ModuleCode renderLinker :: JSLinkConfig -> StgToJSConfig + -> Handle -> CompactorState -> Set ExportedFun -> [ModuleCode] -- ^ linked code per module -> [FilePath] -- ^ additional JS files - -> IO (FilePath -> IO (), Int64, CompactorState, LinkerStats) -renderLinker settings cfg renamer_state rtsDeps code jsFiles = do + -> IO (CompactorState, LinkerStats) +renderLinker settings cfg h renamer_state rtsDeps mods jsFiles = do -- extract ModuleCode fields required to make a LinkedUnit let code_to_linked_unit c = LinkedUnit @@ -375,47 +319,53 @@ renderLinker settings cfg renamer_state rtsDeps code jsFiles = do -- call the compactor let (renamer_state', compacted, meta) = compact settings cfg renamer_state (map ((\(LexicalFastString f) -> f) . funSymbol) $ S.toList rtsDeps) - (map code_to_linked_unit code) - - js_files_contents <- mconcat <$> mapM BL.readFile jsFiles + (map code_to_linked_unit mods) let - render_all fp = do - BL.writeFile fp (rendered_all <> js_files_contents) - - -- render result into JS code - rendered_all = mconcat [mconcat rendered_mods, rendered_meta, rendered_exports] - rendered_mods = fmap render_js compacted - rendered_meta = render_js meta - doc_str = renderStyle (Style - { lineLength = 100 - , ribbonsPerLine = 1.5 - , mode = LeftMode - -- Faster to write but uglier code. - -- Use "PageMode False" to enable nicer code instead - }) - render_js x = BL.fromChunks [BC.pack (doc_str (pretty x)), BC.pack "\n"] - rendered_exports = BL.fromChunks (map mc_exports code) - meta_length = fromIntegral (BL.length rendered_meta) - -- make LinkerStats entry for the given ModuleCode. - -- For now, only associate generated code size in bytes to each module - mk_stat c b = (mc_module c, fromIntegral . BL.length $ b) - stats = LinkerStats $ M.fromList $ zipWith mk_stat code rendered_mods - - pure - ( render_all - , meta_length - , renamer_state' - , stats - ) + putBS = B.hPut h + putJS x = do + before <- hTell h + Ppr.printLeftRender h (pretty x) + hPutChar h '\n' + after <- hTell h + pure $! (after - before) + + --------------------------------------------------------- + -- Pretty-print JavaScript code for all the dependencies. + -- + -- We have to pretty-print at link time because we want to be able to perform + -- global link-time optimisations (e.g. renamings) on the whole generated JS + -- file. + + -- modules themselves + mod_sizes <- forM (mods `zip` compacted) $ \(mod,compacted_mod) -> do + !mod_size <- fromIntegral <$> putJS compacted_mod + let !mod_mod = mc_module mod + pure (mod_mod, mod_size) + + -- metadata + !meta_length <- fromIntegral <$> putJS meta + + -- exports + mapM_ (putBS . mc_exports) mods + + -- explicit additional JS files + mapM_ (\i -> B.readFile i >>= putBS) jsFiles + + -- stats + let link_stats = LinkerStats + { bytesPerModule = M.fromList mod_sizes + , packedMetaDataSize = meta_length + } + + pure (renamer_state', link_stats) -- | Render linker stats -linkerStats :: Int64 -- ^ code size of packed metadata - -> LinkerStats -- ^ code size per module - -> String -linkerStats meta s = +renderLinkerStats :: LinkerStats -> String +renderLinkerStats s = intercalate "\n\n" [meta_stats, package_stats, module_stats] <> "\n\n" where + meta = packedMetaDataSize s meta_stats = "number of modules: " <> show (length bytes_per_mod) <> "\npacked metadata: " <> show meta @@ -453,18 +403,19 @@ getPackageArchives cfg pkgs = profSuff | csProf cfg = "_p" | otherwise = "" -{- | convenience: combine rts.js, lib.js, out.js to all.js that can be run - directly with node.js or SpiderMonkey jsshell - -} + +-- | Combine rts.js, lib.js, out.js to all.js that can be run +-- directly with node.js or SpiderMonkey jsshell combineFiles :: JSLinkConfig -> FilePath -> IO () combineFiles cfg fp = do - files <- mapM (B.readFile.(fp)) ["rts.js", "lib.js", "out.js"] - let runMain - | lcNoHsMain cfg = mempty - | otherwise = runMainJS - writeBinaryFile (fp"all.js") (mconcat (files ++ [runMain])) + let files = map (fp ) ["rts.js", "lib.js", "out.js"] + withBinaryFile (fp "all.js") WriteMode $ \h -> do + let cpy i = B.readFile i >>= B.hPut h + mapM_ cpy files + unless (lcNoHsMain cfg) $ do + B.hPut h runMainJS -- | write the index.html file that loads the program if it does not exit writeHtml @@ -808,20 +759,30 @@ loadArchiveDeps' archives = do pure $ Just (deps, ArchiveFile ar_file) -- | Predicate to check that an entry in Ar is a JS source -isJsArchiveEntry :: Ar.ArchiveEntry -> Bool -isJsArchiveEntry entry = isJsBS (Ar.filedata entry) +-- and to return it without its header +getJsArchiveEntry :: Ar.ArchiveEntry -> Maybe B.ByteString +getJsArchiveEntry entry = getJsBS (Ar.filedata entry) -- | Predicate to check that a file is a JS source isJsFile :: FilePath -> IO Bool -isJsFile fp = isJsBS <$> B.readFile fp +isJsFile fp = withBinaryFile fp ReadMode $ \h -> do + bs <- B.hGet h jsHeaderLength + pure (isJsBS bs) isJsBS :: B.ByteString -> Bool -isJsBS bs = B.take (B.length jsHeader) bs == jsHeader - where - -- Header added to JS sources to discriminate them from other object files. - -- They all have .o extension but JS sources have this header. - jsHeader :: B.ByteString - jsHeader = "//JavaScript" +isJsBS bs = isJust (getJsBS bs) + +-- | Get JS source with its header (if it's one) +getJsBS :: B.ByteString -> Maybe B.ByteString +getJsBS bs = B.stripPrefix jsHeader bs + +-- Header added to JS sources to discriminate them from other object files. +-- They all have .o extension but JS sources have this header. +jsHeader :: B.ByteString +jsHeader = "//JavaScript" + +jsHeaderLength :: Int +jsHeaderLength = B.length jsHeader ===================================== compiler/GHC/StgToJS/Linker/Types.hs ===================================== @@ -15,23 +15,6 @@ -- Josh Meredith -- Stability : experimental -- --- A base bundle is used for incremental linking. it contains information about --- the symbols that have already been linked. These symbols are not included --- again in the incrementally linked program. --- --- The Base data structure contains the information we need to do incremental --- linking against a base bundle. --- --- base file format: --- - GHCJSBASE --- - [renamer state] --- - [linkedPackages] --- - [packages] --- - [modules] --- - [symbols] --- --- The base contains a CompactorState for consistent renaming of private names --- and packed initialization of info tables and static closures. ----------------------------------------------------------------------------- module GHC.StgToJS.Linker.Types where @@ -41,10 +24,7 @@ import GHC.StgToJS.Object import GHC.StgToJS.Types (ClosureInfo, StaticInfo) import GHC.Unit.Types -import GHC.Utils.Outputable hiding ((<>)) import GHC.Data.FastString -import GHC.Driver.Env.Types (HscEnv) -import GHC.Types.Error (Messages) import GHC.Types.Unique.Map import Control.Monad @@ -54,14 +34,10 @@ import Data.ByteString (ByteString) import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Set (Set) -import qualified Data.Set as S -import qualified Data.IntMap as I import Control.Concurrent.MVar -import qualified Control.Exception as E import System.IO -import System.Process import Prelude @@ -279,72 +255,6 @@ addLabel new cs = newCnt = cnt + 1 in cs {csEntries = newLabels, csNumLabels = newCnt} - --------------------------------------------------------------------------------- --- Base --------------------------------------------------------------------------------- - --- | The Base bundle. Used for incremental linking it maintains the compactor --- state the base packages and units. -data Base = Base { baseCompactorState :: CompactorState - , basePkgs :: [UnitId] - , baseUnits :: Set (Module, Int) - } - --- | Custom Show for the @Base@ bundle -showBase :: Base -> String -showBase b = unlines - [ "Base:" - , " packages: " ++ showSDocUnsafe (ppr (basePkgs b)) - , " number of units: " ++ show (S.size $ baseUnits b) - , " renaming table size: " ++ - show (sizeUniqMap . csNameMap . baseCompactorState $ b) - ] - --- | The empty @Base@ bundle -emptyBase :: Base -emptyBase = Base emptyCompactorState [] S.empty - --- | make a @Base@ state from a @CompactorState@: empty the current symbols --- sets, move everything to the parent -makeCompactorParent :: CompactorState -> CompactorState -makeCompactorParent (CompactorState is nm es nes ss nss ls nls pes pss pls sts) - = CompactorState is - nm - emptyUniqMap 0 - emptyUniqMap 0 - emptyUniqMap 0 - (plusUniqMap (fmap (+nes) pes) es) - (plusUniqMap (fmap (+nss) pss) ss) - (plusUniqMap (fmap (+nls) pls) ls) - sts - --- | There are 3 ways the linker can use @Base at . We can not use it, and thus not --- do any incremental linking. We can load it from a file, where we assume that --- the symbols from the bundle and their dependencies have already been loaded. --- In this case We must save the CompactorState so that we can do consistent --- renaming. Or we can use a Base that is already in memory. --- --- Incremental linking greatly improves link time and can also be used in --- multi-page or repl-type applications to serve most of the code from a static --- location, reloading only the small parts that are actually different. -data UseBase = NoBase -- ^ don't use incremental linking - | BaseFile FilePath -- ^ load base from file - | BaseState Base -- ^ use this base - -instance Show UseBase where - show NoBase = "NoBase" - show BaseFile {} = "BaseFile" - show BaseState {} = "BaseState" - -instance Monoid UseBase where - mempty = NoBase - -instance Semigroup UseBase where - x <> NoBase = x - _ <> x = x - - -------------------------------------------------------------------------------- -- Linker Config -------------------------------------------------------------------------------- @@ -361,53 +271,57 @@ data JSLinkConfig = , lcOnlyOut :: Bool , lcNoRts :: Bool , lcNoStats :: Bool - , lcGenBase :: Maybe Module -- ^ base module - , lcUseBase :: UseBase , lcLinkJsLib :: Maybe String , lcJsLibOutputDir :: Maybe FilePath , lcJsLibSrcs :: [FilePath] , lcDedupe :: Bool } --- | Check if we are using the @Base@ bundle, or not. -usingBase :: JSLinkConfig -> Bool -usingBase s | NoBase <- lcUseBase s = False - | otherwise = True - -- | we generate a runnable all.js only if we link a complete application, -- no incremental linking and no skipped parts generateAllJs :: JSLinkConfig -> Bool -generateAllJs s - | NoBase <- lcUseBase s = not (lcOnlyOut s) && not (lcNoRts s) - | otherwise = False +generateAllJs s = not (lcOnlyOut s) && not (lcNoRts s) instance Monoid JSLinkConfig where - mempty = JSLinkConfig False False False False False - Nothing Nothing Nothing False - False False Nothing NoBase - Nothing Nothing mempty False + mempty = JSLinkConfig + { lcNativeExecutables = False + , lcNativeToo = False + , lcBuildRunner = False + , lcNoJSExecutables = False + , lcNoHsMain = False + , lcStripProgram = Nothing + , lcLogCommandLine = Nothing + , lcGhc = Nothing + , lcOnlyOut = False + , lcNoRts = False + , lcNoStats = False + , lcLinkJsLib = Nothing + , lcJsLibOutputDir = Nothing + , lcJsLibSrcs = mempty + , lcDedupe = False + } instance Semigroup JSLinkConfig where - (<>) (JSLinkConfig ne1 nn1 bc1 nj1 noHs1 sp1 lc1 gh1 oo1 nr1 ns1 gb1 ub1 ljsl1 jslo1 jslsrc1 dd1) - (JSLinkConfig ne2 nn2 bc2 nj2 noHs2 sp2 lc2 gh2 oo2 nr2 ns2 gb2 ub2 ljsl2 jslo2 jslsrc2 dd2) = - JSLinkConfig (ne1 || ne2) - (nn1 || nn2) - (bc1 || bc2) - (nj1 || nj2) - (noHs1 || noHs2) - (sp1 `mplus` sp2) - (lc1 `mplus` lc2) - (gh1 `mplus` gh2) - (oo1 || oo2) - (nr1 || nr2) - (ns1 || ns2) - (gb1 `mplus` gb2) - (ub1 <> ub2) - (ljsl1 <> ljsl2) - (jslo1 <> jslo2) - (jslsrc1 <> jslsrc2) - (dd1 || dd2) - + (<>) c1 c2 = + let comb :: (a -> a -> a) -> (JSLinkConfig -> a) -> a + comb f a = f (a c1) (a c2) + in JSLinkConfig + { lcNativeExecutables = comb (||) lcNativeExecutables + , lcNativeToo = comb (||) lcNativeToo + , lcBuildRunner = comb (||) lcBuildRunner + , lcNoJSExecutables = comb (||) lcNoJSExecutables + , lcNoHsMain = comb (||) lcNoHsMain + , lcStripProgram = comb mplus lcStripProgram + , lcLogCommandLine = comb mplus lcLogCommandLine + , lcGhc = comb mplus lcGhc + , lcOnlyOut = comb (||) lcOnlyOut + , lcNoRts = comb (||) lcNoRts + , lcNoStats = comb (||) lcNoStats + , lcLinkJsLib = comb (<>) lcLinkJsLib + , lcJsLibOutputDir = comb (<>) lcJsLibOutputDir + , lcJsLibSrcs = comb (<>) lcJsLibSrcs + , lcDedupe = comb (||) lcDedupe + } -------------------------------------------------------------------------------- -- Linker Environment @@ -430,68 +344,13 @@ data LinkedObj | ObjLoaded String Object -- ^ already loaded: description and payload data GhcjsEnv = GhcjsEnv - { compiledModules :: MVar (Map Module ByteString) -- ^ keep track of already compiled modules so we don't compile twice for dynamic-too - , thRunners :: MVar THRunnerState -- ^ template haskell runners - , thSplice :: MVar Int - , linkerArchiveDeps :: MVar (Map (Set FilePath) + { linkerArchiveDeps :: MVar (Map (Set FilePath) (Map Module (Deps, DepsLocation) , [LinkableUnit] ) ) - , pluginState :: MVar (Maybe HscEnv) } -- | return a fresh @GhcjsEnv@ newGhcjsEnv :: IO GhcjsEnv newGhcjsEnv = GhcjsEnv <$> newMVar M.empty - <*> newMVar emptyTHRunnerState - <*> newMVar 0 - <*> newMVar M.empty - <*> newMVar Nothing - - --------------------------------------------------------------------------------- --- Template Haskell --------------------------------------------------------------------------------- - -data THRunnerState = THRunnerState - { activeRunners :: Map String THRunner - , idleRunners :: [THRunner] - } - -data THRunner = - THRunner { thrProcess :: ProcessHandle - , thrHandleIn :: Handle - , thrHandleErr :: Handle - , thrBase :: MVar Base - , thrRecover :: MVar [Messages String] - , thrExceptions :: MVar (I.IntMap E.SomeException) - } - -emptyTHRunnerState :: THRunnerState -emptyTHRunnerState = THRunnerState mempty mempty - - --------------------------------------------------------------------------------- --- Template Haskell helpers --------------------------------------------------------------------------------- - --- | Add an idle runner to the set of @idleRunners@ in @THRunnerState@ -consIdleRunner :: THRunner -> THRunnerState -> THRunnerState -consIdleRunner r s = s { idleRunners = r : idleRunners s } - --- | Remove an idle runner from the set of @idleRunners@ in @THRunnerState@ -unconsIdleRunner :: THRunnerState -> Maybe (THRunner, THRunnerState) -unconsIdleRunner s - | (r:xs) <- idleRunners s = Just (r, s { idleRunners = xs }) - | otherwise = Nothing - --- | Remove an active runner from the set of @activeRunners@ in @THRunnerState@ -deleteActiveRunner :: String -> THRunnerState -> THRunnerState -deleteActiveRunner m s = - s { activeRunners = M.delete m (activeRunners s) } - --- | Add an active runner to the set of @activeRunners@ in @THRunnerState@ -insertActiveRunner :: String -> THRunner -> THRunnerState -> THRunnerState -insertActiveRunner m runner s = - s { activeRunners = M.insert m runner (activeRunners s) } ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -168,7 +168,7 @@ putObjUnit :: BinHandle -> ObjUnit -> IO () putObjUnit bh (ObjUnit _syms b c d e f g) = do put_ bh b put_ bh c - put_ bh d + lazyPut bh d put_ bh e put_ bh f put_ bh g @@ -179,11 +179,19 @@ getObjUnit :: [FastString] -> BinHandle -> IO ObjUnit getObjUnit syms bh = do b <- get bh c <- get bh - d <- get bh + d <- lazyGet bh e <- get bh f <- get bh g <- get bh - pure (ObjUnit syms b c d e f g) + pure $ ObjUnit + { oiSymbols = syms + , oiClInfo = b + , oiStatic = c + , oiStat = d + , oiRaw = e + , oiFExports = f + , oiFImports = g + } -- | A tag that determines the kind of payload in the .o file. See ===================================== compiler/GHC/StgToJS/Types.hs ===================================== @@ -318,7 +318,7 @@ data ObjUnit = ObjUnit { oiSymbols :: ![FastString] -- ^ toplevel symbols (stored in index) , oiClInfo :: ![ClosureInfo] -- ^ closure information of all closures in block , oiStatic :: ![StaticInfo] -- ^ static closure data - , oiStat :: !JStat -- ^ the code + , oiStat :: JStat -- ^ the code , oiRaw :: !BS.ByteString -- ^ raw JS code , oiFExports :: ![ExpFun] , oiFImports :: ![ForeignJSRef] ===================================== compiler/GHC/Utils/Ppr.hs ===================================== @@ -107,7 +107,7 @@ module GHC.Utils.Ppr ( -- ** GHC-specific rendering printDoc, printDoc_, - bufLeftRender -- performance hack + bufLeftRender, printLeftRender -- performance hack ) where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99736889a3dc19deea9196ed63cf048511ef4c4d...b9333376918223418ba9d3e6d6724778866908cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99736889a3dc19deea9196ed63cf048511ef4c4d...b9333376918223418ba9d3e6d6724778866908cb You're receiving 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 Oct 7 15:21:12 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 07 Oct 2022 11:21:12 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Fix backpack dependencies Message-ID: <634043e8bf5f6_1eea6a5159057369@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: ebe0e1fb by Sylvain Henry at 2022-10-07T17:24:29+02:00 Fix backpack dependencies - - - - - 1 changed file: - compiler/GHC/StgToJS/Linker/Linker.hs Changes: ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -218,7 +218,6 @@ computeLinkDependencies -> (ExportedFun -> Bool) -> IO (Map Module (Deps, DepsLocation), [UnitId], Set LinkableUnit, Set ExportedFun, [FilePath]) computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDeps isRootFun = do - env <- newGhcjsEnv (objDepsMap, objRequiredUnits) <- loadObjDeps objFiles let roots = S.fromList . filter isRootFun $ concatMap (M.keys . depsHaskellExported . fst) (M.elems objDepsMap) @@ -231,43 +230,18 @@ computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDep let (rts_wired_units, rts_wired_functions) = rtsDeps units - let ue_state = ue_units $ unit_env - let preload_units = preloadUnits (ue_units unit_env) - -- all the units we want to link together, without their dependencies - let root_units = nub (preload_units ++ rts_wired_units ++ reverse objPkgs ++ reverse units) - - -- all the units we want to link together, including their dependencies - let all_units = transitive_units root_units - - -- compute transitive unit dependencies - transitive_units = reverse . transitive_units_ [] - transitive_units_ xs = \case - [] -> xs - (u:us) - | u == mainUnitId -> transitive_units_ (u:xs) us - | otherwise -> case lookupUnitId ue_state u of - Nothing -> unit_not_found u - Just d -> - let deps = unitDepends d - is_new_dep x = x `notElem` xs - new_deps = filter is_new_dep deps - in case new_deps of - [] - | u `elem` xs -> transitive_units_ xs us - | otherwise -> transitive_units_ (u:xs) us - ds -> transitive_units_ xs (ds ++ (u:us)) - - unit_not_found u = throwGhcException (CmdLineError ("unknown unit: " ++ unpackFS (unitIdFS u))) - - mkPkgLibPaths :: UnitState -> [UnitId] -> [(UnitId, ([FilePath],[String]))] - mkPkgLibPaths u_st - = map (\k -> ( k - , (getInstalledPackageLibDirs u_st k - , getInstalledPackageHsLibs u_st k) - )) - - dep_archives <- getPackageArchives cfg (map snd $ mkPkgLibPaths ue_state all_units) + let root_units = filter (/= mainUnitId) + $ nub (rts_wired_units ++ reverse objPkgs ++ reverse units) + + -- all the units we want to link together, including their dependencies, + -- preload units, and backpack instantiations + all_units_infos <- mayThrowUnitErr (preloadUnitsInfo' unit_env root_units) + + let all_units = fmap unitId all_units_infos + + dep_archives <- getPackageArchives cfg unit_env all_units + env <- newGhcjsEnv (archsDepsMap, archsRequiredUnits) <- loadArchiveDeps env dep_archives when (logVerbAtLeast logger 2) $ @@ -394,11 +368,16 @@ renderLinkerStats s = module_stats = "code size per module (in bytes):\n\n" <> unlines (map (concatMap showMod) pkgMods) -getPackageArchives :: StgToJSConfig -> [([FilePath],[String])] -> IO [FilePath] -getPackageArchives cfg pkgs = +getPackageArchives :: StgToJSConfig -> UnitEnv -> [UnitId] -> IO [FilePath] +getPackageArchives cfg unit_env units = filterM doesFileExist [ p "lib" ++ l ++ profSuff <.> "a" - | (paths, libs) <- pkgs, p <- paths, l <- libs ] + | u <- units + , p <- getInstalledPackageLibDirs ue_state u + , l <- getInstalledPackageHsLibs ue_state u + ] where + ue_state = ue_units unit_env + -- XXX the profiling library name is probably wrong now profSuff | csProf cfg = "_p" | otherwise = "" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebe0e1fb3941fb9e6681edc453b2c73f71ec2b23 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebe0e1fb3941fb9e6681edc453b2c73f71ec2b23 You're receiving 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 Oct 7 15:40:07 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 07 Oct 2022 11:40:07 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] More on Large Bitmaps Message-ID: <63404857d8487_1eea6a514145740a@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 18f594e8 by Sven Tennie at 2022-10-07T15:39:34+00:00 More on Large Bitmaps - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.cmm - libraries/ghc-heap/tests/decode_cloned_stack.hs - rts/Heap.c - rts/Printer.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -69,14 +69,16 @@ wordsToBitmapEntries _ [] 0 = [] wordsToBitmapEntries _ [] i = error $ "Invalid state: Empty list, size " ++ show i wordsToBitmapEntries _ l 0 = error $ "Invalid state: Size 0, list " ++ show l wordsToBitmapEntries sfi (b:bs) size = - let entries = toBitmapEntries sfi b size - mbLastEntry = (listToMaybe . reverse) entries - mbLastFrame = fmap closureFrame mbLastEntry - in - case mbLastFrame of - Just (StackFrameIter (# s'#, i'# #)) -> - entries ++ wordsToBitmapEntries (StackFrameIter (# s'#, plusWord# i'# 1## #)) bs (subtractDecodedBitmapWord size) - Nothing -> error "This should never happen! Recursion ended not in base case." + trace ("wordsToBitmapEntries - b " ++ show b ++ ", size " ++ show size) + (let entries = toBitmapEntries sfi b (min size (fromIntegral wORD_SIZE_IN_BITS)) + mbLastEntry = (listToMaybe . reverse) entries + mbLastFrame = fmap closureFrame mbLastEntry + in + case mbLastFrame of + Just (StackFrameIter (# s'#, i'# #)) -> + entries ++ wordsToBitmapEntries (StackFrameIter (# s'#, plusWord# i'# 1## #)) bs (subtractDecodedBitmapWord size) + Nothing -> error "This should never happen! Recursion ended not in base case." + ) where subtractDecodedBitmapWord :: Word -> Word subtractDecodedBitmapWord size = fromIntegral $ max 0 ((fromIntegral size) - wORD_SIZE_IN_BITS) @@ -84,9 +86,9 @@ wordsToBitmapEntries sfi (b:bs) size = toBitmapEntries :: StackFrameIter -> Word -> Word -> [BitmapEntry] toBitmapEntries _ _ 0 = [] toBitmapEntries sfi@(StackFrameIter(# s, i #)) bitmap size = BitmapEntry { - closureFrame = sfi, - isPrimitive = (bitmap .&. 1) == 0 - } : toBitmapEntries (StackFrameIter (# s , plusWord# i 1## #)) (bitmap `shiftR` 1) (size - 1) + closureFrame = sfi, + isPrimitive = (bitmap .&. 1) /= 0 + } : toBitmapEntries (StackFrameIter (# s , plusWord# i 1## #)) (bitmap `shiftR` 1) (size - 1) toBitmapPayload :: BitmapEntry -> BitmapPayload toBitmapPayload e | isPrimitive e = Primitive . toWord . closureFrame $ e @@ -112,13 +114,13 @@ unpackStackFrameIter (StackFrameIter (# s#, i# #)) = RET_BCO -> RetBCO RET_SMALL -> let !(# bitmap#, size# #) = getSmallBitmap# s# i# bes = toBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #))(W# bitmap#) (W# size#) - payloads = map toBitmapPayload bes + payloads = map toBitmapPayload (trace ("bes " ++ show bes) bes) in RetSmall None payloads RET_BIG -> let !(# bitmapArray#, size# #) = getLargeBitmap# s# i# bitmapWords :: [Word] = foldrByteArray (\w acc -> W# w : acc) [] bitmapArray# - bes = wordsToBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #)) bitmapWords (trace ("XXX size " ++ show (W# size#))(W# size#)) - payloads = map toBitmapPayload bes + bes = wordsToBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #)) (trace ("bitmapWords" ++ show bitmapWords) bitmapWords) (trace ("XXX size " ++ show (W# size#))(W# size#)) + payloads = map toBitmapPayload (trace ("unpackStackFrameIter - lenght " ++ show (length bes) ++ ", " ++ show bes ) bes) in RetBig payloads RET_FUN -> RetFun ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -83,9 +83,10 @@ getSmallBitmapzh(P_ stack, W_ index) { } unpackClosureFromStackFramezh(P_ stack, W_ index){ - P_ closurePtr; + P_ closurePtr, closurePtrPrime; closurePtr = (StgStack_sp(stack) + WDS(index)); - jump stg_unpackClosurezh(closurePtr); + closurePtrPrime = P_[closurePtr]; + jump stg_unpackClosurezh(closurePtrPrime); } getLargeBitmapzh(P_ stack, W_ index){ ===================================== libraries/ghc-heap/tests/decode_cloned_stack.hs ===================================== @@ -2,10 +2,12 @@ module Main where import GHC.Stack.CloneStack import GHC.Exts.DecodeStack +import GHC.Float (minExpt) +import System.IO (hPutStrLn, stderr) main :: IO () main = do stack <- cloneMyStack res <- decodeStack stack - print res + hPutStrLn stderr $ "result: " ++ show res return () ===================================== rts/Heap.c ===================================== @@ -248,7 +248,8 @@ StgWord collect_pointers(StgClosure *closure, StgClosure *ptrs[]) { StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure)); - + debugBelch("heap_view_closurePtrs : closure %p, printObj ", closure); + printObj(closure); StgWord size = heap_view_closureSize(closure); // First collect all pointers here, with the comfortable memory bound ===================================== rts/Printer.c ===================================== @@ -482,6 +482,8 @@ void printBits(size_t const size, void const * const ptr) debugBelch("\n"); } +StgPtr origSp = NULL; + static void printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, uint32_t size ) @@ -494,13 +496,15 @@ printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, uint32_t i; for(i = 0; i < size; i++, bitmap >>= 1 ) { + debugBelch("printSmallBitmap - index %ld\n", &payload[i] - origSp); debugBelch(" stk[%ld] (%p) = ", (long)(spBottom-(payload+i)), payload+i); if ((bitmap & 1) == 0) { + debugBelch("closure - "); printPtr((P_)payload[i]); debugBelch(" -- "); printObj((StgClosure*) payload[i]); } else { - debugBelch("Word# %" FMT_Word "\n", (W_)payload[i]); + debugBelch("primitive - Word# %" FMT_Word "\n", (W_)payload[i]); } } } @@ -515,29 +519,35 @@ printLargeBitmap( StgPtr spBottom, StgPtr payload, StgLargeBitmap* large_bitmap, i = 0; for (bmp=0; i < size; bmp++) { StgWord bitmap = large_bitmap->bitmap[bmp]; + debugBelch("printLargeBitmap - bitmap no %ul, bits ", bmp); + printBits(sizeof(StgWord), &bitmap); j = 0; for(; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1 ) { debugBelch(" stk[%" FMT_Word "] (%p) = ", (W_)(spBottom-(payload+i)), payload+i); if ((bitmap & 1) == 0) { + debugBelch("closure - "); printPtr((P_)payload[i]); debugBelch(" -- "); printObj((StgClosure*) payload[i]); } else { - debugBelch("Word# %" FMT_Word "\n", (W_)payload[i]); + debugBelch("primitive - Word# %" FMT_Word "\n", (W_)payload[i]); } } } } + void printStackChunk( StgPtr sp, StgPtr spBottom ) { const StgInfoTable *info; + origSp = sp; ASSERT(sp <= spBottom); for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) { info = get_itbl((StgClosure *)sp); debugBelch("printStackChunk - closure size : %lu , sp : %p, spBottom %p, info ptr %p, itbl type %ul \n", stack_frame_sizeW((StgClosure *)sp), sp, spBottom, info, info->type); + debugBelch("printStackChunk - index: %ld \n", sp - origSp); switch (info->type) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18f594e85854d5401a31a86fc1bafc431773d08a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18f594e85854d5401a31a86fc1bafc431773d08a You're receiving 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 Oct 7 19:27:45 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Fri, 07 Oct 2022 15:27:45 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: testsuite: add js_skip_csources function Message-ID: <63407db1e9647_1eea6a514785849ba@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c41031c0 by doyougnu at 2022-10-07T14:17:46-04:00 testsuite: add js_skip_csources function Used to indicate a test that fails in the JS backend because the JS Backend does not yet support c-sources in cabal files. - - - - - 7287a052 by doyougnu at 2022-10-07T14:17:46-04:00 testsuite: JS: skip tests which use c-sources Skip because these tests use c-sources and the JS backend does not yet support including c-sources testsuite: JS backend: skip backpack tests testsuite: JS: skip c-sources ffi tests testsuite: JS: skip multipleHomeUnits_odir testsuite: JS: disable more backpack tests testsuite: JS: disable c-sources rts tests testsuite: JS: skip c-sources codeGen tests testsuite: JS: skip c-sources generics test - - - - - 11 changed files: - testsuite/driver/testlib.py - testsuite/tests/backpack/should_run/all.T - testsuite/tests/codeGen/should_run/T20137/all.T - testsuite/tests/codeGen/should_run/T20735/all.T - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/driver/multipleHomeUnits/o-dir/all.T - testsuite/tests/ffi/should_fail/all.T - testsuite/tests/ffi/should_run/all.T - testsuite/tests/generics/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/rts/all.T Changes: ===================================== testsuite/driver/testlib.py ===================================== @@ -149,6 +149,10 @@ def js_broken( bug: IssueNumber ): else: return normal; +# an alias to js_skip to note that these tests fail due to c-sources +def js_skip_csources(name, opts): + js_skip(name,opts); + def expect_fail( name, opts ): # The compiler, testdriver, OS or platform is missing a certain # feature, and we don't plan to or can't fix it now or in the ===================================== testsuite/tests/backpack/should_run/all.T ===================================== @@ -1,13 +1,13 @@ -test('bkprun01', normal, backpack_run, ['']) -test('bkprun02', normal, backpack_run, ['']) -test('bkprun03', normal, backpack_run, ['']) -test('bkprun04', normal, backpack_run, ['']) -test('bkprun05', exit_code(1), backpack_run, ['']) -test('bkprun06', normal, backpack_run, ['']) -test('bkprun07', normal, backpack_run, ['']) -test('bkprun08', normal, backpack_run, ['']) -test('bkprun09', normal, backpack_run, ['-O']) -test('T13955', normal, backpack_run, ['']) -test('T15138', normal, backpack_run, ['']) -test('T15379', normal, backpack_run,['']) +test('bkprun01', js_skip_csources, backpack_run, ['']) +test('bkprun02', js_skip_csources, backpack_run, ['']) +test('bkprun03', js_skip_csources, backpack_run, ['']) +test('bkprun04', js_skip_csources, backpack_run, ['']) +test('bkprun05', [exit_code(1), js_skip_csources], backpack_run, ['']) +test('bkprun06', js_skip_csources, backpack_run, ['']) +test('bkprun07', js_skip_csources, backpack_run, ['']) +test('bkprun08', js_skip_csources, backpack_run, ['']) +test('bkprun09', js_skip_csources, backpack_run, ['-O']) +test('T13955', js_skip_csources, backpack_run, ['']) +test('T15138', js_skip_csources, backpack_run, ['']) +test('T15379', js_skip_csources, backpack_run,['']) test('T20133', expect_broken(20133), backpack_run, ['']) ===================================== testsuite/tests/codeGen/should_run/T20137/all.T ===================================== @@ -1 +1 @@ -test('T20137', normal, compile_and_run, ['T20137C.c']) +test('T20137', js_skip_csources, compile_and_run, ['T20137C.c']) ===================================== testsuite/tests/codeGen/should_run/T20735/all.T ===================================== @@ -1,5 +1,5 @@ test('T20735', - normal, + js_skip_csources, multi_compile_and_run, ['T20735', [('T20735_c.c', '')], '']) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -211,7 +211,7 @@ test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) test('T17920', cmm_src, compile_and_run, ['']) -test('T18527', normal, compile_and_run, ['T18527FFI.c']) +test('T18527', js_skip_csources, compile_and_run, ['T18527FFI.c']) test('T19149', only_ways('sanity'), compile_and_run, ['T19149_c.c']) test('T20275', normal, compile_and_run, ['']) ===================================== testsuite/tests/driver/multipleHomeUnits/o-dir/all.T ===================================== @@ -1,6 +1,7 @@ # This test checks that getRootSummary doesn't cross package boundaries. test('multipleHomeUnits_odir' - , [extra_files([ 'p1/', 'unitP1']) + , [extra_files([ 'p1/', 'unitP1']), + js_skip_csources ] , makefile_test , ['mhu-odir']) ===================================== testsuite/tests/ffi/should_fail/all.T ===================================== @@ -9,7 +9,7 @@ test('T3066', normal, compile_fail, ['']) test('ccfail004', [extra_files(['Ccfail004A.hs'])], multimod_compile_fail, ['ccfail004', '-v0']) test('ccfail005', normal, compile_fail, ['']) test('ccall_value', normal, compile_fail, ['']) -test('capi_value_function', normal, compile_fail, ['']) +test('capi_value_function', js_skip_csources, compile_fail, ['']) test('NonreducingFfiSignature', normal, compile_fail, ['']) test('T5664', normal, compile_fail, ['-v0']) test('T7506', normal, compile_fail, ['']) @@ -23,7 +23,8 @@ test('T21305_fail', normal, compile_fail, ['']) # from an unsafe foreign function) and only makes sense in non-threaded way # (threaded runtime will hang). See #14912. test('UnsafeReenter', - [omit_ways(threaded_ways), exit_code(1)], + [omit_ways(threaded_ways), exit_code(1), + js_skip_csources], compile_and_run, ['UnsafeReenterC.c']) ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -30,6 +30,7 @@ test('ffi004', skip, compile_and_run, ['']) test('ffi005', [ omit_ways(prof_ways + ['ghci']), when(arch('i386'), skip), when(platform('i386-apple-darwin'), expect_broken(4105)), + js_skip_csources, exit_code(3) ], compile_and_run, ['ffi005_c.c']) @@ -72,7 +73,7 @@ test('ffi014', [only_ways(['threaded1', 'threaded2'])], compile_and_run, ['ffi014_cbits.c']) # GHCi can't handle the separate C file (ToDo: fix this somehow) -test('ffi015', [omit_ways(['ghci'])], compile_and_run, ['ffi015_cbits.c']) +test('ffi015', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['ffi015_cbits.c']) # GHCi can't handle foreign import "&" test('ffi016', omit_ways(['ghci']), compile_and_run, ['']) @@ -85,7 +86,8 @@ test('ffi018_ghci', [extra_files(['ffi018.h']), only_ways(['ghci']), when(unregisterised(), fragile(16085)), - pre_cmd('$MAKE -s --no-print-directory ffi018_ghci_setup')], + pre_cmd('$MAKE -s --no-print-directory ffi018_ghci_setup'), + js_skip_csources], compile_and_run, ['ffi018_ghci_c.o']) test('ffi019', normal, compile_and_run, ['']) @@ -93,14 +95,14 @@ test('ffi019', normal, compile_and_run, ['']) # This one originally failed only GHCi, but doesn't hurt to test all ways. test('T1679', normal, compile_and_run, ['']) -test('T1288', [omit_ways(['ghci'])], compile_and_run, ['T1288_c.c']) +test('T1288', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T1288_c.c']) test('T1288_ghci', [only_ways(['ghci']), when(unregisterised(), fragile(16085)), pre_cmd('$MAKE -s --no-print-directory T1288_ghci_setup')], compile_and_run, ['T1288_ghci_c.o']) -test('T2276', [omit_ways(['ghci'])], compile_and_run, ['T2276_c.c']) +test('T2276', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T2276_c.c']) test('T2276_ghci', [ only_ways(['ghci']), when(opsys('darwin'), skip), # stdcall not supported on OS X pre_cmd('$MAKE -s --no-print-directory T2276_ghci_setup') ], @@ -108,13 +110,15 @@ test('T2276_ghci', [ only_ways(['ghci']), test('T2469', normal, compile_and_run, ['-optc-std=gnu99']) -test('T2594', [omit_ways(['ghci'])], compile_and_run, ['T2594_c.c']) +test('T2594', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T2594_c.c']) test('fptr01', [omit_ways(['ghci'])], compile_and_run, [ 'fptr01_js.js' if arch("js") else 'fptr01_c.c']) test('fptr02', normal, compile_and_run, ['']) -test('fptrfail01', [omit_ways(['ghci']), exit_code(1)], compile_and_run, +test('fptrfail01', [omit_ways(['ghci']), + exit_code(1), + js_skip_csources], compile_and_run, ['fptrfail01_c.c']) test('T2917a', normal, compile_and_run, ['']) @@ -136,7 +140,7 @@ else: flagsForT4038 = [''] test('T4038', normal, compile_and_run, flagsForT4038) -test('T4221', [omit_ways(['ghci'])], compile_and_run, ['T4221_c.c']) +test('T4221', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T4221_c.c']) test('T5402', [ omit_ways(['ghci']), exit_code(42), @@ -159,7 +163,7 @@ test('Capi_Ctype_001', [extra_files(['Capi_Ctype_A_001.hsc', 'capi_ctype_001.h', test('Capi_Ctype_002', [extra_files(['Capi_Ctype_A_002.hsc', 'capi_ctype_002_A.h', 'capi_ctype_002_B.h'])], makefile_test, ['Capi_Ctype_002']) -test('ffi_parsing_001', [omit_ways(['ghci'])], compile_and_run, +test('ffi_parsing_001', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['ffi_parsing_001_c.c']) test('capi_value', [omit_ways(['ghci'])], compile_and_run, ['capi_value_c.c']) @@ -172,7 +176,7 @@ test('T7170', test('T4012', [expect_broken_for(7388, ['ghci'])], multimod_compile_and_run, ['T4012', '']) -test('T8083', [omit_ways(['ghci'])], compile_and_run, ['T8083_c.c']) +test('T8083', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T8083_c.c']) test('T9274', [omit_ways(['ghci'])], compile_and_run, ['']) @@ -184,39 +188,39 @@ test('ffi023', [ omit_ways(['ghci']), # needs it. compile_and_run, ['ffi023_c.c']) -test('T12134', [omit_ways(['ghci'])], compile_and_run, ['T12134_c.c']) +test('T12134', [omit_ways(['ghci']),js_skip_csources], compile_and_run, ['T12134_c.c']) -test('T12614', [omit_ways(['ghci'])], compile_and_run, ['T12614_c.c']) +test('T12614', [omit_ways(['ghci']),js_skip_csources], compile_and_run, ['T12614_c.c']) test('T14624', [omit_ways(['ghci'])], compile_and_run, ['T14624_c.c']) test('T15933', extra_files(['T15933_c.c', 'T15933.h']), makefile_test, ['T15933']) -test('T16650a', [omit_ways(['ghci'])], compile_and_run, ['T16650a_c.c']) +test('T16650a', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T16650a_c.c']) -test('T16650b', [omit_ways(['ghci'])], compile_and_run, ['T16650b_c.c']) +test('T16650b', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T16650b_c.c']) -test('T16650c', [omit_ways(['ghci'])], compile_and_run, ['T16650c_c.c']) +test('T16650c', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T16650c_c.c']) -test('T16650d', [omit_ways(['ghci'])], compile_and_run, ['T16650d_c.c']) +test('T16650d', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T16650d_c.c']) -test('PrimFFIInt8', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIInt8_c.c']) +test('PrimFFIInt8', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIInt8_c.c']) -test('PrimFFIWord8', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIWord8_c.c']) +test('PrimFFIWord8', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIWord8_c.c']) -test('PrimFFIInt16', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIInt16_c.c']) +test('PrimFFIInt16', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIInt16_c.c']) -test('PrimFFIWord16', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIWord16_c.c']) +test('PrimFFIWord16', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIWord16_c.c']) -test('PrimFFIInt32', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIInt32_c.c']) +test('PrimFFIInt32', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIInt32_c.c']) -test('PrimFFIWord32', [omit_ways(['ghci'])], compile_and_run, ['PrimFFIWord32_c.c']) +test('PrimFFIWord32', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['PrimFFIWord32_c.c']) -test('T493', [omit_ways(['ghci'])], compile_and_run, ['T493_c.c']) +test('T493', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T493_c.c']) -test('UnliftedNewtypesByteArrayOffset', [omit_ways(['ghci'])], compile_and_run, ['UnliftedNewtypesByteArrayOffset_c.c']) +test('UnliftedNewtypesByteArrayOffset', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['UnliftedNewtypesByteArrayOffset_c.c']) -test('T17471', [omit_ways(['ghci'])], compile_and_run, +test('T17471', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T17471_c.c -optc-D -optcFOO']) test('IncallAffinity', @@ -226,7 +230,7 @@ test('IncallAffinity', compile_and_run, ['IncallAffinity_c.c -no-hs-main']) -test('T19237', normal, compile_and_run, ['T19237_c.c']) +test('T19237', js_skip_csources, compile_and_run, ['T19237_c.c']) test('T21305', [cmm_src,omit_ways(['ghci'])], multi_compile_and_run, ['T21305', [('T21305_cmm.cmm', '')], '']) ===================================== testsuite/tests/generics/all.T ===================================== @@ -20,9 +20,9 @@ test('GenCannotDoRep1_8', normal, compile_fail, ['']) test('GFullyStrict', normal, compile_and_run, ['']) test('T5462Yes1', [extra_files(['GEnum/', 'GEq/', 'GFunctor/']), - outputdir('out_T5462Yes1')] + outputdir('out_T5462Yes1'), js_skip_csources] , multimod_compile_and_run, ['T5462Yes1', '-iGEq -iGEnum -iGFunctor']) -test('T5462Yes2', [extra_files(['GFunctor/']), outputdir('out_T5462Yes2')] +test('T5462Yes2', [extra_files(['GFunctor/']), outputdir('out_T5462Yes2'), js_skip_csources] , multimod_compile_and_run, ['T5462Yes2', '-iGFunctor']) test('T5462No1', [extra_files(['GFunctor/']), outputdir('out_T5462No1')] , multimod_compile_fail, ['T5462No1', '-iGFunctor']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -40,9 +40,9 @@ test('RepPolyArgument', normal, compile_fail, ['']) test('RepPolyArrowCmd', normal, compile_fail, ['']) test('RepPolyArrowFun', normal, compile_fail, ['']) test('RepPolyBackpack1', normal, backpack_compile_fail, ['']) -test('RepPolyBackpack2', normal, backpack_run, ['']) +test('RepPolyBackpack2', js_skip_csources, backpack_run, ['']) test('RepPolyBackpack3', normal, backpack_compile_fail, ['']) -test('RepPolyBackpack4', normal, backpack_run, ['']) +test('RepPolyBackpack4', js_skip_csources, backpack_run, ['']) test('RepPolyBackpack5', normal, backpack_run, ['']) test('RepPolyBinder', normal, compile_fail, ['']) test('RepPolyCase1', normal, compile_fail, ['']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -276,7 +276,7 @@ test('T7037', [], makefile_test, ['T7037']) test('T7087', exit_code(1), compile_and_run, ['']) test('T7160', omit_ways(['nonmoving_thr', 'nonmoving_thr_ghc']), compile_and_run, ['']) -test('T7040', [omit_ways(['ghci'])], compile_and_run, ['T7040_c.c']) +test('T7040', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['T7040_c.c']) test('T7040_ghci', [extra_files(['T7040_c.h']), @@ -388,7 +388,7 @@ test('T9839_05', test('T10590', [ignore_stderr, when(opsys('mingw32'), skip)], compile_and_run, ['']) # 20000 was easily enough to trigger the bug with 7.10 -test('T10904', [ omit_ways(['ghci']), extra_run_opts('20000') ], +test('T10904', [ omit_ways(['ghci']), extra_run_opts('20000'), js_skip_csources ], compile_and_run, ['T10904lib.c']) test('T10728', [extra_run_opts('+RTS -maxN3 -RTS'), only_ways(['threaded2'])], @@ -483,10 +483,10 @@ test('keep-cafs', # Test proper functioning of C++ exceptions within a C++ program. # On darwin, this requires -fcompact-unwind. -test('T11829', [ check_errmsg("This is a test") ], compile_and_run, +test('T11829', [ check_errmsg("This is a test"), js_skip_csources], compile_and_run, ['T11829_c.cpp -package system-cxx-std-lib']) -test('T16514', normal, compile_and_run, ['T16514_c.c']) +test('T16514', js_skip_csources, compile_and_run, ['T16514_c.c']) test('test-zeroongc', extra_run_opts('-DZ'), compile_and_run, ['-debug']) test('T13676', View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebe0e1fb3941fb9e6681edc453b2c73f71ec2b23...7287a0521bf21cb800ff3455b744b5d3b3ab450f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ebe0e1fb3941fb9e6681edc453b2c73f71ec2b23...7287a0521bf21cb800ff3455b744b5d3b3ab450f You're receiving 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 Oct 8 07:38:51 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 08 Oct 2022 03:38:51 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 2 commits: Cleanup Message-ID: <6341290bc30f_1eea6a5147861123e@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: a342ceb8 by Sven Tennie at 2022-10-08T07:32:48+00:00 Cleanup - - - - - 8e623557 by Sven Tennie at 2022-10-08T07:38:31+00:00 Fix some warnings - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -13,16 +13,16 @@ -- TODO: Find better place than top level. Re-export from top-level? module GHC.Exts.DecodeStack where -import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) #if MIN_VERSION_base(4,17,0) +import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) import Data.Maybe import Data.Bits import Foreign import System.IO.Unsafe import Prelude import GHC.Stack.CloneStack -import GHC.Exts.Heap +import GHC.Exts.Heap hiding (bitmap, size) import Debug.Trace import GHC.Exts import qualified GHC.Exts.Heap.Closures as CL @@ -206,13 +206,16 @@ data StackFrame = deriving (Show) #if defined(DEBUG) -foreign import ccall "belchStack" belchStack :: StackSnapshot# -> IO () +foreign import ccall "belchStack" belchStack# :: StackSnapshot# -> IO () + +belchStack :: StackSnapshot -> IO () +belchStack (StackSnapshot s#) = belchStack s# #endif decodeStack :: StackSnapshot -> IO [StackFrame] -decodeStack s@(StackSnapshot s#) = do +decodeStack s = do #if defined(DEBUG) - belchStack s# + belchStack s #endif pure $ decodeStack' s @@ -223,236 +226,4 @@ decodeStack' s = unpackStackFrameIter (stackHead s) : go (advanceStackFrameIter go Nothing = [] go (Just sfi) = unpackStackFrameIter sfi : go (advanceStackFrameIter sfi) - --- foreign import ccall "stackFrameSizeW" stackFrameSizeW :: Addr# -> Word --- foreign import ccall "getItbl" getItbl :: Addr# -> Ptr StgInfoTable --- foreign import ccall "getSpecialRetSmall" getSpecialRetSmall :: Addr# -> Word --- foreign import ccall "getBitmapSize" getBitmapSize :: Ptr StgInfoTable -> Word --- foreign import ccall "getBitmapWord" getBitmapWord :: Ptr StgInfoTable -> Word --- foreign import prim "stg_unpackClosurezh" unpackClosure_prim# :: Word# -> (# Addr#, ByteArray#, Array# b #) --- foreign import ccall "getLargeBitmapPtr" getLargeBitmapPtr :: Ptr StgInfoTable -> Ptr LargeBitmap --- #if defined(DEBUG) --- foreign import ccall "belchStack" belchStack :: StackSnapshot# -> IO () --- #endif --- --- decodeStack :: StackSnapshot -> IO [StackFrame] --- decodeStack (StackSnapshot stack) = do --- #if defined(DEBUG) --- performMajorGC --- belchStack stack --- #endif --- let (stgStackPtr :: Ptr FFIClosures.StackFields) = Ptr (unsafeCoerce# stack) --- stgStack <- FFIClosures.peekStackFields stgStackPtr --- traceM $ "stack_dirty " ++ show (FFIClosures.stack_dirty stgStack) --- traceM $ "stack_marking " ++ show (FFIClosures.stack_marking stgStack) --- traceM $ "stack_size " ++ show (FFIClosures.stack_size stgStack) --- traceM $ "stack_sp " ++ showAddr# (FFIClosures.stack_sp stgStack) --- decodeStackChunks stgStack --- --- decodeStackChunks :: FFIClosures.StackFields -> IO [StackFrame] --- decodeStackChunks stgStack = --- let --- -- TODO: Use word size here, not just 8 --- stackSize = 8 * (FFIClosures.stack_size stgStack) --- buttom = plusAddr# (FFIClosures.stack_stack stgStack) (integralToInt# stackSize) --- in --- decodeStackFrame buttom (FFIClosures.stack_sp stgStack) --- --- decodeStackFrame :: Addr# -> Addr# -> IO [StackFrame] --- -- TODO: Use ltAddr# ? (Does it even work?) --- decodeStackFrame buttom sp | (addrToInt sp) >= (addrToInt buttom) = do --- traceM $ "decodeStackFrame - buttom " ++ showAddr# buttom --- traceM $ "decodeStackFrame - sp " ++ showAddr# sp --- traceM "buttom reached" --- pure [] --- decodeStackFrame buttom sp = do --- -- traceM $ "decodeStackFrame - (addrToInt sp) >= (addrToInt buttom)" ++ show ((addrToInt sp) >= (addrToInt buttom)) --- -- traceM $ "decodeStackFrame - buttom " ++ showAddr# buttom --- traceM $ "decodeStackFrame - sp " ++ showAddr# sp --- frame <- toStackFrame sp --- traceM $ "decodeStackFrame - frame " ++ show frame --- -- TODO: This is probably not lazy and pretty ugly. --- -- TODO: Use word size instead of 8 --- let --- closureSize = stackFrameSizeW sp --- closureSizeInBytes = 8 * closureSize --- nextSp = plusAddr# sp (integralToInt# closureSizeInBytes) --- --- traceM $ "decodeStackFrame - closureSize " ++ show closureSize ++ " sp " ++ showAddr# sp --- traceM $ "decodeStackFrame - nextSp " ++ showAddr# nextSp --- otherFrames <- decodeStackFrame buttom nextSp --- return $ frame : otherFrames --- --- toStackFrame :: Addr# -> IO StackFrame --- toStackFrame sp = do --- let itblPtr = getItbl sp --- itbl <- peekItbl itblPtr --- traceM $ "itbl " ++ show itbl --- case tipe itbl of --- RET_BCO -> pure RetBCO --- RET_SMALL -> --- let special = ((toEnum . fromInteger . toInteger) (getSpecialRetSmall sp)) --- -- TODO: Use word size here, not just 8 --- payloadAddr# = plusAddr# sp (toInt# 8) --- bSize = getBitmapSize itblPtr --- bWord = getBitmapWord itblPtr --- in --- do --- payloads <- peekBitmapPayloadArray bSize bWord (Ptr payloadAddr#) --- pure $ RetSmall special payloads --- RET_BIG -> do --- let pPtr = payloadPtr (Ptr sp) --- traceM $ "toStackFrame - BIG_RET - pPtr " ++ show pPtr --- let largeBitmapPtr = getLargeBitmapPtr itblPtr --- largeBitmap <- peekStgLargeBitmap largeBitmapPtr --- traceM $ "toStackFrame - BIG_RET - largeBitmap " ++ show largeBitmap --- let entries = bitmapEntries pPtr largeBitmap --- traceM $ "toStackFrame - BIG_RET - entries " ++ show entries --- payloads <- mapM toClosure $ bitmapEntries pPtr largeBitmap --- pure $ RetBig payloads --- RET_FUN -> pure RetFun --- UPDATE_FRAME -> pure UpdateFrame --- CATCH_FRAME -> pure CatchFrame --- UNDERFLOW_FRAME -> pure UnderflowFrame --- STOP_FRAME -> pure StopFrame --- ATOMICALLY_FRAME -> pure AtomicallyFrame --- CATCH_RETRY_FRAME -> pure CatchRetryFrame --- CATCH_STM_FRAME -> pure CatchStmFrame --- _ -> error $ "Unexpected closure type on stack: " ++ show (tipe itbl) --- --- toClosure :: BitmapEntry -> IO BitmapPayload --- toClosure (BitmapEntry ptr isPrimitive) = if isPrimitive then --- do --- -- TODO: duplicated line with else branch --- e <- peek ptr --- pure $ Primitive e --- else --- do --- e <- peek ptr --- c <- getClosureDataFromHeapObject' (toWord# e) --- pure $ Closure c --- --- -- Idea: --- -- 1. convert to list of (significant) bits --- -- Convert to tupe (Ptr addr, closure type) --- -- This is pure! And, should be easy to decode, debug and reuse. --- data BitmapEntry = BitmapEntry { --- closurePtr :: Ptr Word, --- isPrimitive :: Bool --- } deriving (Show) --- --- bitmapEntries :: Ptr Word -> LargeBitmap -> [BitmapEntry] --- bitmapEntries payloadPtr (LargeBitmap size ws) = --- map toBitmapEntry $ zip (bits size ws) [0..] --- where --- toBitmapEntry :: (Bool, Int) -> BitmapEntry --- toBitmapEntry (b,i) = BitmapEntry { --- closurePtr = plusPtr payloadPtr (i * (fromIntegral bytesInWord)), --- isPrimitive = b --- } --- --- bits :: Word -> [Word] -> [Bool] --- bits size ws = take (fromIntegral size) $ concat (map toBits ws) --- --- toBits :: Word -> [Bool] --- toBits w = go 0 --- where --- go :: Int -> [Bool] --- go b | b == (fromIntegral bitsInWord) = [] --- go b = (w .&. (1 `shiftL` b) == 1) : go (b + 1) --- --- peekLargeBitmap :: Word -> [Word] -> Ptr Word -> IO [BitmapPayload] --- peekLargeBitmap 0 _ _ = pure [] --- peekLargeBitmap _ [] _ = pure [] --- peekLargeBitmap bSize (w:ws) pPtr = do --- payloads <- peekPayloadsFromLargeBitmapWord bSize w pPtr --- -- TODO: Not tail-recursive, breaks lazyness --- rest <- peekLargeBitmap remainingBitmapSize ws pPtr --- pure $ payloads ++ rest --- where --- remainingBitmapSize = max 0 (bSize - bitsInWord) --- --- peekPayloadsFromLargeBitmapWord :: Word -> Word -> Ptr Word -> IO [BitmapPayload] --- peekPayloadsFromLargeBitmapWord bSize bWord ptr = go 0 [] --- where --- go :: Word -> [BitmapPayload] -> IO [BitmapPayload] --- go index acc | index >= bitsUsed = pure acc --- go index acc = do --- e <- peekBitmapPayload ptr index bWord --- go (index + 1) (e:acc) --- bitsUsed = min bitsInWord bSize --- --- -- TODO: Use Ptr instead of Addr# (in all possible places)? --- peekBitmapPayloadArray :: Word -> Word -> Ptr Word -> IO [BitmapPayload] --- peekBitmapPayloadArray bSize bWord ptr = go 0 [] --- where --- go :: Word -> [BitmapPayload] -> IO [BitmapPayload] --- go index acc | index >= bSize = pure acc --- go index acc = do --- e <- peekBitmapPayload ptr index bWord --- go (index + 1) (e:acc) --- --- -- | Fetch a single closure payload --- -- As the decission about the value to marshall --- -- to depends on the bitmap, only a `Word` is peeked. --- peekBitmapPayload :: Ptr Word -> Word -> Word -> IO BitmapPayload --- peekBitmapPayload ptr index bitmapWord = do --- traceM $ "peekBitmapPayload - ptr " ++ show ptr --- traceM $ "peekBitmapPayload - index " ++ show index --- e <- (peekElemOff ptr i :: IO Word) --- if isClosure then --- do --- c <- getClosureDataFromHeapObject' (toWord# e) --- pure $ Closure c --- else --- pure $ Primitive e --- where --- isClosure :: Bool --- isClosure = (bitmapWord .&. mask) == 0 --- mask :: Word --- mask = 1 `shiftL` i --- i :: Int --- i = (fromInteger.toInteger) index --- --- getClosureDataFromHeapObject' --- :: Word# --- -- ^ Heap object to decode. --- -> IO Closure --- -- ^ Heap representation of the closure. --- getClosureDataFromHeapObject' x = do --- case unpackClosure_prim# x of --- (# infoTableAddr, heapRep, pointersArray #) -> do --- let infoTablePtr = Ptr infoTableAddr --- ptrList = [case indexArray# pointersArray i of --- (# ptr #) -> Box ptr --- | I# i <- [0..I# (sizeofArray# pointersArray) - 1] --- ] --- --- infoTable <- peekItbl infoTablePtr --- case tipe infoTable of --- TSO -> pure $ UnsupportedClosure infoTable --- STACK -> pure $ UnsupportedClosure infoTable --- _ -> getClosureDataFromHeapRep heapRep infoTablePtr ptrList --- --- --- -- | Converts to 'Int#' --- -- An 'Integral' can be bigger than the domain of 'Int#'. This function drops --- -- the additional bits. So, the caller should better make sure that this --- -- conversion fits. --- integralToInt# :: Integral a => a -> Int# --- integralToInt# w = toInt# $ (fromInteger . toInteger) w --- --- -- | Unbox 'Int#' from 'Int' --- toInt# :: Int -> Int# --- toInt# (I# i) = i --- --- toWord# :: Word -> Word# --- toWord# (W# w#) = w# --- --- showAddr# :: Addr# -> String --- showAddr# addr# = showHex (addrToInt addr#) "" --- --- addrToInt:: Addr# -> Int --- addrToInt addr# = I# (addr2Int# addr#) --- #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18f594e85854d5401a31a86fc1bafc431773d08a...8e623557539cbe4d907852920402724ac28a67bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18f594e85854d5401a31a86fc1bafc431773d08a...8e623557539cbe4d907852920402724ac28a67bc You're receiving 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 Oct 8 09:13:48 2022 From: gitlab at gitlab.haskell.org (Joachim Breitner (@nomeata)) Date: Sat, 08 Oct 2022 05:13:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/joachim/escapeJsonString Message-ID: <63413f4c79b2f_1eea6a51590614472@gitlab.mail> Joachim Breitner pushed new branch wip/joachim/escapeJsonString at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/joachim/escapeJsonString You're receiving 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 Oct 8 11:44:10 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 08 Oct 2022 07:44:10 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 3 commits: Cleanup belching Message-ID: <6341628a683d3_1eea6a51414622657@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: d1df650c by Sven Tennie at 2022-10-08T10:47:49+00:00 Cleanup belching - - - - - 45d76034 by Sven Tennie at 2022-10-08T11:40:18+00:00 Assert closures are valid - - - - - 2f6ca800 by Sven Tennie at 2022-10-08T11:43:50+00:00 Assert more - - - - - 3 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -69,16 +69,14 @@ wordsToBitmapEntries _ [] 0 = [] wordsToBitmapEntries _ [] i = error $ "Invalid state: Empty list, size " ++ show i wordsToBitmapEntries _ l 0 = error $ "Invalid state: Size 0, list " ++ show l wordsToBitmapEntries sfi (b:bs) size = - trace ("wordsToBitmapEntries - b " ++ show b ++ ", size " ++ show size) - (let entries = toBitmapEntries sfi b (min size (fromIntegral wORD_SIZE_IN_BITS)) - mbLastEntry = (listToMaybe . reverse) entries - mbLastFrame = fmap closureFrame mbLastEntry + let entries = toBitmapEntries sfi b (min size (fromIntegral wORD_SIZE_IN_BITS)) + mbLastEntry = (listToMaybe . reverse) entries + mbLastFrame = fmap closureFrame mbLastEntry in case mbLastFrame of Just (StackFrameIter (# s'#, i'# #)) -> entries ++ wordsToBitmapEntries (StackFrameIter (# s'#, plusWord# i'# 1## #)) bs (subtractDecodedBitmapWord size) Nothing -> error "This should never happen! Recursion ended not in base case." - ) where subtractDecodedBitmapWord :: Word -> Word subtractDecodedBitmapWord size = fromIntegral $ max 0 ((fromIntegral size) - wORD_SIZE_IN_BITS) @@ -114,13 +112,13 @@ unpackStackFrameIter (StackFrameIter (# s#, i# #)) = RET_BCO -> RetBCO RET_SMALL -> let !(# bitmap#, size# #) = getSmallBitmap# s# i# bes = toBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #))(W# bitmap#) (W# size#) - payloads = map toBitmapPayload (trace ("bes " ++ show bes) bes) + payloads = map toBitmapPayload bes in RetSmall None payloads RET_BIG -> let !(# bitmapArray#, size# #) = getLargeBitmap# s# i# bitmapWords :: [Word] = foldrByteArray (\w acc -> W# w : acc) [] bitmapArray# bes = wordsToBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #)) (trace ("bitmapWords" ++ show bitmapWords) bitmapWords) (trace ("XXX size " ++ show (W# size#))(W# size#)) - payloads = map toBitmapPayload (trace ("unpackStackFrameIter - lenght " ++ show (length bes) ++ ", " ++ show bes ) bes) + payloads = map toBitmapPayload bes in RetBig payloads RET_FUN -> RetFun @@ -209,7 +207,7 @@ data StackFrame = foreign import ccall "belchStack" belchStack# :: StackSnapshot# -> IO () belchStack :: StackSnapshot -> IO () -belchStack (StackSnapshot s#) = belchStack s# +belchStack (StackSnapshot s#) = belchStack# s# #endif decodeStack :: StackSnapshot -> IO [StackFrame] ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -1,22 +1,20 @@ #include "MachDeps.h" #include "Rts.h" #include "rts/Messages.h" +#include "rts/Types.h" #include "rts/storage/ClosureTypes.h" #include "rts/storage/Closures.h" #include "rts/storage/InfoTables.h" -// Only exists to make the stack_frame_sizeW macro available in Haskell code -// (via FFI). -StgWord stackFrameSizeW(StgClosure *frame) { - return stack_frame_sizeW(frame); -} - StgWord stackFrameSize(StgStack* stack, StgWord index){ - return stackFrameSizeW(stack->sp + index); + StgClosure* c = (StgClosure *) stack->sp + index; + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + return stack_frame_sizeW(c); } StgStack* getUnderflowFrameStack(StgStack* stack, StgWord index){ StgClosure* frame = stack->sp + index; + ASSERT(LOOKS_LIKE_CLOSURE_PTR(frame)); const StgRetInfoTable *info = get_ret_itbl((StgClosure *)frame); if(info->i.type == UNDERFLOW_FRAME) { @@ -28,6 +26,7 @@ StgStack* getUnderflowFrameStack(StgStack* stack, StgWord index){ // Only exists to make the get_itbl macro available in Haskell code (via FFI). const StgInfoTable *getItbl(StgClosure *closure) { + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure)); // printObj(closure); return get_itbl(closure); }; @@ -80,13 +79,19 @@ StgWord getSpecialRetSmall(StgPtr sp) { } // TODO: Consider to use HSC -StgWord getBitmapSize(StgInfoTable *info){ +StgWord getBitmapSize(StgClosure *c){ + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + StgInfoTable* info = get_itbl(c); StgWord bitmap = info->layout.bitmap; return BITMAP_SIZE(bitmap); } // TODO: Consider to use HSC -StgWord getBitmapWord(StgInfoTable *info){ +StgWord getBitmapWord(StgClosure *c){ + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + StgInfoTable* info = get_itbl(c); StgWord bitmap = info->layout.bitmap; debugBelch("getBitmapWord - bitmap : %lu \n", bitmap); StgWord bitmapWord = BITMAP_BITS(bitmap); @@ -94,7 +99,10 @@ StgWord getBitmapWord(StgInfoTable *info){ return bitmapWord; } -StgWord getLargeBitmapSize(StgInfoTable *info){ +StgWord getLargeBitmapSize(StgClosure *c){ + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + StgInfoTable* info = get_itbl(c); StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); return bitmap->size; } @@ -105,7 +113,10 @@ StgWord getLargeBitmapSize(StgInfoTable *info){ #define SIZEOF_W SIZEOF_VOID_P #define WDS(n) ((n)*SIZEOF_W) -StgArrBytes* getLargeBitmaps(Capability *cap, StgInfoTable *info){ +StgArrBytes* getLargeBitmaps(Capability *cap, StgClosure *c){ + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + StgInfoTable* info = get_itbl(c); StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); StgWord neededWords = ROUNDUP_BITS_TO_WDS(bitmap->size); StgArrBytes* array = allocate(cap, sizeofW(StgArrBytes) + neededWords); ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -71,12 +71,13 @@ getInfoTableTypezh (P_ stack, W_ index) { } getSmallBitmapzh(P_ stack, W_ index) { - P_ itbl; - itbl = %STD_INFO(%INFO_PTR(StgStack_sp(stack) + WDS(index))); + P_ c; + c = StgStack_sp(stack) + WDS(index); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); W_ bitmap, size; - (bitmap) = ccall getBitmapWord(itbl); - (size) = ccall getBitmapSize(itbl); + (bitmap) = ccall getBitmapWord(c); + (size) = ccall getBitmapSize(c); ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul\n", bitmap, size); return (bitmap, size); @@ -90,12 +91,13 @@ unpackClosureFromStackFramezh(P_ stack, W_ index){ } getLargeBitmapzh(P_ stack, W_ index){ - P_ itbl, stgArrBytes; + P_ c, stgArrBytes; W_ size; - itbl = %STD_INFO(%INFO_PTR(StgStack_sp(stack) + WDS(index))); + c = StgStack_sp(stack) + WDS(index); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), itbl); - (size) = ccall getLargeBitmapSize(itbl); + (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), c); + (size) = ccall getLargeBitmapSize(c); ccall debugBelch("getLargeBitmapzh - size %ul\n", size); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e623557539cbe4d907852920402724ac28a67bc...2f6ca800f8bc48ea749757654ebb926c7b6ea9eb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e623557539cbe4d907852920402724ac28a67bc...2f6ca800f8bc48ea749757654ebb926c7b6ea9eb You're receiving 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 Oct 8 13:31:39 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 08 Oct 2022 09:31:39 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 5 commits: Assert more Message-ID: <63417bbb86e70_1eea6a515906343a1@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 4cc6d41d by Sven Tennie at 2022-10-08T11:56:37+00:00 Assert more - - - - - e5a82373 by Sven Tennie at 2022-10-08T12:31:18+00:00 Sober casts; mute debug belchs - - - - - 4668dd13 by Sven Tennie at 2022-10-08T12:33:41+00:00 Cleanup - - - - - 3bb4beab by Sven Tennie at 2022-10-08T12:44:06+00:00 Delete unused StackFFI HSC code - - - - - ae908a83 by Sven Tennie at 2022-10-08T13:30:47+00:00 Recognize special small rets - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - − libraries/ghc-heap/GHC/Exts/Heap/StackFFI.hsc - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm - libraries/ghc-heap/ghc-heap.cabal.in Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -57,7 +57,7 @@ foreign import prim "getInfoTableTypezh" getInfoTableType# :: StackSnapshot# -> foreign import prim "getLargeBitmapzh" getLargeBitmap# :: StackSnapshot# -> Word# -> (# ByteArray#, Word# #) -foreign import prim "getSmallBitmapzh" getSmallBitmap# :: StackSnapshot# -> Word# -> (# Word#, Word# #) +foreign import prim "getSmallBitmapzh" getSmallBitmap# :: StackSnapshot# -> Word# -> (# Word#, Word#, Word# #) data BitmapEntry = BitmapEntry { closureFrame :: StackFrameIter, @@ -110,11 +110,12 @@ unpackStackFrameIter :: StackFrameIter -> StackFrame unpackStackFrameIter (StackFrameIter (# s#, i# #)) = case (toEnum . fromIntegral) (W# (getInfoTableType# s# i#)) of RET_BCO -> RetBCO - RET_SMALL -> let !(# bitmap#, size# #) = getSmallBitmap# s# i# + RET_SMALL -> let !(# bitmap#, size#, special# #) = getSmallBitmap# s# i# bes = toBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #))(W# bitmap#) (W# size#) payloads = map toBitmapPayload bes + special = (toEnum . fromInteger . toInteger) (W# special#) in - RetSmall None payloads + RetSmall special payloads RET_BIG -> let !(# bitmapArray#, size# #) = getLargeBitmap# s# i# bitmapWords :: [Word] = foldrByteArray (\w acc -> W# w : acc) [] bitmapArray# bes = wordsToBitmapEntries (StackFrameIter (# s#, plusWord# i# 1## #)) (trace ("bitmapWords" ++ show bitmapWords) bitmapWords) (trace ("XXX size " ++ show (W# size#))(W# size#)) @@ -167,6 +168,7 @@ instance Show BitmapPayload where -- TODO There are likely more. See MiscClosures.h data SpecialRetSmall = + -- TODO: Shoudn't `None` be better `Maybe ...` None | ApV | ApF | ===================================== libraries/ghc-heap/GHC/Exts/Heap/StackFFI.hsc deleted ===================================== @@ -1,75 +0,0 @@ -module GHC.Exts.Heap.StackFFI where - -#include "Rts.h" -#undef BLOCK_SIZE -#undef MBLOCK_SIZE -#undef BLOCKS_PER_MBLOCK -#include "DerivedConstants.h" - --- TODO: Check imports: Are all needed? -import Prelude -- See note [Why do we import Prelude here?] -import GHC.Exts.Heap.InfoTable.Types -#if !defined(TABLES_NEXT_TO_CODE) -import GHC.Exts.Heap.Constants -import Data.Maybe -#endif -import Foreign -import Debug.Trace - -peekSmallBitmapWord :: Ptr StgInfoTable -> IO Word -peekSmallBitmapWord itbl = -#if !defined(TABLES_NEXT_TO_CODE) - let ptr = itbl `plusPtr` (negate wORD_SIZE) -#else - let ptr = itbl -#endif - in - (#peek struct StgInfoTable_, layout.bitmap) ptr - --- TODO: unused --- #define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK) -bitmapSize :: Word -> Word -bitmapSize b = b .&. (#const BITMAP_SIZE_MASK) - --- TODO: unused --- #define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT) -bitmapBits :: Word -> Word -bitmapBits b = b `shiftR` (#const BITMAP_BITS_SHIFT) - -data LargeBitmap = LargeBitmap { - size :: Word, - bitmap :: [Word] -} deriving (Show) - -peekStgLargeBitmap :: Ptr LargeBitmap -> IO LargeBitmap -peekStgLargeBitmap largeBitmapPtr = do --- #if !defined(TABLES_NEXT_TO_CODE) --- largeBitmapPtr <- (#peek struct StgInfoTable_, layout.large_bitmap) itbl --- #else --- -- large_bitmap_offset --- offset <- (#peek struct StgInfoTable_, layout.large_bitmap_offset) itbl --- let largeBitmapPtr = plusPtr itbl offset --- #endif - traceM $ "peekStgLargeBitmap - largeBitmapPtr : " ++ show largeBitmapPtr - size' <- (#peek StgLargeBitmap, size) largeBitmapPtr - traceM $ "peekStgLargeBitmap - size' : " ++ show size' - -- bitmapArrayPtr <- (#peek StgLargeBitmap, bitmap) largeBitmapPtr - -- traceM $ "peekStgLargeBitmap - bitmapArrayPtr : " ++ show bitmapArrayPtr - bitmap' <- peekArray size' (plusPtr largeBitmapPtr (#const OFFSET_StgLargeBitmap_bitmap)) - pure $ LargeBitmap { - -- This is safe: ´StgLargeBitmap.size´ is a StgWord in C/RTS - size = fromIntegral size', - bitmap = bitmap' - } - -bitsInWord :: Word -bitsInWord = (#const BITS_IN(StgWord)) - -bytesInWord :: Word -bytesInWord = (#const sizeof(StgWord)) - -payloadOffset = (#size StgHeader) + (#const OFFSET_StgClosure_payload) --- TODO: Ptr should not be polymorphic. I.e. use a saturized type. --- TODO: Doesn't need to be here (in hsc file) -payloadPtr :: Ptr a -> Ptr Word -payloadPtr sp = plusPtr sp payloadOffset ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -13,7 +13,7 @@ StgWord stackFrameSize(StgStack* stack, StgWord index){ } StgStack* getUnderflowFrameStack(StgStack* stack, StgWord index){ - StgClosure* frame = stack->sp + index; + StgClosure* frame = (StgClosure *) stack->sp + index; ASSERT(LOOKS_LIKE_CLOSURE_PTR(frame)); const StgRetInfoTable *info = get_ret_itbl((StgClosure *)frame); @@ -31,8 +31,9 @@ const StgInfoTable *getItbl(StgClosure *closure) { return get_itbl(closure); }; -StgWord getSpecialRetSmall(StgPtr sp) { - StgWord c = *sp; +StgWord getSpecialRetSmall(StgClosure *closure) { + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closure)); + StgWord c = *(StgWord*)closure; if (c == (StgWord)&stg_ap_v_info) { return 1; } else if (c == (StgWord)&stg_ap_f_info) { @@ -78,31 +79,29 @@ StgWord getSpecialRetSmall(StgPtr sp) { } } -// TODO: Consider to use HSC StgWord getBitmapSize(StgClosure *c){ ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - StgInfoTable* info = get_itbl(c); + const StgInfoTable* info = get_itbl(c); StgWord bitmap = info->layout.bitmap; return BITMAP_SIZE(bitmap); } -// TODO: Consider to use HSC StgWord getBitmapWord(StgClosure *c){ ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - StgInfoTable* info = get_itbl(c); + const StgInfoTable* info = get_itbl(c); StgWord bitmap = info->layout.bitmap; - debugBelch("getBitmapWord - bitmap : %lu \n", bitmap); + // debugBelch("getBitmapWord - bitmap : %lu \n", bitmap); StgWord bitmapWord = BITMAP_BITS(bitmap); - debugBelch("getBitmapWord - bitmapWord : %lu \n", bitmapWord); + // debugBelch("getBitmapWord - bitmapWord : %lu \n", bitmapWord); return bitmapWord; } StgWord getLargeBitmapSize(StgClosure *c){ ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - StgInfoTable* info = get_itbl(c); + const StgInfoTable* info = get_itbl(c); StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); return bitmap->size; } @@ -116,10 +115,10 @@ StgWord getLargeBitmapSize(StgClosure *c){ StgArrBytes* getLargeBitmaps(Capability *cap, StgClosure *c){ ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - StgInfoTable* info = get_itbl(c); + const StgInfoTable* info = get_itbl(c); StgLargeBitmap* bitmap = GET_LARGE_BITMAP(info); StgWord neededWords = ROUNDUP_BITS_TO_WDS(bitmap->size); - StgArrBytes* array = allocate(cap, sizeofW(StgArrBytes) + neededWords); + StgArrBytes* array = (StgArrBytes *) allocate(cap, sizeofW(StgArrBytes) + neededWords); SET_HDR(array, &stg_ARR_WORDS_info, CCCS); array->bytes = WDS(ROUNDUP_BITS_TO_WDS(bitmap->size)); @@ -130,10 +129,6 @@ StgArrBytes* getLargeBitmaps(Capability *cap, StgClosure *c){ return array; } -StgLargeBitmap* getLargeBitmapPtr(const StgInfoTable *info) { - return GET_LARGE_BITMAP(info); -} - #if defined(DEBUG) extern void printStack ( StgStack *stack ); void belchStack(StgStack* stack){ ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -48,7 +48,14 @@ advanceStackFrameIterzh (P_ stack, W_ index) { } } - ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul, stackBottom %p\n", stack, newStack, frameSize, newIndex, hasNext, stackBottom); + // TODO: Execute this block only in -DDEBUG + if(hasNext > 0) { + P_ nextClosure; + nextClosure = StgStack_sp(stack) + WDS(index); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(nextClosure)); + } + + // ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul, stackBottom %p\n", stack, newStack, frameSize, newIndex, hasNext, stackBottom); return (newStack, newIndex, hasNext); } @@ -61,12 +68,13 @@ derefStackWordzh (P_ stack, W_ index) { getInfoTableTypezh (P_ stack, W_ index) { P_ p, info; - p = (StgStack_sp(stack) + WDS(index)); + p = StgStack_sp(stack) + WDS(index); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(p)); info = %INFO_PTR(p); W_ type; type = TO_W_(%INFO_TYPE(%STD_INFO(info))); - ccall debugBelch("getInfoTableTypezh - stack %p , index %ul, closure ptr p %p, info ptr %p, itbl type %ul\n", stack, index, p, info, type); + // ccall debugBelch("getInfoTableTypezh - stack %p , index %ul, closure ptr p %p, info ptr %p, itbl type %ul\n", stack, index, p, info, type); return (type); } @@ -75,12 +83,13 @@ getSmallBitmapzh(P_ stack, W_ index) { c = StgStack_sp(stack) + WDS(index); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - W_ bitmap, size; + W_ bitmap, size, specialType; (bitmap) = ccall getBitmapWord(c); (size) = ccall getBitmapSize(c); + (specialType) = ccall getSpecialRetSmall(c); - ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul\n", bitmap, size); - return (bitmap, size); + // ccall debugBelch("getSmallBitmapzh - bitmap %ul, size %ul\n", bitmap, size); + return (bitmap, size, specialType); } unpackClosureFromStackFramezh(P_ stack, W_ index){ @@ -99,7 +108,7 @@ getLargeBitmapzh(P_ stack, W_ index){ (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), c); (size) = ccall getLargeBitmapSize(c); - ccall debugBelch("getLargeBitmapzh - size %ul\n", size); + // ccall debugBelch("getLargeBitmapzh - size %ul\n", size); return (stgArrBytes, size); } ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -49,5 +49,4 @@ library GHC.Exts.Heap.ProfInfo.Types GHC.Exts.Heap.ProfInfo.PeekProfInfo GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingDisabled - GHC.Exts.Heap.StackFFI GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f6ca800f8bc48ea749757654ebb926c7b6ea9eb...ae908a83a593fd4672e2234b3b149c43881fb8bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f6ca800f8bc48ea749757654ebb926c7b6ea9eb...ae908a83a593fd4672e2234b3b149c43881fb8bc You're receiving 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 Oct 8 17:22:31 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Sat, 08 Oct 2022 13:22:31 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] add experiment on translating calls Message-ID: <6341b1d784cf9_1eea6a5143c645916@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: bc4d6c88 by Norman Ramsey at 2022-10-08T13:22:14-04:00 add experiment on translating calls - - - - - 2 changed files: - compiler/GHC/Wasm/IR.hs - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/IR.hs ===================================== @@ -2,15 +2,19 @@ {-# LANGUAGE DataKinds, GADTs, RankNTypes, TypeOperators, KindSignatures #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeFamilies, StandaloneKindSignatures, PolyKinds #-} {-# LANGUAGE TypeFamilies, ConstraintKinds #-} +{-# LANGUAGE UndecidableInstances #-} -- for RevAppend module GHC.Wasm.IR ( WasmIR(..), (<>), pattern WasmIf32, wasmReturn , BrTableInterval(..), inclusiveInterval , brTableLimit + , WasmType(..), WasmTypeTag(..) , TypeList(..) + , RevAppend , WasmFunctionType(..) , SymName(..) @@ -129,11 +133,22 @@ data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where ----- - WasmCCall :: SymName -> WasmIR bool pre post -- completely untyped +-- WasmCCall :: SymName -> WasmIR bool pre post -- completely untyped WasmGlobalSet :: WasmTypeTag t -> SymName -> WasmIR bool (t : pre) pre WasmLocalGet :: WasmTypeTag t -> Int -> WasmIR bool pre (t : pre) WasmLocalSet :: WasmTypeTag t -> Int -> WasmIR bool (t : pre) pre + WasmCallNoResults :: TypeList ts -> WasmIR bool (RevAppend ts stack) stack + + WasmNop :: WasmIR bool stack stack -- translation of empty list of expressions + +type RevAppend :: forall a. [a] -> [a] -> [a] +type family RevAppend xs ys where + RevAppend '[] ys = ys + RevAppend (x:xs) ys = RevAppend xs (x : ys) + + + data BrTableInterval ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -3,11 +3,18 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies, StandaloneKindSignatures, PolyKinds #-} +{-# LANGUAGE ImpredicativeTypes #-} module GHC.Wasm.Tx ( tx , CG(..) , WasmExpr + + , WasmExprs + , txs + + , call ) where @@ -18,10 +25,13 @@ import Data.Type.Equality import qualified GHC.Cmm.Type as CT import GHC.Cmm.Expr +import GHC.Cmm.Node import GHC.Utils.Panic import GHC.Utils.Panic.Plain (assert) import GHC.Wasm.IR +import GHC.Cmm.Dataflow.Block + ---------------------------------------------------------------- --- --- Overview @@ -210,3 +220,31 @@ withFloatWidthTag :: CT.Width -> (forall t . WasmTypeTag t -> a) -> a withFloatWidthTag CT.W32 k = k TagF32 withFloatWidthTag CT.W64 k = k TagF64 withFloatWidthTag w _ = panic $ "width " ++ show w ++ " not supported on wasm target" + + +---------------------------------------------------------------- +-- new and experimental + +type WasmExprs bool ts = (forall stack . WasmIR bool stack (RevAppend ts stack)) + +txs :: CG bool codegen + => [CmmExpr] + -> (forall ts . TypeList ts -> WasmExprs bool ts -> codegen bool a) + -> codegen bool a +txs [] k = k TypeListNil WasmNop +txs (e:es) k = -- first expression is oldest on stack + txs es $ \ts codes -> + tx e $ \t code -> + k (TypeListCons t ts) (code <> codes) + +type WasmAction bool = (forall stack . WasmIR bool stack stack) + +call :: CG bool codegen + => CmmNode O O + -> (WasmAction bool -> codegen bool a) + -> codegen bool a +call (CmmUnsafeForeignCall _target [] arguments) k = + -- ran out of time to deal with result registers + txs arguments $ \ts codes -> + k (codes <> WasmCallNoResults ts) +call _ _ = panic "more cases needed" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc4d6c88c7f597a817a7bc318bfdffbb44620a6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc4d6c88c7f597a817a7bc318bfdffbb44620a6c You're receiving 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 Oct 8 19:16:03 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Sat, 08 Oct 2022 15:16:03 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] experimental approach to calls Message-ID: <6341cc731bcc1_1eea6a515546505c3@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: fedf7e7a by Norman Ramsey at 2022-10-08T15:15:44-04:00 experimental approach to calls - - - - - 2 changed files: - compiler/GHC/Wasm/IR.hs - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/IR.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE DerivingVia #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE DataKinds, GADTs, RankNTypes, TypeOperators, KindSignatures #-} {-# LANGUAGE FlexibleInstances #-} @@ -5,16 +6,18 @@ {-# LANGUAGE TypeFamilies, StandaloneKindSignatures, PolyKinds #-} {-# LANGUAGE TypeFamilies, ConstraintKinds #-} {-# LANGUAGE UndecidableInstances #-} -- for RevAppend +{-# LANGUAGE TypeFamilyDependencies #-} module GHC.Wasm.IR ( WasmIR(..), (<>), pattern WasmIf32, wasmReturn , BrTableInterval(..), inclusiveInterval , brTableLimit + , WasmLocal(..) , WasmType(..), WasmTypeTag(..) , TypeList(..) - , RevAppend + , RevAppend, Reverse , WasmFunctionType(..) , SymName(..) @@ -24,6 +27,7 @@ where import GHC.Prelude import Data.Kind +import Data.String import Data.Type.Equality @@ -88,6 +92,9 @@ data WasmFunctionType pre post = -- WebAssembly stack when the code runs, and `post` represents -- the state of the stack on completion. +newtype WasmLocal = WasmLocal Int + + data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where WasmPush :: WasmTypeTag t -> WasmIR bool stack (t ': stack) -> WasmIR bool stack (t ': stack) @@ -134,19 +141,36 @@ data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where ----- -- WasmCCall :: SymName -> WasmIR bool pre post -- completely untyped - WasmGlobalSet :: WasmTypeTag t -> SymName -> WasmIR bool (t : pre) pre - WasmLocalGet :: WasmTypeTag t -> Int -> WasmIR bool pre (t : pre) - WasmLocalSet :: WasmTypeTag t -> Int -> WasmIR bool (t : pre) pre +-- WasmGlobalSet :: WasmTypeTag t -> SymName -> WasmIR bool (t : pre) pre +-- WasmLocalGet :: WasmTypeTag t -> Int -> WasmIR bool pre (t : pre) + + WasmSetLocal :: WasmTypeTag t -> WasmLocal -> WasmIR bool (t : pre) pre + + WasmCall :: TypeList argtys + -> TypeList restys + -> SymName + -> WasmIR bool (RevAppend argtys '[]) (RevAppend restys '[]) - WasmCallNoResults :: TypeList ts -> WasmIR bool (RevAppend ts stack) stack + WasmCallIndirect + :: WasmTypeTag t -- type of function value on stack + -> TypeList argtys + -> TypeList restys + -- call target hasn't been added yet + -> WasmIR bool (t : RevAppend argtys '[]) (RevAppend restys '[]) WasmNop :: WasmIR bool stack stack -- translation of empty list of expressions + type RevAppend :: forall a. [a] -> [a] -> [a] type family RevAppend xs ys where RevAppend '[] ys = ys RevAppend (x:xs) ys = RevAppend xs (x : ys) +type Reverse :: forall a . [a] -> [a] +type family Reverse xs where + Reverse xs = RevAppend xs '[] + + @@ -201,3 +225,5 @@ wasmReturn tag e = WasmPush tag e `WasmSeq` WasmReturnTop tag newtype SymName = SymName FastString + deriving (Eq, IsString, Show) via FastString -- , Uniquable + deriving (Ord) via LexicalFastString ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -7,25 +7,34 @@ {-# LANGUAGE ImpredicativeTypes #-} module GHC.Wasm.Tx - ( tx + ( expr , CG(..) , WasmExpr , WasmExprs - , txs + , exprs - , call + , node + + , setLocals + , WasmLocal(..) + + , WasmAction, WasmTopAction ) where import GHC.Prelude +import Data.String import Data.Type.Equality import qualified GHC.Cmm.Type as CT -import GHC.Cmm.Expr +import GHC.Cmm.CLabel + import GHC.Cmm.Expr hiding (node) import GHC.Cmm.Node +import GHC.Platform +import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Utils.Panic.Plain (assert) import GHC.Wasm.IR @@ -55,8 +64,13 @@ import GHC.Cmm.Dataflow.Block -- property used in the prototype: the platform Boolean -- type is discoverable. + class Monad (codegen bool) => CG bool codegen where booleanWasmTypeTag :: codegen bool (WasmTypeTag bool) + cpsLocalReg :: LocalReg + -> (forall t . WasmTypeTag t -> WasmLocal -> codegen bool a) + -> codegen bool a + ---------------------------------------------------------------- @@ -76,7 +90,7 @@ type WasmExpr bool t = (forall stack . WasmIR bool stack (t : stack)) -- Sound Type-Indexed Type Checker (Functional Pearl), Haskell -- Symposium 2020 (https://doi.org/10.1145/3406088.3409015). -tx :: CG bool codegen +expr :: CG bool codegen => CmmExpr -> (forall t . WasmTypeTag t -> WasmExpr bool t -> codegen bool a) -> codegen bool a @@ -84,10 +98,11 @@ tx :: CG bool codegen -- The translation is organized as follows: -- --- * The main translation function `tx` dispatches on the form of a --- Cmm expression. +-- * The main translation function `expr` dispatches on the form of +-- a Cmm expression. (In general, a translation function is named +-- after the thing it translates.) -- --- * For every different type of Cmm operator, `tx` calls a +-- * For every different type of Cmm operator, `expr` calls a -- different auxiliary function: `wasmUnary`, `wasmBinary`, -- `wasmCompare`, and so on. -- @@ -96,12 +111,12 @@ tx :: CG bool codegen -- that each type of operator might require a Haskell translation -- function of a different type. But it's a bit irksome.) -- --- * Each auxiliary function calls back into `tx` to translate +-- * Each auxiliary function calls back into `expr` to translate -- operands, if any, then composes the resulting code. -- -- All functions are CPS. -tx expr k = +expr expr k = case expr of CmmLit (CmmInt n w) -> wasmNullaryInt w (flip WasmInt n) k CmmLit (CmmFloat x w) -> wasmNullaryFloat w (flip WasmFloat x) k @@ -169,7 +184,7 @@ wasmNullaryFloat w operator k = withFloatWidthTag w $ \tag -> k tag (operator tag) wasmUnary w [e] operator k = - tx e $ \tag code -> assert (tag `hasWidth` w) $ k tag (code <> operator tag) + expr e $ \tag code -> assert (tag `hasWidth` w) $ k tag (code <> operator tag) wasmUnary _ _ _ _ = panic "wrong number of operands to unary operator in Cmm" wasmBinary w es operator k = @@ -193,8 +208,8 @@ binaryCPS -> codegen bool a binaryCPS [e1, e2] k = -- would dearly love to use do notation here - tx e1 $ \tag1 code1 -> - tx e2 $ \tag2 code2 -> + expr e1 $ \tag1 code1 -> + expr e2 $ \tag2 code2 -> case tag1 `testEquality` tag2 of -- mandatory check Just Refl -> k tag1 code1 code2 Nothing -> panic "ill-typed Cmm" @@ -227,24 +242,71 @@ withFloatWidthTag w _ = panic $ "width " ++ show w ++ " not supported on wasm ta type WasmExprs bool ts = (forall stack . WasmIR bool stack (RevAppend ts stack)) -txs :: CG bool codegen +-- | Translate a list of Cmm expressions +exprs :: CG bool codegen => [CmmExpr] -> (forall ts . TypeList ts -> WasmExprs bool ts -> codegen bool a) -> codegen bool a -txs [] k = k TypeListNil WasmNop -txs (e:es) k = -- first expression is oldest on stack - txs es $ \ts codes -> - tx e $ \t code -> +exprs [] k = k TypeListNil WasmNop +exprs (e:es) k = -- first expression is oldest on stack + exprs es $ \ts codes -> + expr e $ \t code -> k (TypeListCons t ts) (code <> codes) type WasmAction bool = (forall stack . WasmIR bool stack stack) +type WasmTopAction bool = (WasmIR bool '[] '[]) + +-- | Translate an open-open Cmm node (action) -call :: CG bool codegen +node :: CG bool codegen => CmmNode O O - -> (WasmAction bool -> codegen bool a) + -> (WasmTopAction bool -> codegen bool a) + -- using WasmAction here, I can't get the code to typecheck + -- (non-injectivity of RevAppend) -> codegen bool a -call (CmmUnsafeForeignCall _target [] arguments) k = +node (CmmUnsafeForeignCall (ForeignTarget target _cconv) results arguments) k = -- ran out of time to deal with result registers - txs arguments $ \ts codes -> - k (codes <> WasmCallNoResults ts) -call _ _ = panic "more cases needed" + exprs arguments $ \argtys arg_codes -> + localRegs results $ \restys xs -> + wasmCall argtys restys target $ \code -> + k (arg_codes <> code <> setLocals restys xs) +node _ _ = panic "more cases needed" + +-- | Generate a Wasm call to a Cmm expression +wasmCall :: CG bool codegen + => TypeList argtypes + -> TypeList restypes + -> CmmExpr + -> (WasmIR bool (Reverse argtypes) (Reverse restypes) -> codegen bool a) + -> codegen bool a +wasmCall argtypes restypes (CmmLit (CmmLabel callee)) k = + k (WasmCall argtypes restypes (symNameFromCLabel callee)) +wasmCall argtypes restypes e k = + expr e $ \t code -> k (code <> WasmCallIndirect t argtypes restypes) + + +-- | set the given local variables from values on the evaluation stack +setLocals :: TypeList ts -> [WasmLocal] -> WasmIR bool (RevAppend ts stack) stack +setLocals TypeListNil [] = WasmNop +setLocals (TypeListCons t ts) (x:xs) = setLocals ts xs <> WasmSetLocal t x +setLocals _ _ = panic "this can't happen -- rewrite code to make it obvious?" + + +-- | use the CG monad to find the types and locations of local registers +localRegs :: CG bool codegen + => [LocalReg] + -> (forall ts . TypeList ts -> [WasmLocal] -> codegen bool a) + -> codegen bool a +localRegs [] k = k TypeListNil [] +localRegs (r:rs) k = + localRegs rs $ \ts xs -> + cpsLocalReg r $ \t x -> + k (TypeListCons t ts) (x:xs) + + + +symNameFromCLabel :: CLabel -> SymName +symNameFromCLabel lbl = + fromString $ + showSDocOneLine defaultSDocContext {sdocStyle = PprCode AsmStyle} $ + pprCLabel genericPlatform AsmStyle lbl View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fedf7e7a9f2854d1d8990a94c14eb62759a9dc09 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fedf7e7a9f2854d1d8990a94c14eb62759a9dc09 You're receiving 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 Oct 9 09:14:20 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Oct 2022 05:14:20 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 2 commits: Check sanity of stacks Message-ID: <634290ec5ff2_1eea6a5181c224671773@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 19730a4d by Sven Tennie at 2022-10-08T15:35:52+00:00 Check sanity of stacks - - - - - d264abaf by Sven Tennie at 2022-10-09T09:13:51+00:00 Start Update frames - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.cmm - rts/Printer.c - rts/sm/Sanity.c - rts/sm/Sanity.h Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -92,22 +92,24 @@ toBitmapPayload :: BitmapEntry -> BitmapPayload toBitmapPayload e | isPrimitive e = Primitive . toWord . closureFrame $ e where toWord (StackFrameIter (# s#, i# #)) = W# (derefStackWord# s# i#) -toBitmapPayload e = Closure . unsafePerformIO . toClosure . closureFrame $ e - where - toClosure (StackFrameIter (# s#, i# #)) = - case unpackClosureFromStackFrame# s# i# of - (# infoTableAddr, heapRep, pointersArray #) -> do - let infoTablePtr = Ptr infoTableAddr - ptrList = [case indexArray# pointersArray i of - (# ptr #) -> Box ptr - | I# i <- [0..I# (sizeofArray# pointersArray) - 1] - ] +toBitmapPayload e = Closure . toClosure unpackClosureFromStackFrame# . closureFrame $ e + +-- TODO: Get rid of unsafePerformIO +toClosure :: (StackSnapshot# -> Word# -> (# Addr#, ByteArray#, Array# Any #)) -> StackFrameIter -> CL.Closure +toClosure f# (StackFrameIter (# s#, i# #)) = unsafePerformIO $ + case f# s# i# of + (# infoTableAddr, heapRep, pointersArray #) -> do + let infoTablePtr = Ptr infoTableAddr + ptrList = [case indexArray# pointersArray i of + (# ptr #) -> Box ptr + | I# i <- [0..I# (sizeofArray# pointersArray) - 1] + ] - getClosureDataFromHeapRep heapRep infoTablePtr ptrList + getClosureDataFromHeapRep heapRep infoTablePtr ptrList unpackStackFrameIter :: StackFrameIter -> StackFrame -unpackStackFrameIter (StackFrameIter (# s#, i# #)) = +unpackStackFrameIter sfi@(StackFrameIter (# s#, i# #)) = case (toEnum . fromIntegral) (W# (getInfoTableType# s# i#)) of RET_BCO -> RetBCO RET_SMALL -> let !(# bitmap#, size#, special# #) = getSmallBitmap# s# i# @@ -123,7 +125,8 @@ unpackStackFrameIter (StackFrameIter (# s#, i# #)) = in RetBig payloads RET_FUN -> RetFun - UPDATE_FRAME -> UpdateFrame + -- TODO: Decode update frame type + UPDATE_FRAME -> UpdateFrame NormalUpdateFrame (toClosure unpackUpdateeFromUpdateFrame# sfi) CATCH_FRAME -> CatchFrame UNDERFLOW_FRAME -> UnderflowFrame STOP_FRAME -> StopFrame @@ -158,6 +161,8 @@ toInt# (I# i) = i foreign import prim "unpackClosureFromStackFramezh" unpackClosureFromStackFrame# :: StackSnapshot# -> Word# -> (# Addr#, ByteArray#, Array# b #) +foreign import prim "unpackUpdateeFromUpdateFramezh" unpackUpdateeFromUpdateFrame# :: StackSnapshot# -> Word# -> (# Addr#, ByteArray#, Array# b #) + foreign import prim "derefStackWordzh" derefStackWord# :: StackSnapshot# -> Word# -> Word# data BitmapPayload = Closure CL.Closure | Primitive Word @@ -191,8 +196,14 @@ data SpecialRetSmall = RestoreCCCSEval deriving (Enum, Eq,Show) +data UpdateFrameType = + NormalUpdateFrame | + BhUpdateFrame | + MarkedUpdateFrame + deriving (Show) + data StackFrame = - UpdateFrame | + UpdateFrame UpdateFrameType CL.Closure | CatchFrame | CatchStmFrame | CatchRetryFrame | ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -53,6 +53,7 @@ advanceStackFrameIterzh (P_ stack, W_ index) { P_ nextClosure; nextClosure = StgStack_sp(stack) + WDS(index); ASSERT(LOOKS_LIKE_CLOSURE_PTR(nextClosure)); + ccall checkSTACK(stack); } // ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul, stackBottom %p\n", stack, newStack, frameSize, newIndex, hasNext, stackBottom); @@ -96,9 +97,20 @@ unpackClosureFromStackFramezh(P_ stack, W_ index){ P_ closurePtr, closurePtrPrime; closurePtr = (StgStack_sp(stack) + WDS(index)); closurePtrPrime = P_[closurePtr]; + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closurePtrPrime)); jump stg_unpackClosurezh(closurePtrPrime); } +unpackUpdateeFromUpdateFramezh(P_ stack, W_ index){ + P_ closurePtr, closurePtrPrime, updateePtr; + closurePtr = (StgStack_sp(stack) + WDS(index)); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closurePtr)); + updateePtr = StgUpdateFrame_updatee(closurePtr); + // ccall debugBelch("unpackUpdateeFromUpdateFramezh - frame %p, updateePtr %p\n", closurePtr, updateePtr); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(updateePtr)); + jump stg_unpackClosurezh(updateePtr); +} + getLargeBitmapzh(P_ stack, W_ index){ P_ c, stgArrBytes; W_ size; ===================================== rts/Printer.c ===================================== @@ -260,6 +260,7 @@ printClosure( const StgClosure *obj ) case UPDATE_FRAME: { StgUpdateFrame* u = (StgUpdateFrame*)obj; + debugBelch("printObj - frame %p, indirectee %p\n", u, u->updatee); debugBelch("%s(", info_update_frame(obj)); printPtr((StgPtr)GET_INFO((StgClosure *)u)); debugBelch(","); ===================================== rts/sm/Sanity.c ===================================== @@ -42,7 +42,6 @@ int isHeapAlloced ( StgPtr p); static void checkSmallBitmap ( StgPtr payload, StgWord bitmap, uint32_t ); static void checkLargeBitmap ( StgPtr payload, StgLargeBitmap*, uint32_t ); static void checkClosureShallow ( const StgClosure * ); -static void checkSTACK (StgStack *stack); static W_ countNonMovingSegments ( struct NonmovingSegment *segs ); static W_ countNonMovingHeap ( struct NonmovingHeap *heap ); @@ -700,7 +699,7 @@ checkCompactObjects(bdescr *bd) } } -static void +void checkSTACK (StgStack *stack) { StgPtr sp = stack->sp; ===================================== rts/sm/Sanity.h ===================================== @@ -39,6 +39,7 @@ void memInventory (bool show); void checkBQ (StgTSO *bqe, StgClosure *closure); +void checkSTACK (StgStack *stack); #include "EndPrivate.h" #endif /* DEBUG */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae908a83a593fd4672e2234b3b149c43881fb8bc...d264abafc07006298a3571fbfc5958e5f2966739 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae908a83a593fd4672e2234b3b149c43881fb8bc...d264abafc07006298a3571fbfc5958e5f2966739 You're receiving 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 Oct 9 11:32:10 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Oct 2022 07:32:10 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Decode Update Frame type Message-ID: <6342b13a5a2ff_1eea6a529f4f646879b0@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: ac527c8e by Sven Tennie at 2022-10-09T11:31:45+00:00 Decode Update Frame type - - - - - 4 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm - rts/Printer.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -126,7 +126,11 @@ unpackStackFrameIter sfi@(StackFrameIter (# s#, i# #)) = RetBig payloads RET_FUN -> RetFun -- TODO: Decode update frame type - UPDATE_FRAME -> UpdateFrame NormalUpdateFrame (toClosure unpackUpdateeFromUpdateFrame# sfi) + UPDATE_FRAME -> let + c = toClosure unpackUpdateeFromUpdateFrame# sfi + !t = (toEnum . fromInteger . toInteger) (W# (getUpdateFrameType# s# i#)) + in + UpdateFrame t c CATCH_FRAME -> CatchFrame UNDERFLOW_FRAME -> UnderflowFrame STOP_FRAME -> StopFrame @@ -165,6 +169,8 @@ foreign import prim "unpackUpdateeFromUpdateFramezh" unpackUpdateeFromUpdateFram foreign import prim "derefStackWordzh" derefStackWord# :: StackSnapshot# -> Word# -> Word# +foreign import prim "getUpdateFrameTypezh" getUpdateFrameType# :: StackSnapshot# -> Word# -> Word# + data BitmapPayload = Closure CL.Closure | Primitive Word instance Show BitmapPayload where @@ -194,13 +200,13 @@ data SpecialRetSmall = RetL | RestoreCCCS | RestoreCCCSEval - deriving (Enum, Eq,Show) + deriving (Enum, Eq, Show) data UpdateFrameType = NormalUpdateFrame | BhUpdateFrame | MarkedUpdateFrame - deriving (Show) + deriving (Enum, Eq, Show) data StackFrame = UpdateFrame UpdateFrameType CL.Closure | ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -79,6 +79,23 @@ StgWord getSpecialRetSmall(StgClosure *closure) { } } +StgWord getUpdateFrameType(StgClosure* c) { + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + const StgInfoTable* info = c->header.info; + if (info == &stg_upd_frame_info) { + return 0; + } else if (info == &stg_bh_upd_frame_info) { + return 1; + } else if (info == &stg_marked_upd_frame_info) { + return 2; + } else { + // Cannot do more than warn and exit. + errorBelch("Cannot decide Update Frame type for info table %p closure %p.", info, c); + stg_exit(EXIT_INTERNAL_ERROR); + } +} + StgWord getBitmapSize(StgClosure *c){ ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -93,6 +93,20 @@ getSmallBitmapzh(P_ stack, W_ index) { return (bitmap, size, specialType); } +getLargeBitmapzh(P_ stack, W_ index){ + P_ c, stgArrBytes; + W_ size; + c = StgStack_sp(stack) + WDS(index); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); + + (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), c); + (size) = ccall getLargeBitmapSize(c); + + // ccall debugBelch("getLargeBitmapzh - size %ul\n", size); + + return (stgArrBytes, size); +} + unpackClosureFromStackFramezh(P_ stack, W_ index){ P_ closurePtr, closurePtrPrime; closurePtr = (StgStack_sp(stack) + WDS(index)); @@ -111,16 +125,12 @@ unpackUpdateeFromUpdateFramezh(P_ stack, W_ index){ jump stg_unpackClosurezh(updateePtr); } -getLargeBitmapzh(P_ stack, W_ index){ - P_ c, stgArrBytes; - W_ size; +getUpdateFrameTypezh(P_ stack, W_ index){ + P_ c; c = StgStack_sp(stack) + WDS(index); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - (stgArrBytes) = ccall getLargeBitmaps(MyCapability(), c); - (size) = ccall getLargeBitmapSize(c); - - // ccall debugBelch("getLargeBitmapzh - size %ul\n", size); - - return (stgArrBytes, size); + W_ type; + (type) = ccall getUpdateFrameType(c); + return (type); } ===================================== rts/Printer.c ===================================== @@ -456,6 +456,7 @@ const char *info_update_frame(const StgClosure *closure) // it pointing to the code or struct members when compiling with // TABLES_NEXT_TO_CODE. const StgInfoTable *info = closure->header.info; + debugBelch("info_update_frame - closure %p, info %p\n", closure, info); if (info == &stg_upd_frame_info) { return "NORMAL_UPDATE_FRAME"; } else if (info == &stg_bh_upd_frame_info) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ac527c8e0b45c197d5eee1fcecbbf01f8033a728 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ac527c8e0b45c197d5eee1fcecbbf01f8033a728 You're receiving 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 Oct 9 11:59:43 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Oct 2022 07:59:43 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Decode catch frames Message-ID: <6342b7afc2702_1eea6a529f4f8c6903d2@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: ead7958b by Sven Tennie at 2022-10-09T11:59:22+00:00 Decode catch frames - - - - - 2 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -131,7 +131,11 @@ unpackStackFrameIter sfi@(StackFrameIter (# s#, i# #)) = !t = (toEnum . fromInteger . toInteger) (W# (getUpdateFrameType# s# i#)) in UpdateFrame t c - CATCH_FRAME -> CatchFrame + CATCH_FRAME -> let + c = toClosure unpackHandlerFromCatchFrame# sfi + exceptionsBlocked = W# (getCatchFrameExceptionsBlocked# s# i#) + in + CatchFrame exceptionsBlocked c UNDERFLOW_FRAME -> UnderflowFrame STOP_FRAME -> StopFrame ATOMICALLY_FRAME -> AtomicallyFrame @@ -171,6 +175,10 @@ foreign import prim "derefStackWordzh" derefStackWord# :: StackSnapshot# -> Word foreign import prim "getUpdateFrameTypezh" getUpdateFrameType# :: StackSnapshot# -> Word# -> Word# +foreign import prim "unpackHandlerFromCatchFramezh" unpackHandlerFromCatchFrame# :: StackSnapshot# -> Word# -> (# Addr#, ByteArray#, Array# b #) + +foreign import prim "getCatchFrameExceptionsBlockedzh" getCatchFrameExceptionsBlocked# :: StackSnapshot# -> Word# -> Word# + data BitmapPayload = Closure CL.Closure | Primitive Word instance Show BitmapPayload where @@ -210,7 +218,7 @@ data UpdateFrameType = data StackFrame = UpdateFrame UpdateFrameType CL.Closure | - CatchFrame | + CatchFrame Word CL.Closure | CatchStmFrame | CatchRetryFrame | AtomicallyFrame | ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -134,3 +134,23 @@ getUpdateFrameTypezh(P_ stack, W_ index){ (type) = ccall getUpdateFrameType(c); return (type); } + +unpackHandlerFromCatchFramezh(P_ stack, W_ index){ + P_ closurePtr, closurePtrPrime, handlerPtr; + closurePtr = (StgStack_sp(stack) + WDS(index)); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closurePtr)); + handlerPtr = StgCatchFrame_handler(closurePtr); + // ccall debugBelch("unpackUpdateeFromUpdateFramezh - frame %p, updateePtr %p\n", closurePtr, updateePtr); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(handlerPtr)); + jump stg_unpackClosurezh(handlerPtr); +} + +getCatchFrameExceptionsBlockedzh(P_ stack, W_ index){ + P_ closurePtr, closurePtrPrime, updateePtr; + closurePtr = (StgStack_sp(stack) + WDS(index)); + ASSERT(LOOKS_LIKE_CLOSURE_PTR(closurePtr)); + + W_ exceptions_blocked; + exceptions_blocked = StgCatchFrame_exceptions_blocked(closurePtr); + return (exceptions_blocked); +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ead7958b8116fbb651649864b7b6f6fb09a3634d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ead7958b8116fbb651649864b7b6f6fb09a3634d You're receiving 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 Oct 9 14:31:24 2022 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Sun, 09 Oct 2022 10:31:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/rename-fail-op Message-ID: <6342db3ccde49_1eea6a514c8701896@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/rename-fail-op at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/rename-fail-op You're receiving 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 Oct 9 20:04:45 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Sun, 09 Oct 2022 16:04:45 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 323 commits: chore: extend `.editorconfig` for C files Message-ID: <6343295dc5b1e_1eea6a514c87129e8@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 35cc5749 by Josh Meredith at 2022-10-09T15:26:01-04:00 Add ghcjs changes to deriveConstants: - change String targetOS option in deriveConstants to an enum - separate out getWantedGHSJS, removing generated c file in this path - - - - - 71de9922 by doyougnu at 2022-10-09T15:26:01-04:00 Add JavaScript code generator Adapt code generator of GHCJS to GHC head. Currently it is only enabled with the hidden -fjavascript flag. It produces .o files that can't be used yet except by GHCJS's linker. Codegen: doc Codegen: correctly return linkable object Now we can build a static library (-staticlib) Codegen: doc genLit Codegen: use assignAll Codegen: introduce TypedExpr Refactor assignAll et al, add documentation Codegen: minor changes Doc - - - - - ef951bd2 by doyougnu at 2022-10-09T15:26:02-04:00 Add JS.Rts JS.Rts: compiles reword: progress on RtsTypes StgToJS.Config: add SDoc Context JSRts: move ppr, workaround def type JSRts.Types: compiles JS.Rts: closer to compiling JS.Rts: move jsIdIdent' to StgToJS.Monad JS.Rts: remove unused predicates JS: cleanup, comment sections, math funcs to Make JS.Rts.Types: compiles StgToJS.Expr: fix compilation errors StgToJS.DataCon: move initClosure JS.Rts: remove Alloc module JS.Rts: initalize Rts module, remove redundant fs JS: init Rts.Alloc move initClosure JS.Apply: unwinding combinators in progress JS: add helpers and fixmes JS.Rts.Apply: no more e's, add closure, reg helper StgToJS: add ToStat instance ClosureInfo JS.Rts.Apply: closer to compiling JS.Rts.Apply: more removal of # JS.Rts.Apply: (#) removed JS.Rts.Apply: compiles JS.Rts.Rts: just pretty printing left JS.Rts: Add Notes JS.Rts: add file headers and notes JS.Rts.Rts: fixing stringy issues JS.Rts.Rts: compiles JS.Rts.Rts: fix non-exhaustive patterns warnings - - - - - 16a2f5cf by Sylvain Henry at 2022-10-09T15:26:02-04:00 Doc has been moved into GHC.StgToJs top-level module - - - - - 776fb310 by Sylvain Henry at 2022-10-09T15:26:02-04:00 JS.Rts; refactoring and move to StgToJS * add closure manipulation helpers and use them in Apply * add cache (Array) for pre-generated PAP names * reduce line length: * use BlockArguments instead of parens * remove implicit mconcat in jVar's body Rts: more refactorings Rts: move into StgToJS hierarchy - - - - - 0dae3eec by Sylvain Henry at 2022-10-09T15:26:02-04:00 JS: cleanup, renaming, better module layout Various degrees of cleanup adapting GHCJS to GHC. We move several functions to CoreUtils, remove duplication between the JS.Rts.Apply and Apply module and factor out closure related code into a Closure module for cohesion. Deduplicate code between Rts.Apply and Apply Move might_be_a_function into CoreUtils Factorize closure stuff into Closure module Rename closureExtra into closureField Minor renamings, comments... - - - - - 1e850381 by Sylvain Henry at 2022-10-09T15:26:02-04:00 JS.Backend: add FFI code but don't implement yet FFI: don't crash on JavaScript foreign imports Note that they are still not desugared properly!! But the following cmd doesn't crash anymore: ghc -fjavascript Test.hs -fforce-recomp -ddump-tc -fno-code -ddump-ds FFI: adapt GHCJS desugarer FFI: support direct application The following example: foo :: Int# -> Int# foo = add 50000# foreign import javascript "(function(x,y) { return (x + y) })" add :: Int# -> Int# -> Int# is compiled into an application like this: var h$mainZCMzifoozur2_e; h$mainZCMzifoozur2_e = (function() { var h$mainZCMziaddzur1; h$mainZCMziaddzur1 = h$r1.d1; var h$$mainZCMzietazuB0_8KXnScrCjF5; h$$mainZCMzietazuB0_8KXnScrCjF5 = h$r2; h$r3 = h$$mainZCMzietazuB0_8KXnScrCjF5; h$r2 = 50000; h$r1 = h$mainZCMziaddzur1; return h$ap_2_2_fast(); return h$rs(); }); var h$mainZCMziaddzur1_e; h$mainZCMziaddzur1_e = (function() { var h$$mainZCMzidszusAk_236l8r0P8S9; h$$mainZCMzidszusAk_236l8r0P8S9 = h$r2; var h$$mainZCMzids1zusAl_336l8r0P8S9; h$$mainZCMzids1zusAl_336l8r0P8S9 = h$r3; var h$$mainZCM_2; var h$$mainZCMziwildzusAn_536l8r0P8S9; try { h$$mainZCMziwildzusAn_536l8r0P8S9 = (function(x,y) { return (x + y) })(h$$mainZCMzidszusAk_236l8r0P8S9, h$$mainZCMzids1zusAl_336l8r0P8S9) } catch(except) { return h$throwJSException(except) }; var h$$mainZCMzids3zusAp_736l8r0P8S9; h$$mainZCMzids3zusAp_736l8r0P8S9 = h$$mainZCMziwildzusAn_536l8r0P8S9; h$r1 = h$$mainZCMzids3zusAp_736l8r0P8S9; return h$rs(); }); FFI: correctly dispatch for foreign exports too FFI: move C FFI desugaring into its own module FFI: avoid DynFlags in toJsName (copy of toCName) - - - - - 42d85173 by Sylvain Henry at 2022-10-09T15:26:02-04:00 Configure: preliminary support for triple js-unknown-ghcjs - - - - - 66833b16 by Sylvain Henry at 2022-10-09T15:26:02-04:00 Driver: enable JS backend by default for JS arch - - - - - 748e7b22 by doyougnu at 2022-10-09T15:26:02-04:00 JS.Backend: Add JS specific Linker JS: initialize Linker, DynamicLinking JS.Printer: adapted to GHC Head JS.Printer: some cleanup and init Printer StgToJS.Printer: Compiles JS.Linker: Add types, expose JS keywords JS.Syntax: add Binary instance on Ident's JS.Linker: Migrate more Types to Data.Binary JS.Linker.Types: compiles and adapted to GHC Head JS.Linker.Types: compiles JS.Linker.Types: add UseBase type JS.Linker: Comments and Cleanup JS.Linker.Types: add TH types, Env type, DepsLoc JS.Linker: more FIXMEs numerous Linker fixes JS.Linker: removed Text references JS.UnitUtils: add package related helper functions JS.Linker: more DynFlags removal JS.Linker: Time for semantic errors JS.Linker: DynFlags finally removed JS.Linker: 107 compile errors to go JS.Linker.Utils: initialized, adapted to GHC Head JS.Linker.Utils: initialize Utils module JS.Linker.Utils: more utils JS.Rts: move rtsText to Rts JS.Linker: linkerStats implemented JS.Compactor: compiles, adapted to GHC Head JS.Compactor: have to retrofit compact for linker JS.Linker.Compactor: unwinding lenses JS.Linker.Compactor: comments over addItem JS.Linker.Compactor: Lenses removed JS.Linker.Compactor: SHA256 removed JS.Linker.Compactor: only missing instances left JS.Linker.Compactor: compiles JS.Linker: compiles, adapted to ghc Head JS.Linker: More progress JS.Linker: link in memory compiles JS.Linker: just shims left JS.Linker.DynamicLinking compiles: adapted to head JS.Linker.DynamicLinking: initialization JS.Linker.DynamicLinking: compiles up to Variants JS.Variants: initialize JS.Linker: numerous and various fixes JS.Linker.DynamicLinking: only small errors left JS.Linker.Archive: compiles, adapted to GHC Head JS.Linker: initialize Archive compat module JS.Linker.Archive: minor fixes JS.Linker.DynamicLinking: compiles JS.Linker: cleanup, remove Variants, add comments fixup: more cleanup JS.Linker: more cleanup and comments - - - - - 9ea08ac7 by Sylvain Henry at 2022-10-09T15:26:02-04:00 Minor panic fix - - - - - ebd1d244 by Sylvain Henry at 2022-10-09T15:26:03-04:00 Linker: fix stage2 build - - - - - 97724316 by Sylvain Henry at 2022-10-09T15:26:03-04:00 Configure: Add support fo JS as unregistered ABI Configure: detect emscripten tools e.g. on ArchLinux: EMSDK=/usr/lib/emscripten EMSDK_LLVM=/opt/emscripten-llvm ./configure --target=js-unknown-ghcjs Configure: detect nm tool too, required by Hadrian Configure: make StgToJS use non-unregisterised ABI It should probably be a third kind of ABI... - - - - - f0d49495 by doyougnu at 2022-10-09T15:26:03-04:00 JS.Linker: Hook up to GHC.Driver.Pipeline JS.Linker.Types: Add newGhcjsEnv function JS.UnitUtils: fix encodeModule api JS.Linker: more removal of HscEnv JS.Linker: hooked into GHC.Driver.Pipeline - - - - - 1db89f70 by Sylvain Henry at 2022-10-09T15:26:03-04:00 VERY WIP Hadrian/rts fixes export EMSDK_LLVM=/opt/emscripten-llvm export EMSDK=/usr/lib/emscripten export PATH=./inplace/ghcjs_toolchain/bin:$PATH ./configure --target=js-unknown-ghcjs ./hadrian/build --flavour=quick-js -j --bignum=native --docs=none -V - - - - - a08f672b by Sylvain Henry at 2022-10-09T15:26:03-04:00 Force creation of rts library with dummy file - - - - - 9e27218e by Sylvain Henry at 2022-10-09T15:26:03-04:00 ghc-prim: avoid building C files - - - - - da35a8d3 by Sylvain Henry at 2022-10-09T15:26:03-04:00 Hadrian: disable -fllvm - - - - - b3856db9 by Sylvain Henry at 2022-10-09T15:26:03-04:00 JS: fix caches Note that the fact that we need index 0 may hide another issue... - - - - - cca64ce4 by Sylvain Henry at 2022-10-09T15:26:03-04:00 codegen: enhance genCon debug message - - - - - dd1f7394 by Sylvain Henry at 2022-10-09T15:26:04-04:00 RTS: fix stupid comment - - - - - 95028071 by Sylvain Henry at 2022-10-09T15:26:04-04:00 RTS: embed headers - - - - - ad20f319 by Sylvain Henry at 2022-10-09T15:26:04-04:00 JS.StgToJS: add documentation header for JS Types - - - - - f0894bb9 by Sylvain Henry at 2022-10-09T15:26:04-04:00 CodeGen: refactor ExprCtx code - - - - - b8887cad by Sylvain Henry at 2022-10-09T15:26:04-04:00 CodeGen: cache LNE frame size - - - - - 42a7791c by doyougnu at 2022-10-09T15:26:04-04:00 JS.Types: Add Outputable for TypedExpr - - - - - 24104db0 by doyougnu at 2022-10-09T15:26:04-04:00 JS.CoreUtils: handle IOPort case - - - - - 0154f97c by doyougnu at 2022-10-09T15:26:04-04:00 JS.Expr: Fix unhandled datacon for RuntimeRep - - - - - 7f1fb526 by doyougnu at 2022-10-09T15:26:04-04:00 JS.Literals: Adapt genLit to new Literal domain - - - - - 704b6fc8 by Sylvain Henry at 2022-10-09T15:26:05-04:00 RTS: expose more headers (required to build base) - - - - - 6a44a96e by Sylvain Henry at 2022-10-09T15:26:05-04:00 Base: don't build C and Cmm sources with ghcjs - - - - - 4394d668 by Sylvain Henry at 2022-10-09T15:26:05-04:00 Tentatively set NO_REGS for JS platforms - - - - - 7f6f214f by Sylvain Henry at 2022-10-09T15:26:05-04:00 CodeGen: output LitRubbish as null JS values - - - - - a0abc133 by Sylvain Henry at 2022-10-09T15:26:05-04:00 base: disable forkOS and bound thread machinery - - - - - 65cb1133 by Sylvain Henry at 2022-10-09T15:26:05-04:00 CodeGen: support StackSnapshot# in primTypeVt - - - - - 01310944 by Sylvain Henry at 2022-10-09T15:26:05-04:00 CodeGen: better debug message for assignCoerce1 - - - - - d189c7e9 by Sylvain Henry at 2022-10-09T15:26:05-04:00 Misc: enable HasDebugCallStack for zipWithEqual* - - - - - 4b68d809 by Sylvain Henry at 2022-10-09T15:26:05-04:00 CodeGen: remove useless imports - - - - - b0fb1bc8 by Sylvain Henry at 2022-10-09T15:26:06-04:00 Stg: expose pprStgAlt - - - - - 3f5c68e0 by Sylvain Henry at 2022-10-09T15:26:06-04:00 CodeGen: restore assignAll (instead of assignAllEqual) - - - - - e66ae05d by Sylvain Henry at 2022-10-09T15:26:06-04:00 CodeGen: handle proxy# - - - - - cbe82449 by doyougnu at 2022-10-09T15:26:06-04:00 ghc-heap: Don't compile Cmm file for JS-Backend - - - - - 7bf25c0b by doyougnu at 2022-10-09T15:26:06-04:00 Driver.Main: minor refactor do_code_gen To clearly separate the JS-Backend from any other backend - - - - - f6fa8dd5 by Sylvain Henry at 2022-10-09T15:26:06-04:00 Configure: fix echo on Mac, add ghcjs target OS - - - - - 98a261e3 by Sylvain Henry at 2022-10-09T15:26:06-04:00 Configure: fix previous commit - - - - - 272f8404 by Luite Stegeman at 2022-10-09T15:26:06-04:00 fix package name in module name field of system dependencies - - - - - 101e3999 by Luite Stegeman at 2022-10-09T15:26:06-04:00 fix duplicate module name in symbols - - - - - 22f7802e by doyougnu at 2022-10-09T15:26:07-04:00 GHCi.FFI: ignore ffi.h and friends for js-backend - - - - - beb9c5e4 by Sylvain Henry at 2022-10-09T15:26:07-04:00 RTS: fix build of native rts - - - - - 7206d41c by Sylvain Henry at 2022-10-09T15:26:07-04:00 Remove temporary -fjavascript flag - - - - - 0fccb36a by Sylvain Henry at 2022-10-09T15:26:07-04:00 Codegen: fix symbol names ppr - - - - - 236ae54a by Sylvain Henry at 2022-10-09T15:26:07-04:00 Outputable: add ShortText instance - - - - - ed87f00e by Sylvain Henry at 2022-10-09T15:26:07-04:00 Linker: enhance debugging message - - - - - 38da872d by Sylvain Henry at 2022-10-09T15:26:07-04:00 Remove unused ghcjs unit related code - - - - - d3bd2da0 by Sylvain Henry at 2022-10-09T15:26:07-04:00 ghci: Avoid unused-xyz warnings - - - - - d263a5a8 by Sylvain Henry at 2022-10-09T15:26:08-04:00 Linker: remove wiring of ghcjs-prim and ghcjs-th They will be replaced by ghc-prim, base, template-haskell, etc. - - - - - 2e906cce by Sylvain Henry at 2022-10-09T15:26:08-04:00 Add outputable instance for Deps - - - - - d3c1a3f5 by doyougnu at 2022-10-09T15:26:08-04:00 Docs: JS.Syntax, JS.Make docs done JS-backend: Add documentation headers Docs: JS.Syntax done Docs: JS.Make done Docs: JS.Make JS.Syntax refined a bit - - - - - 398e5451 by Sylvain Henry at 2022-10-09T15:26:08-04:00 Rename u_env into unit_env (more common) - - - - - 3bb2b12e by Sylvain Henry at 2022-10-09T15:26:08-04:00 Linker: deduplication + fixes - deduplicate code that was copied from old GHC - explicitly add preloadUnits to the link - avoid calling getShims - - - - - f12d510e by Sylvain Henry at 2022-10-09T15:26:08-04:00 Linker: reenable packStrings (not yet implemented though) - - - - - 5cac75a6 by Sylvain Henry at 2022-10-09T15:26:08-04:00 ShortText: add singleton - - - - - aad905f2 by Sylvain Henry at 2022-10-09T15:26:08-04:00 Linker: force less efficient (but working) static encoding - - - - - 7c8e3583 by Luite Stegeman at 2022-10-09T15:26:08-04:00 add GHCJS modules to base package - - - - - f8e74165 by Sylvain Henry at 2022-10-09T15:26:09-04:00 Linker: remove JS Shims,tiny GHC.Linker refactor - - - - - 80d6da85 by doyougnu at 2022-10-09T15:26:09-04:00 Hadrian: QuickJS ways [] --> Set - - - - - e58246e9 by doyougnu at 2022-10-09T15:26:09-04:00 JS-Backend: rebased to master 468f919b First rebase of the JS-Backend. This rebase includes the JS backend combined with !7442 (new backend design). Unfortunately we have to short circuit the new backend design because the JS backend takes over after STG and not after StgToCmm. What's working: - hadrian builds JS backend - JS backend outputs .js files and "links" them What still has to be done: - JS backend is missing core js libraries as we add these we discover bugs in the linker and js rts. - - - - - bcd06d79 by doyougnu at 2022-10-09T15:26:09-04:00 JS: silence haddock warnings JS Backend: remove misc. warnings - - - - - bf8262d4 by doyougnu at 2022-10-09T15:26:09-04:00 JS Backend: ghcjs_HOST_OS --> js_HOST_ARCH - - - - - da86b426 by Sylvain Henry at 2022-10-09T15:26:09-04:00 JS.Linker: add shims GHCJS uses JS files for primitive things like the GC and RTS. We call these JS files "shims". This sequence of commits adds shims from JS and includes them for linking. In addition the shim directory is controlled via an evironment variable JS_RTS_PATH...at least for now. Linker: implement tryReadShimFile Linker: link with shims provided via an env variable Use JS_RTS_PATH to provide a directory into which .js and .js.pp files will be linked into rts.js JS.Linker: add js dir at root, fix js cpp includes JS.gc.pp: remove variadic macro JS.RTS: add rts JS shims files, remove shim CPP RTS: remove the need for rts.h and add rts JS files rts.h only contained a few constants duplicated in the codegen. Let's use the Haskell version as the single source of truth and pass defined values explicitly to cpp command line ("-DXYZ=abc" arguments). Also switch from "raw" (use_cpp_and_not_cc_dash_E = True) to the opposite: in both case we call "cc -E" (meh), but with False the preprocessor doesn't choke one varargs in macros. RTS: remove integer.js.pp We use the native ghc-bignum backend, so we don't need the GMP compatible JS code. In addition, this code was failing to run as it requires the JSBN (https://www.npmjs.com/package/jsbn) "Javascript big number" library, which we don't necessarily have installed. RTS: fix typo in field name RTS: generate CPP macros in Haskell RTS: share common CPP def into CAFs - - - - - 8f2adaad by Sylvain Henry at 2022-10-09T15:26:09-04:00 CPP: disable line markers CPP: move option before input filename (to be squashed) - - - - - 1d991126 by Sylvain Henry at 2022-10-09T15:26:09-04:00 Linker: add more types Some cleanup Enhance and fix LinkerStats Document and refactor renderLinker Split collectDeps Fix collectDeps Fix linker stats rendering Remove unused seqListSpine It isn't used in ghcjs either - - - - - 6904cc48 by Sylvain Henry at 2022-10-09T15:26:09-04:00 Add some missing primops (Word32,Int32) Also fix the rendering of missing primops (they must be z-encoded to avoid having a "#" in their JS name) - - - - - d3bf0329 by Sylvain Henry at 2022-10-09T15:26:10-04:00 FFI: desugar every foreign import/export in JS with JS backend It means we also desugar CApi calls into JS. It's probably wrong but instead of generating invalid JS we will only get the failure at runtime when we will use the function. fixup - - - - - bb703fa4 by doyougnu at 2022-10-09T15:26:10-04:00 JS.Linker: remove dflags includePath workaround. We implemented a workaround for shims that modified the dynflags includePaths so that the JS backend would find the rts.h file during CPP of shims. Since aebcca98 this is no longer required because we've removed the need for rts.h completely. Thus, this commit reverts that modification. - - - - - 1a3c6974 by Sylvain Henry at 2022-10-09T15:26:10-04:00 Temporarily wire-in base's shim Use JS_BASE_PATH env var to set base's shim directory (js_base for now) Also minor other changes base: fix encoding for JS arch - - - - - a0ace338 by Sylvain Henry at 2022-10-09T15:26:10-04:00 Add primops Add primop - - - - - 49b349af by doyougnu at 2022-10-09T15:26:10-04:00 Make Shims type, refactor JS Linker This commit: - Adds a proper Shim type and associated utilities. These utitlies are purposefully limited to ensure the ShimLbl tag is preserved thus guarenteeing shim ordering at link time. - Refactors the JS backend linker to use this ordering and Shim API. The ordering is not correct (yet!) but with this API its much easier to triage, experiment and diagnose link time issues. Refactor linker to compile time shim ordering - - - - - 4725d939 by doyougnu at 2022-10-09T15:26:10-04:00 Base: Adapt primitives to JS backend, add base.js - - - - - 9bb57096 by doyougnu at 2022-10-09T15:26:10-04:00 Base: Remove binding forms in JS ffi - - - - - aae076e2 by Josh Meredith at 2022-10-09T15:26:10-04:00 Replace GHCJS Objectable with GHC Binary - - - - - 8bffa1ad by Sylvain Henry at 2022-10-09T15:26:10-04:00 Binary: remove unused Map instance - - - - - 1eb4d06d by Sylvain Henry at 2022-10-09T15:26:11-04:00 CodeGen: Add export list - - - - - 80e22889 by Sylvain Henry at 2022-10-09T15:26:11-04:00 Primops: add some Int64/Word64 primops - - - - - f01918eb by Sylvain Henry at 2022-10-09T15:26:11-04:00 base: fix one ffi import - - - - - a89c6f8b by doyougnu at 2022-10-09T15:26:11-04:00 base: CPP for JS-backend, adapt write in base shim This commit ports over each CPP directive from GHCJS to base. In addition, it adds struct.js.pp to Base shim directory and modifies h$base_write to always take 6 arguments. Thereby avoiding errors such as "c(bytesWritten) is not a function". The missing parameter was the file descriptor object, fdo, which was looked up in the function itself and is now passed through to comport with the FFI expectations. - - - - - 1bb9c6f8 by doyougnu at 2022-10-09T15:26:11-04:00 fixup: remove redundant struct.js.pp in js_base - - - - - b391c14e by doyougnu at 2022-10-09T15:26:11-04:00 JS.Linker: enable linker RTS symbols - - - - - 5337c478 by doyougnu at 2022-10-09T15:26:11-04:00 base.GHCJS: adapt Prim to direct call FFI format - - - - - 38afb1c9 by doyougnu at 2022-10-09T15:26:11-04:00 Linker: Load JSVal from base not ghc-prim - - - - - ad777264 by doyougnu at 2022-10-09T15:26:11-04:00 fixup: caught one more reference to JSVal in prim - - - - - 3ffea260 by Sylvain Henry at 2022-10-09T15:26:12-04:00 base: match on js arch , not ghcjs os - - - - - fae9f7a7 by Sylvain Henry at 2022-10-09T15:26:12-04:00 Fix MK_JSVAL - - - - - 0884eff3 by doyougnu at 2022-10-09T15:26:12-04:00 Prim: cleanup comments - - - - - 299c0d66 by doyougnu at 2022-10-09T15:26:12-04:00 JS.Prim: add Int64 PrimOps - - - - - 5283f47d by Sylvain Henry at 2022-10-09T15:26:12-04:00 Vendor MD5 lib - - - - - c67bc88e by Sylvain Henry at 2022-10-09T15:26:12-04:00 More 64-bit primops - - - - - d96089e6 by Sylvain Henry at 2022-10-09T15:26:12-04:00 CodeGen: use if10 helper - - - - - be1e754d by Sylvain Henry at 2022-10-09T15:26:12-04:00 Ppr: fix selector to avoid adding a newline - - - - - cd925df6 by doyougnu at 2022-10-09T15:26:13-04:00 base: GHCJS.Prim make ffi imports use anon funcs - - - - - 7ec12790 by Sylvain Henry at 2022-10-09T15:26:13-04:00 Linker: disable invalid constructors again - - - - - 11a32208 by Sylvain Henry at 2022-10-09T15:26:13-04:00 More 64-bits primops - - - - - f1c83c42 by Sylvain Henry at 2022-10-09T15:26:13-04:00 Fix base_write function - - - - - dc5c3a43 by Sylvain Henry at 2022-10-09T15:26:13-04:00 Fix base_write for 32-bit size_t - - - - - 84b0b015 by Sylvain Henry at 2022-10-09T15:26:13-04:00 Configure: fix detection of the target toolchain - - - - - 563c8cfc by Sylvain Henry at 2022-10-09T15:26:13-04:00 Remove js_base directory - - - - - b98caf92 by Sylvain Henry at 2022-10-09T15:26:13-04:00 Kill Node when the main loop reports an unhandled exception - - - - - 2b36baa8 by Sylvain Henry at 2022-10-09T15:26:13-04:00 CodeGen: preparation to make match on primops complete - - - - - 7cf71a42 by Sylvain Henry at 2022-10-09T15:26:41-04:00 Primops: fix Compact primops - - - - - 3a6c3df8 by Sylvain Henry at 2022-10-09T15:26:41-04:00 Ignore result arity for some exception primops - - - - - b8899558 by Sylvain Henry at 2022-10-09T15:26:41-04:00 Fix more primops. Bump array submodule! - - - - - f4021c52 by Sylvain Henry at 2022-10-09T15:26:41-04:00 Compact: fix return of 3 values - - - - - 6ec9807e by Sylvain Henry at 2022-10-09T15:26:41-04:00 Configure: switch to absolute path - - - - - b81a7cff by Sylvain Henry at 2022-10-09T15:26:41-04:00 Add a few primops - - - - - cbf7ad2c by Sylvain Henry at 2022-10-09T15:26:41-04:00 Primop: implement WordAdd2 - - - - - 23d07897 by Luite Stegeman at 2022-10-09T15:26:41-04:00 quick fix for uTypeVt and typePrimRep panics this may cause other panics, a full fix will require a bit more rework and probably removal of VarType - - - - - 41af93a2 by Josh Meredith at 2022-10-09T15:26:42-04:00 Replace ShortText with (Lexical)FastString in GHCJS backend - - - - - 5d46445d by Sylvain Henry at 2022-10-09T15:26:42-04:00 Primops: add arithmetic ops Primops: add decodeDoubleInt64 back Primop: added timesInt2# Primop: add mulWord32 and mul2Word32 - - - - - 3d7ab0e3 by Sylvain Henry at 2022-10-09T15:26:42-04:00 Reduce dependency on goog - - - - - 67c954b2 by Sylvain Henry at 2022-10-09T15:26:42-04:00 Primop: implement quotWord32, remWord32, and quotRemWord32 - - - - - 44b021ad by Sylvain Henry at 2022-10-09T15:26:42-04:00 Primop: Implement quotRem2Word32, misc fixes Primop: implement quotRem2Word32 Primop: fix timesInt2# Primop: fix some shifting primops - - - - - 61c48a91 by Sylvain Henry at 2022-10-09T15:26:42-04:00 Fix bug in upd_frame I've introduced this bug when I've refactored the code to use helpers to assign closures. - - - - - 1f0fd890 by Sylvain Henry at 2022-10-09T15:26:42-04:00 Primop: throw an exception for unimplemented primops - - - - - f38cf6dc by Sylvain Henry at 2022-10-09T15:26:42-04:00 Primop: fix remWord32 - - - - - b177de73 by Josh Meredith at 2022-10-09T15:26:42-04:00 Configure: add EMSDK_BIN, match emsdk expectations Change EMSDK vars to match emscripten/emsdk_env.sh definitions Add EMSDK_BIN environment variable to configure - - - - - cc3dbdae by Sylvain Henry at 2022-10-09T15:26:43-04:00 resultSize: correctly handle Void# - - - - - 5ff65797 by Sylvain Henry at 2022-10-09T15:26:43-04:00 Primop: fix Sized test, more shifting fixes Primop: ensure that we return u32 values for word primops Also a refactoring from i3 to i32 for clarity. Primop: add/fix more shifting primops Primops: fix Sized test! - - - - - 9c68c4a9 by Sylvain Henry at 2022-10-09T15:26:43-04:00 StgToJS.Apply: Docs Doc Doc - - - - - bb22fad9 by Josh Meredith at 2022-10-09T15:26:43-04:00 Fix EMSDK configure condition - - - - - 06dcd4b0 by doyougnu at 2022-10-09T15:26:43-04:00 StgToJS.Arg: Unboxable Literal Optimization note - - - - - f2471294 by Sylvain Henry at 2022-10-09T15:26:43-04:00 Fix Outputable instances for JExpr/JVal - Put orphan instances in JS.Ppr - Also fix some redundant imports - - - - - 6ede1a7d by doyougnu at 2022-10-09T15:26:43-04:00 configure: avoid CXX stdlib check for js backend and some cleanup for a previously mis-applied commit during rebasing - - - - - d3d8ec31 by doyougnu at 2022-10-09T15:26:43-04:00 fixup: misc. fixes post rebase - - - - - 09963e93 by Sylvain Henry at 2022-10-09T15:26:43-04:00 PrimOps: add more 64-bit primops PrimOp: implement more 64-bit primops + PM fix Ensure that we cover every primop explicitly - - - - - 62e1ecd1 by Sylvain Henry at 2022-10-09T15:26:44-04:00 PrimOp: correclty (un)handle new thread related primops - - - - - 619d7f25 by Sylvain Henry at 2022-10-09T15:26:44-04:00 PrimOp: disable LabelThreadOp for now - - - - - 92e959ce by Sylvain Henry at 2022-10-09T15:26:44-04:00 Minor doc/cleanup Fix more redundant imports - - - - - 3f3b2018 by doyougnu at 2022-10-09T15:26:44-04:00 base: GHCJS.Prim directory --> GHC.JS.Prim - - - - - c476d412 by Luite Stegeman at 2022-10-09T15:26:44-04:00 implement KeepAlive primop - - - - - 1c68d691 by Sylvain Henry at 2022-10-09T15:26:44-04:00 Remove orphan instance for StaticArg - - - - - bea6576f by Sylvain Henry at 2022-10-09T15:26:44-04:00 Remove redundant jsIdIdent' function - - - - - a46f8a0d by Sylvain Henry at 2022-10-09T15:26:44-04:00 Split StgToJS.Monad into StgToJS.{Monad,Ids,Stack} - - - - - b9ab556a by Sylvain Henry at 2022-10-09T15:26:44-04:00 Apply: remove commented case (wasn't optimized either in latest ghcjs) - - - - - 00cd0a21 by Sylvain Henry at 2022-10-09T15:26:45-04:00 Doc: Apply Apply: doc and refactoring - use new types instead of Bool/Int - factorize some code - - - - - e1813774 by Sylvain Henry at 2022-10-09T15:26:45-04:00 Primop: arith fixes Primop: fix 64-bit shifting primops + add some traces Primop: fix quotRem2Word32 Primop: fix timesInt2. Progress towards passing arith003 PrimOp: fix timesInt32 PrimOp: use mulWord32 when appropriate - - - - - 12a2f3c8 by doyougnu at 2022-10-09T15:26:45-04:00 Configure: remove EMSDK hacks and wrapper scripts configure JS: remove wrapper scripts Configure: remove EMSDK hacks. Use emconfigure instead emconfigure ./configure --target=js-unknown-ghcjs - - - - - 0ed3da29 by Sylvain Henry at 2022-10-09T15:26:45-04:00 GHCJS.Prim leftovers - - - - - a7c0c506 by Sylvain Henry at 2022-10-09T15:26:45-04:00 Linker: fix linking issue for tuples - - - - - 972961fa by Sylvain Henry at 2022-10-09T15:26:45-04:00 FFI: remove narrowing Fix tests such as cgrun015 (Core lint error) - - - - - 253e710a by Sylvain Henry at 2022-10-09T15:26:45-04:00 Linker: disable logs with default verbosity - - - - - 6cdbae35 by Sylvain Henry at 2022-10-09T15:26:45-04:00 Append program name in top-level exception handler - - - - - d43e64e6 by doyougnu at 2022-10-09T15:26:45-04:00 GHC.JS: Remove FIXMEs JS.Syntax: Remove FIXMEs JS.Make: remove FIXMEs JS.Ppr/Transform: Remove FIXMEs - - - - - bbc1ed43 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Primop: fix timesInt2# Pass arith003 test - - - - - d63abddc by doyougnu at 2022-10-09T15:26:46-04:00 JS.Linker.Linker: remove FIXMEs, clean dead code - - - - - 1eed67d3 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Linker: link platform shim before the others - - - - - 7c80a317 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Primops: rework 64-bit and Word32 primops - Use BigInt instead of complex and buggy bit twiddling. We'll assess performance later. Let's use a correct and simple implementation for now. - Implement previously missing 64-bit quot and rem - Refactor logical operators and Prim module more generally - - - - - b1112405 by Sylvain Henry at 2022-10-09T15:26:46-04:00 PrimOp: fixup previous commit... - - - - - c918b596 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Primop: fixup previous commit - - - - - 5576ba27 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Doc: minor changes - - - - - cbe2feab by Sylvain Henry at 2022-10-09T15:26:46-04:00 Add debug option to watch for insertion of undefined/null in the stack - - - - - 775811c9 by Sylvain Henry at 2022-10-09T15:26:46-04:00 Apply: fix tag generation - - - - - 36e9a750 by Sylvain Henry at 2022-10-09T15:26:47-04:00 Remove redundant import - - - - - 1ecfa2a7 by Sylvain Henry at 2022-10-09T15:26:47-04:00 Testsuite: disable Cmm tests with the JS backend - - - - - d4a291d7 by Sylvain Henry at 2022-10-09T15:26:47-04:00 Base: fix c_interruptible_open - - - - - 1d1670d2 by Sylvain Henry at 2022-10-09T15:26:47-04:00 Base: fix typo in long_from_number - - - - - 08df8fae by Sylvain Henry at 2022-10-09T15:26:47-04:00 Env: only add program name to errors, not to traces - - - - - 998bfbcf by Sylvain Henry at 2022-10-09T15:26:47-04:00 Testsuite: disable more Cmm tests - - - - - 1a0f32b8 by doyougnu at 2022-10-09T15:26:47-04:00 JS.Linker: removes FIXMEs JS.Linker.Linker: remove FIXMEs, clean dead code StgToJS.Linker.Utils: remove FIXMEs Compactor: Remove FIXMEs StgToJS.Linker.Types: Remove FIXMEs JS.Linker.Archive/Dynamic: remove FIXMEs StgToJS.Linker.Shims: remove FIXMEs - - - - - fbb51305 by doyougnu at 2022-10-09T15:26:47-04:00 JS RTS: remove FIXMEs StgToJS.Rts.Types: Remove FIXMEs - - - - - b48161c5 by Sylvain Henry at 2022-10-09T15:26:47-04:00 Primop: fix bswap32/64 (cf cgrun072) - - - - - 9bf42ba4 by Sylvain Henry at 2022-10-09T15:26:48-04:00 Testsuite: normalise ghc program name - - - - - 13e86921 by doyougnu at 2022-10-09T15:26:48-04:00 JS Backend: Remove FIXMEs StgToJS.Apply: Remove FIXMEs StgToJS.FFI: remove FIXMEs StgToJS.Expr: remove FIXMEs StgToJS: Remove FIXMEs - - - - - 751e97cc by Sylvain Henry at 2022-10-09T15:26:48-04:00 Enable RTS args filtering (cf cgrun025) - - - - - 931d4fe5 by Sylvain Henry at 2022-10-09T15:26:48-04:00 Remove trailing whitespaces (whitespace test) - - - - - f705834b by Sylvain Henry at 2022-10-09T15:26:48-04:00 Testsuite: remove platform prefix for unlit tool - - - - - 505ba980 by Sylvain Henry at 2022-10-09T15:26:48-04:00 Primop: fix Int64 conversion/negate (integerConversions test) - - - - - 7f1a03a7 by Sylvain Henry at 2022-10-09T15:26:48-04:00 Linker: remove message with default verbosity - - - - - 93a42249 by Sylvain Henry at 2022-10-09T15:26:48-04:00 Testsuite: normalise .jsexe suffix - - - - - 8777d6da by Sylvain Henry at 2022-10-09T15:26:48-04:00 Remove warning about orphan instance - - - - - 380821f3 by Sylvain Henry at 2022-10-09T15:26:49-04:00 Compactor: disable dead code - - - - - ac04433f by Sylvain Henry at 2022-10-09T15:26:49-04:00 Exception: implement raiseUnderflow etc. as primops - - - - - 916f63fc by Sylvain Henry at 2022-10-09T15:26:49-04:00 Primop: fix Int8/18 quot/rem - - - - - 6f92413a by Sylvain Henry at 2022-10-09T15:26:49-04:00 Linker: refactor wired-in deps - - - - - 15991886 by Sylvain Henry at 2022-10-09T15:26:49-04:00 Ppr: remove useless left padding for functions in JS dumps - - - - - 1ca11bbe by Josh Meredith at 2022-10-09T15:26:49-04:00 Disable llvm ways and ghci for JS backend testsuite - - - - - 33d806e9 by Sylvain Henry at 2022-10-09T15:26:49-04:00 StaticPtr: don't generate CStubs for the JS backend - - - - - 547121db by Sylvain Henry at 2022-10-09T15:26:49-04:00 StaticPtr: fix hs_spt_lookup after upstream change - - - - - 72c344d4 by Sylvain Henry at 2022-10-09T15:26:49-04:00 Testsuite: fix normalisation for unlit T8430 shows: `js-unknown-ghcjs-unlit' failed in phase `Literate pre-processor'. (Exit code: 1) Notice the quote around the program name. So I've made the regex match more cases (i.e. not only lines starting with the program name). - - - - - 1b6015d7 by Sylvain Henry at 2022-10-09T15:26:50-04:00 Codegen: fix codegen of string literals Due to FastString change: Before: Text.pack . BSC.unpack After: mkFastString . BSC.unpack It seems that Text handles buggy multi-byte codepoints split into several String Chars. - - - - - e744b1b0 by Sylvain Henry at 2022-10-09T15:26:50-04:00 CPP: fix LINE markers. Only disable them for JS - - - - - b6ed6f77 by Luite Stegeman at 2022-10-09T15:26:50-04:00 add JavaScript files listed in js-sources to package archives - - - - - 108c416b by Luite Stegeman at 2022-10-09T15:26:50-04:00 update rts js files to include recent fixes - - - - - 281309c2 by Luite Stegeman at 2022-10-09T15:26:50-04:00 fix definitions in js/rts.h - - - - - 02510036 by Josh Meredith at 2022-10-09T15:26:50-04:00 stopgap fix for missing ghc-pkg in cross-compiler tests - - - - - c46fe293 by Sylvain Henry at 2022-10-09T15:26:50-04:00 Testsuite: better fix for finding prefixed tools - - - - - 1398a729 by Sylvain Henry at 2022-10-09T15:26:50-04:00 Ppr: add hangBrace helper - - - - - 8b59ced1 by Sylvain Henry at 2022-10-09T15:26:50-04:00 Only declare ccs var in profiling mode - - - - - 42b8b529 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Don't consider recursive bindings as inline nor as evaluated Fix mdo001 - - - - - 3a88e374 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Hadrian: disable shared libs for JS target - - - - - 9421b358 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Support -ddump-stg-final with the JS backend - - - - - 6b9bff37 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Add ticky_ghc0 flavour transformer to ticky stage1 - - - - - 378c20cf by Sylvain Henry at 2022-10-09T15:26:51-04:00 Don't read object file when -ddump-js isn't passed - - - - - 3fdfd999 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Object: remove dead code + renaming - - - - - c271194d by Sylvain Henry at 2022-10-09T15:26:51-04:00 Object: replace SymbolTableR with Dictionary - - - - - 027f2921 by Sylvain Henry at 2022-10-09T15:26:51-04:00 Object: refactoring - - - - - 34ba13cc by Sylvain Henry at 2022-10-09T15:26:52-04:00 RTS: link platform.js before the others! - - - - - 787415d1 by Sylvain Henry at 2022-10-09T15:26:52-04:00 Hadrian: treat JS objects similarly to other objects - - - - - f8d4770b by Luite Stegeman at 2022-10-09T15:26:52-04:00 fix javascript FFI calls for read and write - - - - - 7268481a by doyougnu at 2022-10-09T15:26:52-04:00 propagate ppr code changes to JS backend - - - - - 37af1bb5 by Sylvain Henry at 2022-10-09T15:26:52-04:00 Switch from Data.Binary and ByteString to BinHandle - - - - - e9da018a by Sylvain Henry at 2022-10-09T15:26:52-04:00 Perf: use Ppr's LeftMode to output JS - - - - - 15b68589 by doyougnu at 2022-10-09T15:26:52-04:00 Primops: Add {Index,Write,Read}ByteArrayAs ops Still need to check for correctness based on T4442. minor doc fixes fixup: add some Index..As primops fixup missed type signature Primops: Add WriteByteArrayOp_Word8AsFoo ops Primops: {Index,Read,Write}FooAsBar done except Addr's Primops: add {Index,Read,Write}ByteArrayAsAddr ops These will need to be tested for correctness with T4442.hs - - - - - 5c933316 by Sylvain Henry at 2022-10-09T15:26:52-04:00 Move platform.js to base (it must be linked first) - - - - - 1e739d42 by Sylvain Henry at 2022-10-09T15:26:52-04:00 Remove old shim directory - - - - - e39c2879 by doyougnu at 2022-10-09T15:26:53-04:00 JS.Prim: more PrimOps {IndexByteArrayAs, CAS} Primop: WriteByteArrayOp_Word8AsChar use setInt8 Primops: remove dv_s_u8 This function is non-sensical. Due to the infelicities of JS as a platform we must use Int8 and friends to write, then coerce to a word, thus dv_s_iN are the only legal calls for a write, and dv_s_uN legal for Index and Reads. Primops: set dv_u8 to correct method call should be getUint8, not getUInt8, of course the naming convention changes ever so slightly for Words. Primops: T4442 finishes ByteArrayAs still fails JS.Prim: More IndexByteAAs primops JS.Prim: Prefetch PrimOps are noOps JS.Primops: Doc explaining lack of vector support JS.Prim: add CAS and Fetch Ops - - - - - 1481534a by doyougnu at 2022-10-09T15:26:53-04:00 GHC.Utils.Binary: BinDictionary -> FSTable Rename to avoid naming conflict with haddock. - - - - - 11357323 by Josh Meredith at 2022-10-09T15:26:53-04:00 Adjust derefnull test exit code for ghcjs - - - - - bdacc17f by doyougnu at 2022-10-09T15:26:53-04:00 Fix Driver missing type signature warnings - - - - - 3e0aa394 by doyougnu at 2022-10-09T15:26:53-04:00 PipeLine.Execute: silence warnings on JS backend - - - - - f9cba182 by doyougnu at 2022-10-09T15:26:53-04:00 JS.Primops: Add Bit reverse ops - - - - - f6555b16 by doyougnu at 2022-10-09T15:26:53-04:00 SysTools.Tasks: quiet non-totality warnings - - - - - ae8e504a by doyougnu at 2022-10-09T15:26:53-04:00 JS.Primops: Add InterlockedExchange Addr Word - - - - - 82881a73 by Sylvain Henry at 2022-10-09T15:26:53-04:00 base: conditional js-sources - - - - - be7233fe by Sylvain Henry at 2022-10-09T15:26:54-04:00 TH: add support for JS files - - - - - 6b18d1d5 by Sylvain Henry at 2022-10-09T15:26:54-04:00 Linker: fix creation of directories in output paths - - - - - 5f94513d by Sylvain Henry at 2022-10-09T15:26:54-04:00 Backpack: fix empty stubs - - - - - 617fae3b by Sylvain Henry at 2022-10-09T15:26:54-04:00 Add encodeDouble/Float RTS functions - - - - - cb192c6e by Sylvain Henry at 2022-10-09T15:26:54-04:00 encodeDouble: correctly handle 0 base - - - - - 93c10d72 by doyougnu at 2022-10-09T15:26:54-04:00 JS.Primops: Add listThreads op - - - - - d979d3a2 by doyougnu at 2022-10-09T15:26:54-04:00 JS.Primops: Add Read/WriteAddrOp ops - - - - - cb0e371e by doyougnu at 2022-10-09T15:26:54-04:00 JS: Linker and Compactor: cleanup and docs Compactor: Cleanup: Remove dead comments JS.Linker.Types: cleanup and document module - - - - - 44ccba3d by doyougnu at 2022-10-09T15:26:54-04:00 StgToJS.Linker: Add docs to utility modules StgToJS.Linker.Utils: more docs StgToJS.Linker.Archive: more docs - - - - - 634e6db5 by doyougnu at 2022-10-09T15:26:55-04:00 StgToJS.Object: Add documentation - - - - - ad2bdae1 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Refactor Expr - - - - - 7e9c05ed by Sylvain Henry at 2022-10-09T15:26:55-04:00 Object: reduce pinned allocation. And don't forget to hClose invalid objects - - - - - 633431e8 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Fix pdep (cgrun075) - - - - - 198efab7 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Fix error message (don't mention emscripten) - - - - - 181614a4 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Add Float/Word casts - - - - - fcf0377c by Sylvain Henry at 2022-10-09T15:26:55-04:00 Disable HPC tests with JS backend - - - - - a91724f2 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Fix encodeDouble/Float - - - - - 36dd6c97 by Sylvain Henry at 2022-10-09T15:26:55-04:00 Implement putchar (fix cgrun015) - - - - - 77295a16 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Fix decoding of denormalized floats - - - - - 84255645 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Fix isFloatDenormalized function - - - - - 29515de8 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Reuse convert buffer - - - - - 597fa877 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Reuse convert buffer bis - - - - - 5f506bd6 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Skip some tests that require the dynamic linker - - - - - de84ed2c by Josh Meredith at 2022-10-09T15:26:56-04:00 JavaScript ShrinkSmallMutableArrayOp_Char & GetSizeofSmallMutableArrayOp - - - - - 0b67a804 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Disable more linker tests - - - - - b60425ea by Sylvain Henry at 2022-10-09T15:26:56-04:00 Testsuite: better normalisation for ghc and ghc-pkg Allow normalisation for ghc and ghc-pkg anywhere in the output, not just at the beginning of the line. Fix T1750 and ghcpkg05 for example - - - - - 3b8cfc71 by Sylvain Henry at 2022-10-09T15:26:56-04:00 Skip T14373 because it requires Cmm - - - - - 379c065c by Sylvain Henry at 2022-10-09T15:26:57-04:00 Disable cg010 with JS backend - - - - - e7cb1f4b by Sylvain Henry at 2022-10-09T15:26:57-04:00 Testsuite: better normalisation of .jsexe extension - - - - - 6da79496 by doyougnu at 2022-10-09T15:26:57-04:00 JS: Linker,Rts docs and cleanup JS.Linker: Cleanup: remove unused functions/types JS.Rts.Types: remove dead code, docs StgToJS.RTS: cleanup and more docs - - - - - d8bcd7b0 by Sylvain Henry at 2022-10-09T15:26:57-04:00 Disable recomp015 - - - - - 6a3a8779 by Sylvain Henry at 2022-10-09T15:26:57-04:00 Minor refactoring - - - - - 97aa2448 by Sylvain Henry at 2022-10-09T15:26:57-04:00 Temporary fix the testsuite bug - - - - - 95dd39c3 by doyougnu at 2022-10-09T15:26:57-04:00 JS.StgToJS.Types: Docs and cleanup - - - - - d20738d2 by Josh Meredith at 2022-10-09T15:26:57-04:00 change JS.Transform.Idents* to use UniqDSet from Set - - - - - 2d807e03 by Sylvain Henry at 2022-10-09T15:26:57-04:00 Minor Linker cleanup Minor cleanup - - - - - c6140a1c by Sylvain Henry at 2022-10-09T15:26:58-04:00 Linker: load all the dependent units transitively - - - - - f0883a76 by doyougnu at 2022-10-09T15:26:58-04:00 JS: Add Docs and cleanup StgToJS.{Arg,Ids} JS.Arg: docs and cleanup StgToJS.Arg: add minimal docs StgToJS.Ids: Add header - - - - - a45df4f2 by Sylvain Henry at 2022-10-09T15:26:58-04:00 Implement h$sleep (T5611) - - - - - 0e1cd5e0 by Sylvain Henry at 2022-10-09T15:26:58-04:00 Linker: don't link the same unit twice - - - - - b1885325 by doyougnu at 2022-10-09T15:26:58-04:00 JS: docs, cleanup, StgToJS.{Expr,DataCon,Stack} StgToJS.Deps/Expr: add docs StgToJS.DataCon: add minor docs StgToJS.Stack: Docs and cleanup In particular: -- Removing some single use functions -- Some minor refactors related to these removals StgToJS: comments on static args and optimizeFree - - - - - 83ab2e02 by Sylvain Henry at 2022-10-09T15:26:58-04:00 Disable compact tests - - - - - 86906bf6 by Sylvain Henry at 2022-10-09T15:26:58-04:00 Add support for JS files passed on the command line - - - - - 98453fbe by Sylvain Henry at 2022-10-09T15:26:58-04:00 Minor cleanup in compactor - - - - - e0c3cf92 by Sylvain Henry at 2022-10-09T15:26:59-04:00 Fix encoding of unboxed strings (don't pass through FastString/h$str) - - - - - c889dcd1 by doyougnu at 2022-10-09T15:26:59-04:00 JS: Misc fixes post Del-Cont rebase - - - - - 1a7681b1 by Sylvain Henry at 2022-10-09T15:26:59-04:00 Minor cleanup - - - - - 716df754 by Sylvain Henry at 2022-10-09T15:26:59-04:00 Add log1p and expm1 (fix cgrun078) - - - - - 9971f80e by Sylvain Henry at 2022-10-09T15:26:59-04:00 Assume existence of Math.fround and use it in Float's primops - - - - - 435c720e by Sylvain Henry at 2022-10-09T15:26:59-04:00 Disable "debug" test - - - - - d7fa892c by Sylvain Henry at 2022-10-09T15:26:59-04:00 Implement copyMutableArray with overlap support - - - - - 35fd207a by Sylvain Henry at 2022-10-09T15:26:59-04:00 Skip CmmSwitchTests - - - - - 41b5425d by Sylvain Henry at 2022-10-09T15:26:59-04:00 Fix WordToDouble/WordToFloat (Word2Float32 test) - - - - - fecff007 by Sylvain Henry at 2022-10-09T15:27:00-04:00 Skip one more test - - - - - 4b7e942f by Sylvain Henry at 2022-10-09T15:27:00-04:00 Fix after GHC.Tuple to GHC.Tuple.Prim - - - - - 3323909b by Sylvain Henry at 2022-10-09T15:27:00-04:00 Fix InterlockedExchange primops (cgrun080) - - - - - 549a0f51 by Sylvain Henry at 2022-10-09T15:27:00-04:00 Disable T12059 - - - - - c6a66c4b by Sylvain Henry at 2022-10-09T15:27:00-04:00 Implement sqrt/sqrtf (fix T14619) - - - - - 92b92c5c by Sylvain Henry at 2022-10-09T15:27:00-04:00 Skip more tests - - - - - 77486ef1 by Sylvain Henry at 2022-10-09T15:27:00-04:00 Disable conc012 - - - - - 986f9fbd by Sylvain Henry at 2022-10-09T15:27:00-04:00 Disable more Cmm tests - - - - - 5feb234c by Sylvain Henry at 2022-10-09T15:27:00-04:00 Fix AtomicPrimops test. Some refactoring in Prim too - - - - - 98a6a4ba by Sylvain Henry at 2022-10-09T15:27:01-04:00 Use GHCJS's signExtend/narrow - - - - - cac23166 by Josh Meredith at 2022-10-09T15:27:01-04:00 Implement get/set thread label prims - - - - - 5dbe2a34 by doyougnu at 2022-10-09T15:27:01-04:00 JS: remove Linker.Archive module - - - - - 849477a8 by Sylvain Henry at 2022-10-09T15:27:01-04:00 Start disabling tests that use TH/interpreter - - - - - 00457b86 by Josh Meredith at 2022-10-09T15:27:01-04:00 Add flagged bounds checking to JS primops - - - - - dd3255d6 by Sylvain Henry at 2022-10-09T15:27:01-04:00 Disable more tests - - - - - 19e96c90 by Sylvain Henry at 2022-10-09T15:27:01-04:00 Disable T1791 - - - - - 68773b71 by Sylvain Henry at 2022-10-09T15:27:01-04:00 Raise NonTermination as an async exception - - - - - 17b9d04d by Sylvain Henry at 2022-10-09T15:27:01-04:00 Expect IOPort test to be broken - - - - - cbe5475d by Sylvain Henry at 2022-10-09T15:27:02-04:00 Implement rts_isThreaded (fix jules_xref2) - - - - - 22f5abb7 by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable outofmem2 test - - - - - 498e1cd0 by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable tests using C files - - - - - 7ce5061f by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable delimited continuation tests - - - - - b0ffa21a by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable native RTS flag tests - - - - - d7ed2895 by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable more tests - - - - - 825a7858 by Sylvain Henry at 2022-10-09T15:27:02-04:00 Disable more tests - - - - - 296a9e9d by Sylvain Henry at 2022-10-09T15:27:02-04:00 Annotation tests require an interpreter - - - - - 33cdf83b by Sylvain Henry at 2022-10-09T15:27:03-04:00 Skip more tests - - - - - 946a7399 by Sylvain Henry at 2022-10-09T15:27:03-04:00 Disable try_putmvar tests that use C files - - - - - 32e4ee07 by Sylvain Henry at 2022-10-09T15:27:03-04:00 Disable even more tests - - - - - 33c18f2a by Sylvain Henry at 2022-10-09T15:27:03-04:00 Disable test using Cmm - - - - - f2e5ba78 by Sylvain Henry at 2022-10-09T15:27:03-04:00 Linker: remove dead code (base, compactor) - - - - - 63a3fd99 by Sylvain Henry at 2022-10-09T15:27:03-04:00 Better shims linking - - - - - 916fb690 by Sylvain Henry at 2022-10-09T15:27:03-04:00 Make isJsFile a bit faster by only reading the header - - - - - 5ef9358a by Sylvain Henry at 2022-10-09T15:27:03-04:00 Linker: write directly into output file - - - - - 2a70b20a by Sylvain Henry at 2022-10-09T15:27:03-04:00 Linker: more refactoring - - - - - ef409720 by Sylvain Henry at 2022-10-09T15:27:04-04:00 Lazy loading of JStat in object code - - - - - e04ddd7c by Sylvain Henry at 2022-10-09T15:27:04-04:00 Use Ppr hack to render directly into a file - - - - - 16696e4f by Sylvain Henry at 2022-10-09T15:27:04-04:00 Fix backpack dependencies - - - - - ca078ce8 by doyougnu at 2022-10-09T15:27:04-04:00 testsuite: add js_skip_csources function Used to indicate a test that fails in the JS backend because the JS Backend does not yet support c-sources in cabal files. - - - - - 888271a3 by doyougnu at 2022-10-09T15:27:04-04:00 testsuite: JS: skip tests which use c-sources Skip because these tests use c-sources and the JS backend does not yet support including c-sources testsuite: JS backend: skip backpack tests testsuite: JS: skip c-sources ffi tests testsuite: JS: skip multipleHomeUnits_odir testsuite: JS: disable more backpack tests testsuite: JS: disable c-sources rts tests testsuite: JS: skip c-sources codeGen tests testsuite: JS: skip c-sources generics test - - - - - 26 changed files: - .editorconfig - README.md - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Data/Graph/Directed.hs - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/Backend/Internal.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/StgToCmm.hs - + compiler/GHC/Driver/Config/StgToJS.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Phases.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Foreign/C.hs - compiler/GHC/HsToCore/Foreign/Decl.hs - + compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Tidy/StaticPtrTable.hs - + compiler/GHC/JS/Make.hs - + compiler/GHC/JS/Parser/Header.hs - + compiler/GHC/JS/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7287a0521bf21cb800ff3455b744b5d3b3ab450f...888271a3818c849b981b1d099ee9067758f2de6f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7287a0521bf21cb800ff3455b744b5d3b3ab450f...888271a3818c849b981b1d099ee9067758f2de6f You're receiving 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 Oct 10 07:04:08 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 10 Oct 2022 03:04:08 -0400 Subject: [Git][ghc/ghc][wip/js-staging] use exit code 134 for JS prim bounds checks Message-ID: <6343c3e84d7c_1eea6a51414757717@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: b82f6e7b by Josh Meredith at 2022-10-10T07:03:58+00:00 use exit code 134 for JS prim bounds checks - - - - - 1 changed file: - compiler/GHC/StgToJS/Prim.hs Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1476,7 +1476,7 @@ boundsChecked False _ _ r = r boundsChecked True xs i r = ifS ((i .<. xs .^ "length") .&&. (i .>=. zero_)) r - (returnS $ app "h$throwJSException" [ValExpr $ JStr "Array out of bounds"]) + (returnS $ app "h$exitProcess" [Int 134]) -- e|0 (32 bit signed integer truncation) required because of JS numbers. e|0 -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b82f6e7b7a7acee4bce84a728a5ae8cd539b04ec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b82f6e7b7a7acee4bce84a728a5ae8cd539b04ec You're receiving 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 Oct 10 11:44:14 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 10 Oct 2022 07:44:14 -0400 Subject: [Git][ghc/ghc][wip/javascript-backend] 756 commits: hadrian: Ensure that --extra-lib-dirs are used Message-ID: <6344058ed347b_1eea6a6375ad88794358@gitlab.mail> Sylvain Henry pushed to branch wip/javascript-backend at Glasgow Haskell Compiler / GHC Commits: 0950e2c4 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Ensure that --extra-lib-dirs are used Previously we only took `extraLibDirs` and friends from the package description, ignoring any contribution from the `LocalBuildInfo`. Fix this. Fixes #20566. - - - - - 53cc93ae by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Drop redundant include directories The package-specific include directories in Settings.Builders.Common.cIncludeDirs are now redundant since they now come from Cabal. Closes #20566. - - - - - b2721819 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Clean up handling of libffi dependencies - - - - - 18e5103f by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: More robust library way detection Previously `test.mk` would try to determine whether the dynamic, profiling, and vanilla library ways are available by searching for `PrimOpWrappers.{,dyn_,p_}hi` in directory reported by `ghc-pkg field ghc-prim library-dirs`. However, this is extremely fragile as there is no guarantee that there is only one library directory. To handle the case of multiple `library-dirs` correct we would have to carry out the delicate task of tokenising the directory list (in shell, no less). Since this isn't a task that I am eager to solve, I have rather moved the detection logic into the testsuite driver and instead perform a test compilation in each of the ways. This should be more robust than the previous approach. I stumbled upon this while fixing #20579. - - - - - 6c7a4913 by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: Cabalify ghc-config To ensure that the build benefits from Hadrian's usual logic for building packages, avoiding #21409. Closes #21409. - - - - - 9af091f7 by Ben Gamari at 2022-04-25T10:18:53-04:00 rts: Factor out built-in GC roots - - - - - e7c4719d by Ben Gamari at 2022-04-25T10:18:54-04:00 Ensure that wired-in exception closures aren't GC'd As described in Note [Wired-in exceptions are not CAFfy], a small set of built-in exception closures get special treatment in the code generator, being declared as non-CAFfy despite potentially containing CAF references. The original intent of this treatment for the RTS to then add StablePtrs for each of the closures, ensuring that they are not GC'd. However, this logic was not applied consistently and eventually removed entirely in 951c1fb0. This lead to #21141. Here we fix this bug by reintroducing the StablePtrs and document the status quo. Closes #21141. - - - - - 9587726f by Ben Gamari at 2022-04-25T10:18:54-04:00 testsuite: Add testcase for #21141 - - - - - cb71226f by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop dead code in GHC.Linker.Static.linkBinary' Previously we supported building statically-linked executables using libtool. However, this was dropped in 91262e75dd1d80f8f28a3922934ec7e59290e28c in favor of using ar/ranlib directly. Consequently we can drop this logic. Fixes #18826. - - - - - 9420d26b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop libtool path from settings file GHC no longers uses libtool for linking and therefore this is no longer necessary. - - - - - 41cf758b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop remaining vestiges of libtool Drop libtool logic from gen-dll, allowing us to drop the remaining logic from the `configure` script. Strangely, this appears to reliably reduce compiler allocations of T16875 on Windows. Closes #18826. Metric Decrease: T16875 - - - - - e09afbf2 by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - e76705cf by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Improve documentation of closure types Also drops the unused TREC_COMMITTED transaction state. - - - - - f2c08124 by Bodigrim at 2022-04-25T10:20:44-04:00 Document behaviour of RULES with KnownNat - - - - - 360dc2bc by Li-yao Xia at 2022-04-25T19:13:06+00:00 Fix rendering of liftA haddock - - - - - 16df6058 by Ben Gamari at 2022-04-27T10:02:25-04:00 testsuite: Report minimum and maximum stat changes As suggested in #20733. - - - - - e39cab62 by Fabian Thorand at 2022-04-27T10:03:03-04:00 Defer freeing of mega block groups Solves the quadratic worst case performance of freeing megablocks that was described in issue #19897. During GC runs, we now keep a secondary free list for megablocks that is neither sorted, nor coalesced. That way, free becomes an O(1) operation at the expense of not being able to reuse memory for larger allocations. At the end of a GC run, the secondary free list is sorted and then merged into the actual free list in a single pass. That way, our worst case performance is O(n log(n)) rather than O(n^2). We postulate that temporarily losing coalescense during a single GC run won't have any adverse effects in practice because: - We would need to release enough memory during the GC, and then after that (but within the same GC run) allocate a megablock group of more than one megablock. This seems unlikely, as large objects are not copied during GC, and so we shouldn't need such large allocations during a GC run. - Allocations of megablock groups of more than one megablock are rare. They only happen when a single heap object is large enough to require that amount of space. Any allocation areas that are supposed to hold more than one heap object cannot use megablock groups, because only the first megablock of a megablock group has valid `bdescr`s. Thus, heap object can only start in the first megablock of a group, not in later ones. - - - - - 5de6be0c by Fabian Thorand at 2022-04-27T10:03:03-04:00 Add note about inefficiency in returnMemoryToOS - - - - - 8bef471a by sheaf at 2022-04-27T10:03:43-04:00 Ensure that Any is Boxed in FFI imports/exports We should only accept the type `Any` in foreign import/export declarations when it has type `Type` or `UnliftedType`. This patch adds a kind check, and a special error message triggered by occurrences of `Any` in foreign import/export declarations at other kinds. Fixes #21305 - - - - - ba3d4e1c by Ben Gamari at 2022-04-27T10:04:19-04:00 Basic response file support Here we introduce support into our command-line parsing infrastructure and driver for handling gnu-style response file arguments, typically used to work around platform command-line length limitations. Fixes #16476. - - - - - 3b6061be by Ben Gamari at 2022-04-27T10:04:19-04:00 testsuite: Add test for #16476 - - - - - 75bf1337 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix cabal-reinstall job It's quite nice we can do this by mostly deleting code Fixes #21373 - - - - - 2c00d904 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add test to check that release jobs have profiled libs - - - - - 50d78d3b by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Explicitly handle failures in test_hadrian We also disable the stage1 testing which is broken. Related to #21072 - - - - - 2dcdf091 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix shell command - - - - - 55c84123 by Matthew Pickering at 2022-04-27T10:04:55-04:00 bootstrap: Add bootstrapping files for ghc-9_2_2 Fixes #21373 - - - - - c7ee0be6 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add linting job which checks authors are not GHC CI - - - - - 23aad124 by Adam Sandberg Ericsson at 2022-04-27T10:05:31-04:00 rts: state explicitly what evacuate and scavange mean in the copying gc - - - - - 318e0005 by Ben Gamari at 2022-04-27T10:06:07-04:00 rts/eventlog: Don't attempt to flush if there is no writer If the user has not configured a writer then there is nothing to flush. - - - - - ee11d043 by Ben Gamari at 2022-04-27T10:06:07-04:00 Enable eventlog support in all ways by default Here we deprecate the eventlogging RTS ways and instead enable eventlog support in the remaining ways. This simplifies packaging and reduces GHC compilation times (as we can eliminate two whole compilations of the RTS) while simplifying the end-user story. The trade-off is a small increase in binary sizes in the case that the user does not want eventlogging support, but we think that this is a fine trade-off. This also revealed a latent RTS bug: some files which included `Cmm.h` also assumed that it defined various macros which were in fact defined by `Config.h`, which `Cmm.h` did not include. Fixing this in turn revealed that `StgMiscClosures.cmm` failed to import various spinlock statistics counters, as evidenced by the failed unregisterised build. Closes #18948. - - - - - a2e5ab70 by Andreas Klebinger at 2022-04-27T10:06:43-04:00 Change `-dsuppress-ticks` to only suppress non-code ticks. This means cost centres and coverage ticks will still be present in output. Makes using -dsuppress-all more convenient when looking at profiled builds. - - - - - ec9d7e04 by Ben Gamari at 2022-04-27T10:07:21-04:00 Bump text submodule. This should fix #21352 - - - - - c3105be4 by Bodigrim at 2022-04-27T10:08:01-04:00 Documentation for setLocaleEncoding - - - - - 7f618fd3 by sheaf at 2022-04-27T10:08:40-04:00 Update docs for change to type-checking plugins There was no mention of the changes to type-checking plugins in the 9.4.1 notes, and the extending_ghc documentation contained a reference to an outdated type. - - - - - 4419dd3a by Adam Sandberg Ericsson at 2022-04-27T10:09:18-04:00 rts: add some more documentation to StgWeak closure type - - - - - 5a7f0dee by Matthew Pickering at 2022-04-27T10:09:54-04:00 Give Cmm files fake ModuleNames which include full filepath This fixes the initialisation functions when using -prof or -finfo-table-map. Fixes #21370 - - - - - 81cf52bb by sheaf at 2022-04-27T10:10:33-04:00 Mark GHC.Prim.PtrEq as Unsafe This module exports unsafe pointer equality operations, so we accordingly mark it as Unsafe. Fixes #21433 - - - - - f6a8185d by Ben Gamari at 2022-04-28T09:10:31+00:00 testsuite: Add performance test for #14766 This distills the essence of the Sigs.hs program found in the ticket. - - - - - c7a3dc29 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Add Monoid instance to Way - - - - - 654bafea by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Enrich flavours to build profiled/debugged/threaded ghcs per stage - - - - - 4ad559c8 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: add debug_ghc and debug_stage1_ghc flavour transformers - - - - - f9728fdb by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Don't pass -rtsopts when building libraries - - - - - 769279e6 by Matthew Pickering at 2022-04-28T18:54:44-04:00 testsuite: Fix calculation about whether to pass -dynamic to compiler - - - - - da8ae7f2 by Ben Gamari at 2022-04-28T18:55:20-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 61305184 by Ben Gamari at 2022-04-28T18:55:56-04:00 Bump process submodule - - - - - a8c99391 by sheaf at 2022-04-28T18:56:37-04:00 Fix unification of ConcreteTvs, removing IsRefl# This patch fixes the unification of concrete type variables. The subtlety was that unifying concrete metavariables is more subtle than other metavariables, as decomposition is possible. See the Note [Unifying concrete metavariables], which explains how we unify a concrete type variable with a type 'ty' by concretising 'ty', using the function 'GHC.Tc.Utils.Concrete.concretise'. This can be used to perform an eager syntactic check for concreteness, allowing us to remove the IsRefl# special predicate. Instead of emitting two constraints `rr ~# concrete_tv` and `IsRefl# rr concrete_tv`, we instead concretise 'rr'. If this succeeds we can fill 'concrete_tv', and otherwise we directly emit an error message to the typechecker environment instead of deferring. We still need the error message to be passed on (instead of directly thrown), as we might benefit from further unification in which case we will need to zonk the stored types. To achieve this, we change the 'wc_holes' field of 'WantedConstraints' to 'wc_errors', which stores general delayed errors. For the moement, a delayed error is either a hole, or a syntactic equality error. hasFixedRuntimeRep_MustBeRefl is now hasFixedRuntimeRep_syntactic, and hasFixedRuntimeRep has been refactored to directly return the most useful coercion for PHASE 2 of FixedRuntimeRep. This patch also adds a field ir_frr to the InferResult datatype, holding a value of type Maybe FRROrigin. When this value is not Nothing, this means that we must fill the ir_ref field with a type which has a fixed RuntimeRep. When it comes time to fill such an ExpType, we ensure that the type has a fixed RuntimeRep by performing a representation-polymorphism check with the given FRROrigin This is similar to what we already do to ensure we fill an Infer ExpType with a type of the correct TcLevel. This allows us to properly perform representation-polymorphism checks on 'Infer' 'ExpTypes'. The fillInferResult function had to be moved to GHC.Tc.Utils.Unify to avoid a cyclic import now that it calls hasFixedRuntimeRep. This patch also changes the code in matchExpectedFunTys to make use of the coercions, which is now possible thanks to the previous change. This implements PHASE 2 of FixedRuntimeRep in some situations. For example, the test cases T13105 and T17536b are now both accepted. Fixes #21239 and #21325 ------------------------- Metric Decrease: T18223 T5631 ------------------------- - - - - - 43bd897d by Simon Peyton Jones at 2022-04-28T18:57:13-04:00 Add INLINE pragmas for Enum helper methods As #21343 showed, we need to be super-certain that the "helper methods" for Enum instances are actually inlined or specialised. I also tripped over this when I discovered that numericEnumFromTo and friends had no pragmas at all, so their performance was very fragile. If they weren't inlined, all bets were off. So I've added INLINE pragmas for them too. See new Note [Inline Enum method helpers] in GHC.Enum. I also expanded Note [Checking for INLINE loop breakers] in GHC.Core.Lint to explain why an INLINE function might temporarily be a loop breaker -- this was the initial bug report in #21343. Strangely we get a 16% runtime allocation decrease in perf/should_run/T15185, but only on i386. Since it moves in the right direction I'm disinclined to investigate, so I'll accept it. Metric Decrease: T15185 - - - - - ca1434e3 by Ben Gamari at 2022-04-28T18:57:49-04:00 configure: Bump GHC version to 9.5 Bumps haddock submodule. - - - - - 292e3971 by Teo Camarasu at 2022-04-28T18:58:28-04:00 add since annotation for GHC.Stack.CCS.whereFrom - - - - - 905206d6 by Tamar Christina at 2022-04-28T22:19:34-04:00 winio: add support to iserv. - - - - - d182897e by Tamar Christina at 2022-04-28T22:19:34-04:00 Remove unused line - - - - - 22cf4698 by Matthew Pickering at 2022-04-28T22:20:10-04:00 Revert "rts: Refactor handling of dead threads' stacks" This reverts commit e09afbf2a998beea7783e3de5dce5dd3c6ff23db. - - - - - 8ed57135 by Matthew Pickering at 2022-04-29T04:11:29-04:00 Provide efficient unionMG function for combining two module graphs. This function is used by API clients (hls). This supercedes !6922 - - - - - 0235ff02 by Ben Gamari at 2022-04-29T04:12:05-04:00 Bump bytestring submodule Update to current `master`. - - - - - 01988418 by Matthew Pickering at 2022-04-29T04:12:05-04:00 testsuite: Normalise package versions in UnusedPackages test - - - - - 724d0dc0 by Matthew Pickering at 2022-04-29T08:59:42+00:00 testsuite: Deduplicate ways correctly This was leading to a bug where we would run a profasm test twice which led to invalid junit.xml which meant the test results database was not being populated for the fedora33-perf job. - - - - - 5630dde6 by Ben Gamari at 2022-04-29T13:06:20-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - 0cdef807 by parsonsmatt at 2022-04-30T16:51:12-04:00 Add a note about instance visibility across component boundaries In principle, the *visible* instances are * all instances defined in a prior top-level declaration group (see docs on `newDeclarationGroup`), or * all instances defined in any module transitively imported by the module being compiled However, actually searching all modules transitively below the one being compiled is unreasonably expensive, so `reifyInstances` will report only the instance for modules that GHC has had some cause to visit during this compilation. This is a shortcoming: `reifyInstances` might fail to report instances for a type that is otherwise unusued, or instances defined in a different component. You can work around this shortcoming by explicitly importing the modules whose instances you want to be visible. GHC issue #20529 has some discussion around this. Fixes #20529 - - - - - e2dd884a by Ryan Scott at 2022-04-30T16:51:47-04:00 Make mkFunCo take AnonArgFlags into account Previously, whenever `mkFunCo` would produce reflexive coercions, it would use `mkVisFunTy` to produce the kind of the coercion. However, `mkFunCo` is also used to produce coercions between types of the form `ty1 => ty2` in certain places. This has the unfortunate side effect of causing the type of the coercion to appear as `ty1 -> ty2` in certain error messages, as spotted in #21328. This patch address this by changing replacing the use of `mkVisFunTy` with `mkFunctionType` in `mkFunCo`. `mkFunctionType` checks the kind of `ty1` and makes the function arrow `=>` instead of `->` if `ty1` has kind `Constraint`, so this should always produce the correct `AnonArgFlag`. As a result, this patch fixes part (2) of #21328. This is not the only possible way to fix #21328, as the discussion on that issue lists some possible alternatives. Ultimately, it was concluded that the alternatives would be difficult to maintain, and since we already use `mkFunctionType` in `coercionLKind` and `coercionRKind`, using `mkFunctionType` in `mkFunCo` is consistent with this choice. Moreover, using `mkFunctionType` does not regress the performance of any test case we have in GHC's test suite. - - - - - 170da54f by Ben Gamari at 2022-04-30T16:52:27-04:00 Convert More Diagnostics (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors. - - - - - 39edc7b4 by Marius Ghita at 2022-04-30T16:53:06-04:00 Update user guide example rewrite rules formatting Change the rewrite rule examples to include a space between the composition of `f` and `g` in the map rewrite rule examples. Without this change, if the user has locally enabled the extension OverloadedRecordDot the copied example will result in a compile time error that `g` is not a field of `f`. ``` • Could not deduce (GHC.Records.HasField "g" (a -> b) (a1 -> b)) arising from selecting the field ‘g’ ``` - - - - - 2e951e48 by Adam Sandberg Ericsson at 2022-04-30T16:53:42-04:00 ghc-boot: export typesynonyms from GHC.Utils.Encoding This makes the Haddocks easier to understand. - - - - - d8cbc77e by Adam Sandberg Ericsson at 2022-04-30T16:54:18-04:00 users guide: add categories to some flags - - - - - d0f14fad by Chris Martin at 2022-04-30T16:54:57-04:00 hacking guide: mention the core libraries committee - - - - - 34b28200 by Matthew Pickering at 2022-04-30T16:55:32-04:00 Revert "Make the specialiser handle polymorphic specialisation" This reverts commit ef0135934fe32da5b5bb730dbce74262e23e72e8. See ticket #21229 ------------------------- Metric Decrease: T15164 Metric Increase: T13056 ------------------------- - - - - - ee891c1e by Matthew Pickering at 2022-04-30T16:55:32-04:00 Add test for T21229 - - - - - ab677cc8 by Matthew Pickering at 2022-04-30T16:56:08-04:00 Hadrian: Update README about the flavour/testsuite contract There have been a number of tickets about non-tested flavours not passing the testsuite.. this is expected and now noted in the documentation. You use other flavours to run the testsuite at your own risk. Fixes #21418 - - - - - b57b5b92 by Ben Gamari at 2022-04-30T16:56:44-04:00 rts/m32: Fix assertion failure This fixes an assertion failure in the m32 allocator due to the imprecisely specified preconditions of `m32_allocator_push_filled_list`. Specifically, the caller must ensure that the page type is set to filled prior to calling `m32_allocator_push_filled_list`. While this issue did result in an assertion failure in the debug RTS, the issue is in fact benign. - - - - - a7053a6c by sheaf at 2022-04-30T16:57:23-04:00 Testsuite driver: don't crash on empty metrics The testsuite driver crashed when trying to display minimum/maximum performance changes when there are no metrics (i.e. there is no baseline available). This patch fixes that. - - - - - 636f7c62 by Andreas Klebinger at 2022-05-01T22:21:17-04:00 StgLint: Check that functions are applied to compatible runtime reps We use compatibleRep to compare reps, and avoid checking functions with levity polymorphic types because of #21399. - - - - - 60071076 by Hécate Moonlight at 2022-05-01T22:21:55-04:00 Add documentation to the ByteArray# primetype. close #21417 - - - - - 2b2e3020 by Andreas Klebinger at 2022-05-01T22:22:31-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. - - - - - 4eaf0f33 by Eric Lindblad at 2022-05-01T22:23:11-04:00 typos - - - - - fc58df90 by Niklas Hambüchen at 2022-05-02T08:59:27+00:00 libraries/base: docs: Explain relationshipt between `finalizeForeignPtr` and `*Conc*` creation Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/21420 - - - - - 3e400f20 by Krzysztof Gogolewski at 2022-05-02T18:29:23-04:00 Remove obsolete code in CoreToStg Note [Nullary unboxed tuple] was removed in e9e61f18a548b70693f4. This codepath is tested by T15696_3. - - - - - 4a780928 by Krzysztof Gogolewski at 2022-05-02T18:29:24-04:00 Fix several note references - - - - - 15ffe2b0 by Sebastian Graf at 2022-05-03T20:11:51+02:00 Assume at least one evaluation for nested SubDemands (#21081, #21133) See the new `Note [SubDemand denotes at least one evaluation]`. A demand `n :* sd` on a let binder `x=e` now means > "`x` was evaluated `n` times and in any program trace it is evaluated, `e` is > evaluated deeply in sub-demand `sd`." The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081) ```hs f :: (Bool, Bool) -> (Bool, Bool) f pr = (case pr of (a,b) -> a /= b, True) -- before: <MP(L,L)> -- after: <MP(SL,SL)> g :: Int -> (Bool, Bool) g x = let y = let z = odd x in (z,z) in f y ``` The change in demand signature "before" to "after" allows us to case-bind `z` here. Similarly good things happen for the `sd` in call sub-demands `Cn(sd)`, which allows for more eta-reduction (which is only sound with `-fno-pedantic-bottoms`, albeit). We also fix #21085, a surprising inconsistency with `Poly` to `Call` sub-demand expansion. In an attempt to fix a regression caused by less inlining due to eta-reduction in T15426, I eta-expanded the definition of `elemIndex` and `elemIndices`, thus fixing #21345 on the go. The main point of this patch is that it fixes #21081 and #21133. Annoyingly, I discovered that more precise demand signatures for join points can transform a program into a lazier program if that join point gets floated to the top-level, see #21392. There is no simple fix at the moment, but !5349 might. Thus, we accept a ~5% regression in `MultiLayerModulesTH_OneShot`, where #21392 bites us in `addListToUniqDSet`. T21392 reliably reproduces the issue. Surprisingly, ghc/alloc perf on Windows improves much more than on other jobs, by 0.4% in the geometric mean and by 2% in T16875. Metric Increase: MultiLayerModulesTH_OneShot Metric Decrease: T16875 - - - - - 948c7e40 by Andreas Klebinger at 2022-05-04T09:57:34-04:00 CoreLint - When checking for levity polymorphism look through more ticks. For expressions like `(scc<cc_name> primOp#) arg1` we should also look at arg1 to determine if we call primOp# at a fixed runtime rep. This is what corePrep already does but CoreLint didn't yet. This patch will bring them in sync in this regard. It also uses tickishFloatable in CorePrep instead of CorePrep having it's own slightly differing definition of when a tick is floatable. - - - - - 85bc73bd by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Support Unicode properly - - - - - 063d485e by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Replace LaTeX documentation syntax with Haddock The LaTeX documentation generator does not seem to have been used for quite some time, so the LaTeX-to-Haddock preprocessing step has become a pointless complication that makes documenting the contents of GHC.Prim needlessly difficult. This commit replaces the LaTeX syntax with the Haddock it would have been converted into, anyway, though with an additional distinction: it uses single quotes in places to instruct Haddock to generate hyperlinks to bindings. This improves the quality of the generated output. - - - - - d61f7428 by Ben Gamari at 2022-05-04T09:58:50-04:00 rts/ghc.mk: Only build StgCRunAsm.S when it is needed Previously the make build system unconditionally included StgCRunAsm.S in the link, meaning that the RTS would require an execstack unnecessarily. Fixes #21478. - - - - - 934a90dd by Simon Peyton Jones at 2022-05-04T16:15:34-04:00 Improve error reporting in generated code Our error reporting in generated code (via desugaring before typechecking) only worked when the generated code was just a simple call. This commit makes it work in nested cases. - - - - - 445d3657 by sheaf at 2022-05-04T16:16:12-04:00 Ensure Any is not levity-polymorphic in FFI The previous patch forgot to account for a type such as Any @(TYPE (BoxedRep l)) for a quantified levity variable l. - - - - - ddd2591c by Ben Gamari at 2022-05-04T16:16:48-04:00 Update supported LLVM versions Pull forward minimum version to match 9.2. (cherry picked from commit c26faa54c5fbe902ccb74e79d87e3fa705e270d1) - - - - - f9698d79 by Ben Gamari at 2022-05-04T16:16:48-04:00 testsuite/T7275: Use sed -r Darwin requires the `-r` flag to be compatible with GNU sed. (cherry picked from commit 512338c8feec96c38ef0cf799f3a01b77c967c56) - - - - - 8635323b by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Use ld.lld on ARMv7/Linux Due to #16177. Also cleanup some code style issues. (cherry picked from commit cc1c3861e2372f464bf9e3c9c4d4bd83f275a1a6) - - - - - 4f6370c7 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Always preserve artifacts, even in failed jobs (cherry picked from commit fd08b0c91ea3cab39184f1b1b1aafcd63ce6973f) - - - - - 6f662754 by Ben Gamari at 2022-05-04T16:16:48-04:00 configure: Make sphinx version check more robust It appears that the version of sphinx shipped on CentOS 7 reports a version string of `Sphinx v1...`. Accept the `v`. (cherry picked from commit a9197a292fd4b13308dc6664c01351c7239357ed) - - - - - 0032dc38 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Don't run make job in release pipelines (cherry picked from commit 16d6a8ff011f2194485387dcca1c00f8ddcdbdeb) - - - - - 27f9aab3 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab/ci: Fix name of bootstrap compiler directory Windows binary distributions built with Hadrian have a target platform suffix in the name of their root directory. Teach `ci.sh` about this fact. (cherry picked from commit df5752f39671f6d04d8cd743003469ae5eb67235) - - - - - b528f0f6 by Krzysztof Gogolewski at 2022-05-05T09:05:43-04:00 Fix several note references, part 2 - - - - - 691aacf6 by Adam Sandberg Ericsson at 2022-05-05T09:06:19-04:00 adjustors: align comment about number of integer like arguments with implementation for Amd4+MinGW implementation - - - - - f050557e by Simon Jakobi at 2022-05-05T12:47:32-04:00 Remove two uses of IntMap.size IntMap.size is O(n). The new code should be slightly more efficient. The transformation of GHC.CmmToAsm.CFG.calcFreqs.nodeCount can be described formally as the transformation: (\sum_{0}^{n-1} \sum_{0}^{k-1} i_nk) + n ==> (\sum_{0}^{n-1} 1 + \sum_{0}^{k-1} i_nk) - - - - - 7da90ae3 by Tom Ellis at 2022-05-05T12:48:09-04:00 Explain that 'fail s' should run in the monad itself - - - - - 610d0283 by Matthew Craven at 2022-05-05T12:48:47-04:00 Add a test for the bracketing in rules for (^) - - - - - 016f9ca6 by Matthew Craven at 2022-05-05T12:48:47-04:00 Fix broken rules for (^) with known small powers - - - - - 9372aaab by Matthew Craven at 2022-05-05T12:48:47-04:00 Give the two T19569 tests different names - - - - - 61901b32 by Andreas Klebinger at 2022-05-05T12:49:23-04:00 SpecConstr: Properly create rules for call patterns representing partial applications The main fix is that in addVoidWorkerArg we now add the argument to the front. This fixes #21448. ------------------------- Metric Decrease: T16875 ------------------------- - - - - - 71278dc7 by Teo Camarasu at 2022-05-05T12:50:03-04:00 add since annotations for instances of ByteArray - - - - - 962ff90b by sheaf at 2022-05-05T12:50:42-04:00 Start 9.6.1-notes Updates the documentation notes to start tracking changes for the 9.6.1 release (instead of 9.4). - - - - - aacb15a3 by Matthew Pickering at 2022-05-05T20:24:01-04:00 ci: Add job to check that jobs.yaml is up-to-date There have been quite a few situations where jobs.yaml has been out of date. It's better to add a CI job which checks that it's right. We don't want to use a staged pipeline because it obfuscates the structure of the pipeline. - - - - - be7102e5 by Ben Gamari at 2022-05-05T20:24:37-04:00 rts: Ensure that XMM registers are preserved on Win64 Previously we only preserved the bottom 64-bits of the callee-saved 128-bit XMM registers, in violation of the Win64 calling convention. Fix this. Fixes #21465. - - - - - 73b22ff1 by Ben Gamari at 2022-05-05T20:24:37-04:00 testsuite: Add test for #21465 - - - - - e2ae9518 by Ziyang Liu at 2022-05-06T19:22:22-04:00 Allow `let` just before pure/return in ApplicativeDo The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case. - - - - - 0415449a by Matthew Pickering at 2022-05-06T19:22:58-04:00 template-haskell: Fix representation of OPAQUE pragmas There is a mis-match between the TH representation of OPAQUE pragmas and GHC's internal representation due to how OPAQUE pragmas disallow phase annotations. It seemed most in keeping to just fix the wired in name issue by adding a special case to the desugaring of INLINE pragmas rather than making TH/GHC agree with how the representation should look. Fixes #21463 - - - - - 4de887e2 by Simon Peyton Jones at 2022-05-06T19:23:34-04:00 Comments only: Note [AppCtxt] - - - - - 6e69964d by Matthew Pickering at 2022-05-06T19:24:10-04:00 Fix name of windows release bindist in doc-tarball job - - - - - ced4689e by Matthew Pickering at 2022-05-06T19:24:46-04:00 ci: Generate source-tarball in release jobs We need to distribute the source tarball so we should generate it in the CI pipeline. - - - - - 3c91de21 by Rob at 2022-05-08T13:40:53+02:00 Change Specialise to use OrdList. Fixes #21362 Metric Decrease: T16875 - - - - - 67072c31 by Simon Jakobi at 2022-05-08T12:23:43-04:00 Tweak GHC.CmmToAsm.CFG.delEdge mapAdjust is more efficient than mapAlter. - - - - - 374554bb by Teo Camarasu at 2022-05-09T16:24:37-04:00 Respect -po when heap profiling (#21446) - - - - - 1ea414b6 by Teo Camarasu at 2022-05-09T16:24:37-04:00 add test case for #21446 - - - - - c7902078 by Jens Petersen at 2022-05-09T16:25:17-04:00 avoid hadrian/bindist/Makefile install_docs error when --docs=none When docs are disabled the bindist does not have docs/ and hence docs-utils/ is not generated. Here we just test that docs-utils exists before attempting to install prologue.txt and gen_contents_index to avoid the error: /usr/bin/install: cannot stat 'docs-utils/prologue.txt': No such file or directory make: *** [Makefile:195: install_docs] Error 1 - - - - - 158bd659 by Hécate Moonlight at 2022-05-09T16:25:56-04:00 Correct base's changelog for 4.16.1.0 This commit reaffects the new Ix instances of the foreign integral types from base 4.17 to 4.16.1.0 closes #21529 - - - - - a4fbb589 by Sylvain Henry at 2022-05-09T16:26:36-04:00 STG: only print cost-center if asked to - - - - - 50347ded by Gergo ERDI at 2022-05-10T11:43:33+00:00 Improve "Glomming" note Add a paragraph that clarifies that `occurAnalysePgm` finding out-of-order references, and thus needing to glom, is not a cause for concern when its root cause is rewrite rules. - - - - - df2e3373 by Eric Lindblad at 2022-05-10T20:45:41-04:00 update INSTALL - - - - - dcac3833 by Matthew Pickering at 2022-05-10T20:46:16-04:00 driver: Make -no-keep-o-files -no-keep-hi-files work in --make mode It seems like it was just an oversight to use the incorrect DynFlags (global rather than local) when implementing these two options. Using the local flags allows users to request these intermediate files get cleaned up, which works fine in --make mode because 1. Interface files are stored in memory 2. Object files are only cleaned at the end of session (after link) Fixes #21349 - - - - - 35da81f8 by Ben Gamari at 2022-05-10T20:46:52-04:00 configure: Check for ffi.h As noted in #21485, we checked for ffi.h yet then failed to throw an error if it is missing. Fixes #21485. - - - - - bdc99cc2 by Simon Peyton Jones at 2022-05-10T20:47:28-04:00 Check for uninferrable variables in tcInferPatSynDecl This fixes #21479 See Note [Unquantified tyvars in a pattern synonym] While doing this, I found that some error messages pointed at the pattern synonym /name/, rather than the /declaration/ so I widened the SrcSpan to encompass the declaration. - - - - - 142a73d9 by Matthew Pickering at 2022-05-10T20:48:04-04:00 hadrian: Fix split-sections transformer The splitSections transformer has been broken since -dynamic-too support was implemented in hadrian. This is because we actually build the dynamic way when building the dynamic way, so the predicate would always fail. The fix is to just always pass `split-sections` even if it doesn't do anything for a particular way. Fixes #21138 - - - - - 699f5935 by Matthew Pickering at 2022-05-10T20:48:04-04:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. Closes #21135 - - - - - 21feece2 by Simon Peyton Jones at 2022-05-10T20:48:39-04:00 Use the wrapper for an unlifted binding We assumed the wrapper for an unlifted binding is the identity, but as #21516 showed, that is no always true. Solution is simple: use it. - - - - - 68d1ea5f by Matthew Pickering at 2022-05-10T20:49:15-04:00 docs: Fix path to GHC API docs in index.html In the make bindists we generate documentation in docs/ghc-<VER> but the hadrian bindists generate docs/ghc/ so the path to the GHC API docs was wrong in the index.html file. Rather than make the hadrian and make bindists the same it was easier to assume that if you're using the mkDocs script that you're using hadrian bindists. Fixes #21509 - - - - - 9d8f44a9 by Matthew Pickering at 2022-05-10T20:49:51-04:00 hadrian: Don't pass -j to haddock This has high potential for oversubcribing as many haddock jobs can be spawned in parralel which will each request the given number of capabilities. Once -jsem is implemented (#19416, !5176) we can expose that haddock via haddock and use that to pass a semaphore. Ticket #21136 - - - - - fec3e7aa by Matthew Pickering at 2022-05-10T20:50:27-04:00 hadrian: Only copy and install libffi headers when using in-tree libffi When passed `--use-system-libffi` then we shouldn't copy and install the headers from the system package. Instead the headers are expected to be available as a runtime dependency on the users system. Fixes #21485 #21487 - - - - - 5b791ed3 by mikael at 2022-05-11T08:22:13-04:00 FIND_LLVM_PROG: Recognize llvm suffix used by FreeBSD, ie llc10. - - - - - 8500206e by ARATA Mizuki at 2022-05-11T08:22:57-04:00 Make floating-point abs IEEE 754 compliant The old code used by via-C backend didn't handle the sign bit of NaN. See #21043. - - - - - 4a4c77ed by Alan Zimmerman at 2022-05-11T08:23:33-04:00 EPA: do statement with leading semicolon has wrong anchor The code do; a <- doAsync; b Generated an incorrect Anchor for the statement list that starts after the first semicolon. This commit fixes it. Closes #20256 - - - - - e3ca8dac by Simon Peyton Jones at 2022-05-11T08:24:08-04:00 Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. - - - - - fcc7dc4c by Ben Gamari at 2022-05-11T20:05:41-04:00 gitlab-ci: Check for dynamic msys2 dependencies Both #20878 and #21196 were caused by unwanted dynamic dependencies being introduced by boot libraries. Ensure that we catch this in CI by attempting to run GHC in an environment with a minimal PATH. - - - - - 3c998f0d by Matthew Pickering at 2022-05-11T20:06:16-04:00 Add back Debian9 CI jobs We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19 not being at EOL until April 2023 and they still need tinfo5. Fixes #21469 - - - - - dea9a3d9 by Ben Gamari at 2022-05-11T20:06:51-04:00 rts: Drop setExecutable Since f6e366c058b136f0789a42222b8189510a3693d1 setExecutable has been dead code. Drop it. - - - - - 32cdf62d by Simon Peyton Jones at 2022-05-11T20:07:27-04:00 Add a missing guard in GHC.HsToCore.Utils.is_flat_prod_pat This missing guard gave rise to #21519. - - - - - 2c00a8d0 by Matthew Pickering at 2022-05-11T20:08:02-04:00 Add mention of -hi to RTS --help Fixes #21546 - - - - - a2dcad4e by Andre Marianiello at 2022-05-12T02:15:48+00:00 Decouple dynflags in Cmm parser (related to #17957) - - - - - 3a022baa by Andre Marianiello at 2022-05-12T02:15:48+00:00 Remove Module argument from initCmmParserConfig - - - - - 2fc8d76b by Andre Marianiello at 2022-05-12T02:15:48+00:00 Move CmmParserConfig and PDConfig into GHC.Cmm.Parser.Config - - - - - b8c5ffab by Andre Marianiello at 2022-05-12T18:13:55-04:00 Decouple dynflags in GHC.Core.Opt.Arity (related to #17957) Metric Decrease: T16875 - - - - - 3bf938b6 by sheaf at 2022-05-12T18:14:34-04:00 Update extending_ghc for TcPlugin changes The documentation still mentioned Derived constraints and an outdated datatype TcPluginResult. - - - - - 668a9ef4 by jackohughes at 2022-05-13T12:10:34-04:00 Fix printing of brackets in multiplicities (#20315) Change mulArrow to allow for printing of correct application precedence where necessary and update callers of mulArrow to reflect this. As part of this, move mulArrow from GHC/Utils/Outputtable to GHC/Iface/Type. Fixes #20315 - - - - - 30b8b7f1 by Ben Gamari at 2022-05-13T12:11:09-04:00 rts: Add debug output on ocResolve failure This makes it easier to see how resolution failures nest. - - - - - 53b3fa1c by Ben Gamari at 2022-05-13T12:11:09-04:00 rts/PEi386: Fix handling of weak symbols Previously we would flag the symbol as weak but failed to set its address, which must be computed from an "auxiliary" symbol entry the follows the weak symbol. Fixes #21556. - - - - - 5678f017 by Ben Gamari at 2022-05-13T12:11:09-04:00 testsuite: Add tests for #21556 - - - - - 49af0e52 by Ben Gamari at 2022-05-13T22:23:26-04:00 Re-export augment and build from GHC.List Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/19127 - - - - - aed356e1 by Simon Peyton Jones at 2022-05-13T22:24:02-04:00 Comments only around HsWrapper - - - - - 27b90409 by Ben Gamari at 2022-05-16T08:30:44-04:00 hadrian: Introduce linting flavour transformer (+lint) The linting flavour enables -dlint uniformly across anything build by the stage1 compiler. -dcmm-lint is not currently enabled because it fails on i386 (see #21563) - - - - - 3f316776 by Matthew Pickering at 2022-05-16T08:30:44-04:00 hadrian: Uniformly enable -dlint with enableLinting transformer This fixes some bugs where * -dcore-lint was being passed when building stage1 libraries with the boot compiler * -dcore-lint was not being passed when building executables. Fixes #20135 - - - - - 3d74cfca by Andreas Klebinger at 2022-05-16T08:31:20-04:00 Make closure macros EXTERN_INLINE to make debugging easier Implements #21424. The RTS macros get_itbl and friends are extremely helpful during debugging. However only a select few of those were available in the compiled RTS as actual symbols as the rest were INLINE macros. This commit marks all of them as EXTERN_INLINE. This will still inline them at use sites but allow us to use their compiled counterparts during debugging. This allows us to use things like `p get_fun_itbl(ptr)` in the gdb shell since `get_fun_itbl` will now be available as symbol! - - - - - 93153aab by Matthew Pickering at 2022-05-16T08:31:55-04:00 packaging: Introduce CI job for generating hackage documentation This adds a CI job (hackage-doc-tarball) which generates the necessary tarballs for uploading libraries and documentation to hackage. The release script knows to download this folder and the upload script will also upload the release to hackage as part of the release. The `ghc_upload_libs` script is moved from ghc-utils into .gitlab/ghc_upload_libs There are two modes, preparation and upload. * The `prepare` mode takes a link to a bindist and creates a folder containing the source and doc tarballs ready to upload to hackage. * The `upload` mode takes the folder created by prepare and performs the upload to hackage. Fixes #21493 Related to #21512 - - - - - 65d31d05 by Simon Peyton Jones at 2022-05-16T15:32:50-04:00 Add arity to the INLINE pragmas for pattern synonyms The lack of INLNE arity was exposed by #21531. The fix is simple enough, if a bit clumsy. - - - - - 43c018aa by Krzysztof Gogolewski at 2022-05-16T15:33:25-04:00 Misc cleanup - Remove groupWithName (unused) - Use the RuntimeRepType synonym where possible - Replace getUniqueM + mkSysLocalOrCoVar with mkSysLocalOrCoVarM No functional changes. - - - - - 8dfea078 by Pavol Vargovcik at 2022-05-16T15:34:04-04:00 TcPlugin: access to irreducible givens + fix passed ev_binds_var - - - - - fb579e15 by Ben Gamari at 2022-05-17T00:25:02-04:00 driver: Introduce pgmcxx Here we introduce proper support for compilation of C++ objects. This includes: * logic in `configure` to detect the C++ toolchain and propagating this information into the `settings` file * logic in the driver to use the C++ toolchain when compiling C++ sources - - - - - 43628ed4 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Build T20918 with HC, not CXX - - - - - 0ef249aa by Ben Gamari at 2022-05-17T00:25:02-04:00 Introduce package to capture dependency on C++ stdlib Here we introduce a new "virtual" package into the initial package database, `system-cxx-std-lib`. This gives users a convenient, platform agnostic way to link against C++ libraries, addressing #20010. Fixes #20010. - - - - - 03efe283 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Add tests for system-cxx-std-lib package Test that we can successfully link against C++ code both in GHCi and batch compilation. See #20010 - - - - - 5f6527e0 by nineonine at 2022-05-17T00:25:38-04:00 OverloadedRecordFields: mention parent name in 'ambiguous occurrence' error for better disambiguation (#17420) - - - - - eccdb208 by Simon Peyton Jones at 2022-05-17T07:16:39-04:00 Adjust flags for pprTrace We were using defaultSDocContext for pprTrace, which suppresses lots of useful infomation. This small MR adds GHC.Utils.Outputable.traceSDocContext and uses it for pprTrace and pprTraceUserWarning. traceSDocContext is a global, and hence not influenced by flags, but that seems unavoidable. But I made the sdocPprDebug bit controlled by unsafeHasPprDebug, since we have the latter for exactly this purpose. Fixes #21569 - - - - - d2284c4c by Simon Peyton Jones at 2022-05-17T07:17:15-04:00 Fix bad interaction between withDict and the Specialiser This MR fixes a bad bug, where the withDict was inlined too vigorously, which in turn made the type-class Specialiser generate a bogus specialisation, because it saw the same overloaded function applied to two /different/ dictionaries. Solution: inline `withDict` later. See (WD8) of Note [withDict] in GHC.HsToCore.Expr See #21575, which is fixed by this change. - - - - - 70f52443 by Matthew Pickering at 2022-05-17T07:17:50-04:00 Bump time submodule to 1.12.2 This bumps the time submodule to the 1.12.2 release. Fixes #21571 - - - - - 2343457d by Vladislav Zavialov at 2022-05-17T07:18:26-04:00 Remove unused test files (#21582) Those files were moved to the perf/ subtree in 11c9a469, and then accidentally reintroduced in 680ef2c8. - - - - - cb52b4ae by Ben Gamari at 2022-05-17T16:00:14-04:00 CafAnal: Improve code clarity Here we implement a few measures to improve the clarity of the CAF analysis implementation. Specifically: * Use CafInfo instead of Bool since the former is more descriptive * Rename CAFLabel to CAFfyLabel, since not all CAFfyLabels are in fact CAFs * Add numerous comments - - - - - b048a9f4 by Ben Gamari at 2022-05-17T16:00:14-04:00 codeGen: Ensure that static datacon apps are included in SRTs When generating an SRT for a recursive group, GHC.Cmm.Info.Build.oneSRT filters out recursive references, as described in Note [recursive SRTs]. However, doing so for static functions would be unsound, for the reason described in Note [Invalid optimisation: shortcutting]. However, the same argument applies to static data constructor applications, as we discovered in #20959. Fix this by ensuring that static data constructor applications are included in recursive SRTs. The approach here is not entirely satisfactory, but it is a starting point. Fixes #20959. - - - - - 0e2d16eb by Matthew Pickering at 2022-05-17T16:00:50-04:00 Add test for #21558 This is now fixed on master and 9.2 branch. Closes #21558 - - - - - ef3c8d9e by Sylvain Henry at 2022-05-17T20:22:02-04:00 Don't store LlvmConfig into DynFlags LlvmConfig contains information read from llvm-passes and llvm-targets files in GHC's top directory. Reading these files is done only when needed (i.e. when the LLVM backend is used) and cached for the whole compiler session. This patch changes the way this is done: - Split LlvmConfig into LlvmConfig and LlvmConfigCache - Store LlvmConfigCache in HscEnv instead of DynFlags: there is no good reason to store it in DynFlags. As it is fixed per session, we store it in the session state instead (HscEnv). - Initializing LlvmConfigCache required some changes to driver functions such as newHscEnv. I've used the opportunity to untangle initHscEnv from initGhcMonad (in top-level GHC module) and to move it to GHC.Driver.Main, close to newHscEnv. - I've also made `cmmPipeline` independent of HscEnv in order to remove the call to newHscEnv in regalloc_unit_tests. - - - - - 828fbd8a by Andreas Klebinger at 2022-05-17T20:22:38-04:00 Give all EXTERN_INLINE closure macros prototypes - - - - - cfc8e2e2 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Introduce [sg]etFinalizerExceptionHandler This introduces a global hook which is called when an exception is thrown during finalization. - - - - - 372cf730 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Throw exceptions raised while closing finalized Handles Fixes #21336. - - - - - 3dd2f944 by Ben Gamari at 2022-05-19T04:57:51-04:00 testsuite: Add tests for #21336 - - - - - 297156e0 by Matthew Pickering at 2022-05-19T04:58:27-04:00 Add release flavour and use it for the release jobs The release flavour is essentially the same as the perf flavour currently but also enables `-haddock`. I have hopefully updated all the relevant places where the `-perf` flavour was hardcoded. Fixes #21486 - - - - - a05b6293 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Don't build sphinx documentation on centos The centos docker image lacks the sphinx builder so we disable building sphinx docs for these jobs. Fixes #21580 - - - - - 209d7c69 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Use correct syntax when args list is empty This seems to fail on the ancient version of bash present on CentOS - - - - - 02d16334 by Matthew Pickering at 2022-05-19T04:59:03-04:00 hadrian: Don't attempt to build dynamic profiling libraries We only support building static profiling libraries, the transformer was requesting things like a dynamic, threaded, debug, profiling RTS, which we have never produced nor distributed. Fixes #21567 - - - - - 35bdab1c by Ben Gamari at 2022-05-19T04:59:39-04:00 configure: Check CC_STAGE0 for --target support We previously only checked the stage 1/2 compiler for --target support. We got away with this for quite a while but it eventually caught up with us in #21579, where `bytestring`'s new NEON implementation was unbuildable on Darwin due to Rosetta's seemingly random logic for determining which executable image to execute. This lead to a confusing failure to build `bytestring`'s cbits, when `clang` tried to compile NEON builtins while targetting x86-64. Fix this by checking CC_STAGE0 for --target support. Fixes #21579. - - - - - 0ccca94b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator analysis of `CmmGraph` This commit adds module `GHC.Cmm.Dominators`, which provides a wrapper around two existing algorithms in GHC: the Lengauer-Tarjan dominator analysis from the X86 back end and the reverse postorder ordering from the Cmm Dataflow framework. Issue #20726 proposes that we evaluate some alternatives for dominator analysis, but for the time being, the best path forward is simply to use the existing analysis on `CmmGraph`s. This commit addresses a bullet in #21200. - - - - - 54f0b578 by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator-tree function - - - - - 05ed917b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add HasDebugCallStack; remove unneeded extensions - - - - - 0b848136 by Andreas Klebinger at 2022-05-20T05:32:32-04:00 document fields of `DominatorSet` - - - - - 8a26e8d6 by Ben Gamari at 2022-05-20T05:33:08-04:00 nonmoving: Fix documentation of GC statistics fields These were previously incorrect. Fixes #21553. - - - - - c1e24e61 by Matthew Pickering at 2022-05-20T05:33:44-04:00 Remove pprTrace from pushCoercionIntoLambda (#21555) This firstly caused spurious output to be emitted (as evidenced by #21555) but even worse caused a massive coercion to be attempted to be printed (> 200k terms) which would invariably eats up all the memory of your computer. The good news is that removing this trace allows the program to compile to completion, the bad news is that the program exhibits a core lint error (on 9.0.2) but not any other releases it seems. Fixes #21577 and #21555 - - - - - a36d12ee by Zubin Duggal at 2022-05-20T10:44:35-04:00 docs: Fix LlvmVersion in manpage (#21280) - - - - - 36b8a57c by Matthew Pickering at 2022-05-20T10:45:10-04:00 validate: Use $make rather than make In the validate script we are careful to use the $make variable as this stores whether we are using gmake, make, quiet mode etc. There was just this one place where we failed to use it. Fixes #21598 - - - - - 4aa3c5bd by Norman Ramsey at 2022-05-21T03:11:04+00:00 Change `Backend` type and remove direct dependencies With this change, `Backend` becomes an abstract type (there are no more exposed value constructors). Decisions that were formerly made by asking "is the current back end equal to (or different from) this named value constructor?" are now made by interrogating the back end about its properties, which are functions exported by `GHC.Driver.Backend`. There is a description of how to migrate code using `Backend` in the user guide. Clients using the GHC API can find a backdoor to access the Backend datatype in GHC.Driver.Backend.Internal. Bumps haddock submodule. Fixes #20927 - - - - - ecf5f363 by Julian Ospald at 2022-05-21T12:51:16-04:00 Respect DESTDIR in hadrian bindist Makefile, fixes #19646 - - - - - 7edd991e by Julian Ospald at 2022-05-21T12:51:16-04:00 Test DESTDIR in test_hadrian() - - - - - ea895b94 by Matthew Pickering at 2022-05-22T21:57:47-04:00 Consider the stage of typeable evidence when checking stage restriction We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547 - - - - - ffbe28e5 by Dominik Peteler at 2022-05-22T21:58:23-04:00 Modularize GHC.Core.Opt.LiberateCase Progress towards #17957 - - - - - bc723ac2 by Simon Peyton Jones at 2022-05-23T17:09:34+01:00 Improve FloatOut and SpecConstr This patch addresses a relatively obscure situation that arose when chasing perf regressions in !7847, which itself is fixing It does two things: * SpecConstr can specialise on ($df d1 d2) dictionary arguments * FloatOut no longer checks argument strictness See Note [Specialising on dictionaries] in GHC.Core.Opt.SpecConstr. A test case is difficult to construct, but it makes a big difference in nofib/real/eff/VSM, at least when we have the patch for #21286 installed. (The latter stops worker/wrapper for dictionary arguments). There is a spectacular, but slightly illusory, improvement in runtime perf on T15426. I have documented the specifics in T15426 itself. Metric Decrease: T15426 - - - - - 1a4195b0 by John Ericson at 2022-05-23T17:33:59-04:00 Make debug a `Bool` not an `Int` in `StgToCmmConfig` We don't need any more resolution than this. Rename the field to `stgToCmmEmitDebugInfo` to indicate it is no longer conveying any "level" information. - - - - - e9fff12b by Alan Zimmerman at 2022-05-23T21:04:49-04:00 EPA : Remove duplicate comments in DataFamInstD The code data instance Method PGMigration = MigrationQuery Query -- ^ Run a query against the database | MigrationCode (Connection -> IO (Either String ())) -- ^ Run any arbitrary IO code Resulted in two instances of the "-- ^ Run a query against the database" comment appearing in the Exact Print Annotations when it was parsed. Ensure only one is kept. Closes #20239 - - - - - e2520df3 by Alan Zimmerman at 2022-05-23T21:05:27-04:00 EPA: Comment Order Reversed Make sure comments captured in the exact print annotations are in order of increasing location Closes #20718 - - - - - 4b45fd72 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Add test for T21455 - - - - - e2cd1d43 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Allow passing -po outside profiling way Resolves #21455 - - - - - 3b8c413a by Greg Steuck at 2022-05-24T10:49:52-04:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 1db877a3 by Ben Gamari at 2022-05-24T10:50:28-04:00 hadrian/bindist: Drop redundant include of install.mk `install.mk` is already included by `config.mk`. Moreover, `install.mk` depends upon `config.mk` to set `RelocatableBuild`, making this first include incorrect. - - - - - f485d267 by Greg Steuck at 2022-05-24T10:51:08-04:00 Remove -z wxneeded for OpenBSD With all the recent W^X fixes in the loader this workaround is not necessary any longer. I verified that the only tests failing for me on OpenBSD 7.1-current are the same (libc++ related) before and after this commit (with --fast). - - - - - 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Bodigrim at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergo ERDI at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Bodigrim at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 35cc5749 by Josh Meredith at 2022-10-09T15:26:01-04:00 Add ghcjs changes to deriveConstants: - change String targetOS option in deriveConstants to an enum - separate out getWantedGHSJS, removing generated c file in this path - - - - - 7d22facd by doyougnu at 2022-10-10T13:41:38+02:00 Add JavaScript code generator Adapt code generator of GHCJS to GHC head. Currently it is only enabled with the hidden -fjavascript flag. It produces .o files that can't be used yet except by GHCJS's linker. Codegen: doc Codegen: correctly return linkable object Now we can build a static library (-staticlib) Codegen: doc genLit Codegen: use assignAll Codegen: introduce TypedExpr Refactor assignAll et al, add documentation Codegen: minor changes Doc - - - - - 19 changed files: - − .appveyor.sh - .editorconfig - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - + .gitlab/upload_ghc_libs.py - HACKING.md - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - bindisttest/Makefile - − bindisttest/ghc.mk - boot - compiler/.hlint.yaml - compiler/CodeGen.Platform.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8118f3e553a6eb7c1e72ce95805112621f531fdb...7d22facdfdc6e3c7e3223ffc0ddd92a9cec76e05 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8118f3e553a6eb7c1e72ce95805112621f531fdb...7d22facdfdc6e3c7e3223ffc0ddd92a9cec76e05 You're receiving 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 Oct 10 11:49:27 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 07:49:27 -0400 Subject: [Git][ghc/ghc][wip/T21851-rule-win] 12 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <634406c7a8cc9_1eea6a5141479641e@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851-rule-win at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - d73286bb by Simon Peyton Jones at 2022-10-10T08:59:28+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Monad.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b9ad44f42207a7d4ce388c945437f5856609401...d73286bb2d9e2ac92c31eeeafbf3e44f54ba2cbf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b9ad44f42207a7d4ce388c945437f5856609401...d73286bb2d9e2ac92c31eeeafbf3e44f54ba2cbf You're receiving 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 Oct 10 12:44:39 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 08:44:39 -0400 Subject: [Git][ghc/ghc][wip/T22084] 9 commits: chore: extend `.editorconfig` for C files Message-ID: <634413b77b11a_1eea6a5fada5c08104ca@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22084 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 5b1c1381 by Simon Peyton Jones at 2022-10-10T13:44:40+01:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 0f74e329 by Simon Peyton Jones at 2022-10-10T13:46:19+01:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Tc/Instance/Class.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - libraries/base/tools/ucd2haskell/ucd.sh - rts/include/Stg.h - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - + testsuite/tests/simplCore/should_compile/T21148.hs - + testsuite/tests/simplCore/should_compile/T21148.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/T21128.hs - testsuite/tests/stranal/should_compile/T21128.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd65da060f00bd74351e6324ddf567f19e31def4...0f74e32997446f7492a4a68bb5ebb341736d0446 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd65da060f00bd74351e6324ddf567f19e31def4...0f74e32997446f7492a4a68bb5ebb341736d0446 You're receiving 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 Oct 10 13:43:11 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 10 Oct 2022 09:43:11 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 5 commits: Remove panic in getObject Message-ID: <6344216fb219f_1eea6a5fc830fc8258e8@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 7d68c183 by Sylvain Henry at 2022-10-10T13:34:30+02:00 Remove panic in getObject - - - - - 07f889f9 by Sylvain Henry at 2022-10-10T13:34:30+02:00 Add debug and Outputable instances - - - - - fb613efe by Sylvain Henry at 2022-10-10T14:30:46+02:00 Remove backup file - - - - - f8202bbb by Sylvain Henry at 2022-10-10T14:31:07+02:00 Skip overflow tests - - - - - 5b1174db by Sylvain Henry at 2022-10-10T15:46:07+02:00 Fix RTS includes for native build - - - - - 6 changed files: - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Types.hs - compiler/GHC/StgToJS/Object.hs - rts/rts.cabal.in - − rts/rts.cabal.in.orig - testsuite/tests/rts/T9579/all.T Changes: ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -218,21 +218,27 @@ computeLinkDependencies -> (ExportedFun -> Bool) -> IO (Map Module (Deps, DepsLocation), [UnitId], Set LinkableUnit, Set ExportedFun, [FilePath]) computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDeps isRootFun = do + (objDepsMap, objRequiredUnits) <- loadObjDeps objFiles let roots = S.fromList . filter isRootFun $ concatMap (M.keys . depsHaskellExported . fst) (M.elems objDepsMap) rootMods = map (moduleNameString . moduleName . head) . group . sort . map funModule . S.toList $ roots objPkgs = map moduleUnitId $ nub (M.keys objDepsMap) - when (logVerbAtLeast logger 2) $ void $ + when (logVerbAtLeast logger 2) $ void $ do compilationProgressMsg logger $ hcat [ text "Linking ", text target, text " (", text (intercalate "," rootMods), char ')' ] + compilationProgressMsg logger $ hcat + [ text "objDepsMap ", ppr objDepsMap ] + compilationProgressMsg logger $ hcat + [ text "objFiles ", ppr objFiles ] let (rts_wired_units, rts_wired_functions) = rtsDeps units -- all the units we want to link together, without their dependencies let root_units = filter (/= mainUnitId) - $ nub (rts_wired_units ++ reverse objPkgs ++ reverse units) + $ nub + $ rts_wired_units ++ reverse objPkgs ++ reverse units -- all the units we want to link together, including their dependencies, -- preload units, and backpack instantiations @@ -701,7 +707,7 @@ mkJsSymbol mod s = mkFastString $ mconcat -- | read all dependency data from the to-be-linked files loadObjDeps :: [LinkedObj] -- ^ object files to link -> IO (Map Module (Deps, DepsLocation), [LinkableUnit]) -loadObjDeps objs = prepareLoadedDeps <$> mapM readDepsFile' objs +loadObjDeps objs = (prepareLoadedDeps . catMaybes) <$> mapM readDepsFromObj objs -- | Load dependencies for the Linker from Ar loadArchiveDeps :: GhcjsEnv @@ -779,11 +785,12 @@ requiredUnits d = map (depsModule d,) (IS.toList $ depsRequired d) -- | read dependencies from an object that might have already been into memory -- pulls in all Deps from an archive -readDepsFile' :: LinkedObj -> IO (Deps, DepsLocation) -readDepsFile' = \case +readDepsFromObj :: LinkedObj -> IO (Maybe (Deps, DepsLocation)) +readDepsFromObj = \case ObjLoaded name obj -> do let !deps = objDeps obj - pure (deps,InMemory name obj) + pure $ Just (deps,InMemory name obj) ObjFile file -> do - deps <- readObjectDeps file - pure (deps,ObjectFile file) + readObjectDeps file >>= \case + Nothing -> pure Nothing + Just deps -> pure $ Just (deps,ObjectFile file) ===================================== compiler/GHC/StgToJS/Linker/Types.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-orphans #-} -- for Ident's Binary instance @@ -19,27 +20,28 @@ module GHC.StgToJS.Linker.Types where -import GHC.JS.Syntax -import GHC.StgToJS.Object -import GHC.StgToJS.Types (ClosureInfo, StaticInfo) +import GHC.JS.Syntax +import GHC.StgToJS.Object +import GHC.StgToJS.Types (ClosureInfo, StaticInfo) -import GHC.Unit.Types -import GHC.Data.FastString -import GHC.Types.Unique.Map +import GHC.Unit.Types +import GHC.Data.FastString +import GHC.Types.Unique.Map +import GHC.Utils.Outputable (hsep,Outputable(..),text,ppr) -import Control.Monad +import Control.Monad -import Data.Array -import Data.ByteString (ByteString) -import Data.Map.Strict (Map) -import qualified Data.Map.Strict as M -import Data.Set (Set) +import Data.Array +import Data.ByteString (ByteString) +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as M +import Data.Set (Set) -import Control.Concurrent.MVar +import Control.Concurrent.MVar -import System.IO +import System.IO -import Prelude +import Prelude -- | return a list of fresh @Ident@ newLocals :: [Ident] @@ -343,6 +345,11 @@ data LinkedObj = ObjFile FilePath -- ^ load from this file | ObjLoaded String Object -- ^ already loaded: description and payload +instance Outputable LinkedObj where + ppr = \case + ObjFile fp -> hsep [text "ObjFile", text fp] + ObjLoaded s o -> hsep [text "ObjLoaded", text s, ppr (objModuleName o)] + data GhcjsEnv = GhcjsEnv { linkerArchiveDeps :: MVar (Map (Set FilePath) (Map Module (Deps, DepsLocation) ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -89,8 +89,7 @@ import GHC.Types.Unique.Map import GHC.Float (castDoubleToWord64, castWord64ToDouble) import GHC.Utils.Binary hiding (SymbolTable) -import GHC.Utils.Outputable (ppr, Outputable, hcat, vcat, text) -import GHC.Utils.Panic +import GHC.Utils.Outputable (ppr, Outputable, hcat, vcat, text, hsep) import GHC.Utils.Monad (mapMaybeM) -- | An object file @@ -135,6 +134,12 @@ data DepsLocation | ArchiveFile FilePath -- ^ In a Ar file at path | InMemory String Object -- ^ In memory +instance Outputable DepsLocation where + ppr = \case + ObjectFile fp -> hsep [text "ObjectFile", text fp] + ArchiveFile fp -> hsep [text "ArchiveFile", text fp] + InMemory s o -> hsep [text "InMemory", text s, ppr (objModuleName o)] + data BlockDeps = BlockDeps { blockBlockDeps :: [Int] -- ^ dependencies on blocks in this object , blockFunDeps :: [ExportedFun] -- ^ dependencies on exported symbols in other objects @@ -304,26 +309,27 @@ getObjectBody bh0 mod_name = do } -- | Parse object -getObject :: BinHandle -> IO Object +getObject :: BinHandle -> IO (Maybe Object) getObject bh = do getObjectHeader bh >>= \case - Left err -> panic ("getObject: " ++ err) - Right mod_name -> getObjectBody bh mod_name + Left _err -> pure Nothing + Right mod_name -> Just <$> getObjectBody bh mod_name -- | Read object from file -- -- The object is still in memory after this (see objHandle). -readObject :: FilePath -> IO Object +readObject :: FilePath -> IO (Maybe Object) readObject file = do bh <- readBinMem file getObject bh -- | Reads only the part necessary to get the dependencies -readObjectDeps :: FilePath -> IO Deps +readObjectDeps :: FilePath -> IO (Maybe Deps) readObjectDeps file = do bh <- readBinMem file - obj <- getObject bh - pure $! objDeps obj + getObject bh >>= \case + Just obj -> pure $! Just $! objDeps obj + Nothing -> pure Nothing -- | Get units in the object file, using the given filtering function getObjectUnits :: Object -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit] @@ -339,8 +345,9 @@ getObjectUnits obj pred = mapMaybeM read_entry (zip (objIndex obj) [0..]) -- | Read units in the object file, using the given filtering function readObjectUnits :: FilePath -> (Word -> IndexEntry -> Bool) -> IO [ObjUnit] readObjectUnits file pred = do - obj <- readObject file - getObjectUnits obj pred + readObject file >>= \case + Nothing -> pure [] + Just obj -> getObjectUnits obj pred -------------------------------------------------------------------------------- ===================================== rts/rts.cabal.in ===================================== @@ -481,6 +481,7 @@ library cmm-sources: Apply.cmm Compact.cmm + ContinuationOps.cmm Exception.cmm HeapStackCheck.cmm PrimOps.cmm @@ -497,7 +498,7 @@ library else -- Use GHC's native adjustors if arch(i386) - asm-sources: AdjustorAsm.S + asm-sources: adjustor/Nativei386Asm.S c-sources: adjustor/Nativei386.c if arch(x86_64) if os(mingw32) @@ -525,6 +526,7 @@ library CloneStack.c ClosureFlags.c ClosureSize.c + Continuation.c Disassembler.c FileLock.c ForeignExports.c ===================================== rts/rts.cabal.in.orig deleted ===================================== @@ -1,662 +0,0 @@ -cabal-version: 3.0 -name: rts -version: 1.0.2 -license: BSD-3-Clause -maintainer: glasgow-haskell-users at haskell.org -build-type: Simple - -source-repository head - type: git - location: https://gitlab.haskell.org/ghc/ghc.git - subdir: rts - -flag libm - default: @CabalHaveLibm@ -flag librt - default: @CabalHaveLibrt@ -flag libdl - default: @CabalHaveLibdl@ -flag use-system-libffi - default: @CabalUseSystemLibFFI@ -flag libffi-adjustors - default: @CabalLibffiAdjustors@ -flag need-pthread - default: @CabalNeedLibpthread@ -flag libbfd - default: @CabalHaveLibbfd@ -flag mingwex - default: @CabalMingwex@ -flag need-atomic - default: @CabalNeedLibatomic@ -flag libdw - default: @CabalHaveLibdw@ -flag libnuma - default: @CabalHaveLibNuma@ -flag 64bit - default: @Cabal64bit@ -flag leading-underscore - default: @CabalLeadingUnderscore@ -flag smp - default: True -flag find-ptr - default: False --- Some cabal flags used to control the flavours we want to produce --- for libHSrts in hadrian. By default, we just produce vanilla and --- threaded. The flags "compose": if you enable debug and profiling, --- you will produce vanilla, _thr, _debug, _p but also _thr_p, --- _thr_debug_p and so on. -flag profiling - default: False -flag debug - default: False -flag logging - default: False -flag dynamic - default: False -flag thread-sanitizer - description: - Enable checking for data races using the ThreadSanitizer (TSAN) - mechanism supported by GCC and Clang. See Note [ThreadSanitizer] - in @rts/include/rts/TSANUtils.h at . - default: False - -library - -- rts is a wired in package and - -- expects the unit-id to be - -- set without version - ghc-options: -this-unit-id rts - - -- If we are using an in-tree libffi then we must declare it as a bundled - -- library to ensure that Cabal installs it. - if !flag(use-system-libffi) - if os(windows) - extra-bundled-libraries: Cffi-6 - else - extra-bundled-libraries: Cffi - - -- The make build system does something special in config.mk.in - -- for generating profiled, debugged, etc builds of those - -- libraries, but we need to be transparent for hadrian which - -- gets information about the rts "package" through Cabal and - -- this cabal file. We therefore declare several - -- flavours to be available when passing the suitable (combination of) - -- flag(s) when configuring the RTS from hadrian, using Cabal. - extra-library-flavours: _thr - - if flag(profiling) - extra-library-flavours: _p _thr_p - if flag(debug) - extra-library-flavours: _debug_p _thr_debug_p - if flag(debug) - extra-library-flavours: _debug _thr_debug - if flag(dynamic) - extra-dynamic-library-flavours: _debug _thr_debug - if flag(logging) - extra-library-flavours: _l _thr_l - if flag(dynamic) - extra-dynamic-library-flavours: _l _thr_l - if flag(dynamic) - extra-dynamic-library-flavours: _thr - - if flag(thread-sanitizer) - cc-options: -fsanitize=thread - ld-options: -fsanitize=thread - extra-libraries: tsan - - exposed: True - exposed-modules: - if os(linux) - -- the RTS depends upon libc. while this dependency is generally - -- implicitly added by `cc`, we must explicitly add it here to ensure - -- that it is ordered correctly with libpthread, since ghc-prim.cabal - -- also explicitly lists libc. See #19029. - extra-libraries: c - if flag(libm) - -- for ldexp() - extra-libraries: m - if flag(librt) - extra-libraries: rt - if flag(libdl) - extra-libraries: dl - if flag(use-system-libffi) - extra-libraries: ffi - if os(windows) - extra-libraries: - -- for the linker - wsock32 gdi32 winmm - -- for crash dump - dbghelp - -- for process information - psapi - -- TODO: Hadrian will use this cabal file, so drop WINVER from Hadrian's configs. - -- Minimum supported Windows version. - -- These numbers can be found at: - -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx - -- If we're compiling on windows, enforce that we only support Windows 7+ - -- Adding this here means it doesn't have to be done in individual .c files - -- and also centralizes the versioning. - cpp-options: -D_WIN32_WINNT=0x06010000 - cc-options: -D_WIN32_WINNT=0x06010000 - if flag(need-pthread) - -- for pthread_getthreadid_np, pthread_create, ... - extra-libraries: pthread - if flag(need-atomic) - -- for sub-word-sized atomic operations (#19119) - extra-libraries: atomic - if flag(libbfd) - -- for debugging - extra-libraries: bfd iberty - if flag(mingwex) - extra-libraries: mingwex - if flag(libdw) - -- for backtraces - extra-libraries: elf dw - if flag(libnuma) - extra-libraries: numa - if !flag(smp) - cpp-options: -DNOSMP - - include-dirs: include - @FFIIncludeDir@ - @LibdwIncludeDir@ - includes: Rts.h - install-includes: Cmm.h HsFFI.h MachDeps.h Rts.h RtsAPI.h Stg.h - ghcautoconf.h ghcconfig.h ghcplatform.h ghcversion.h - -- ^ from include - DerivedConstants.h ffi.h ffitarget.h - rts/EventLogConstants.h - rts/EventTypes.h - -- ^ generated - rts/Adjustor.h - rts/ExecPage.h - rts/BlockSignals.h - rts/Bytecodes.h - rts/Config.h - rts/Constants.h - rts/EventLogFormat.h - rts/EventLogWriter.h - rts/FileLock.h - rts/Flags.h - rts/ForeignExports.h - rts/GetTime.h - rts/Globals.h - rts/Hpc.h - rts/IOInterface.h - rts/Libdw.h - rts/LibdwPool.h - rts/Linker.h - rts/Main.h - rts/Messages.h - rts/NonMoving.h - rts/OSThreads.h - rts/Parallel.h - rts/PrimFloat.h - rts/Profiling.h - rts/IPE.h - rts/PosixSource.h - rts/Signals.h - rts/SpinLock.h - rts/StableName.h - rts/StablePtr.h - rts/StaticPtrTable.h - rts/TTY.h - rts/Threads.h - rts/Ticky.h - rts/Time.h - rts/Timer.h - rts/TSANUtils.h - rts/Types.h - rts/Utils.h - rts/prof/CCS.h - rts/prof/Heap.h - rts/prof/LDV.h - rts/storage/Block.h - rts/storage/ClosureMacros.h - rts/storage/ClosureTypes.h - rts/storage/Closures.h - rts/storage/FunTypes.h - rts/storage/Heap.h - rts/storage/GC.h - rts/storage/InfoTables.h - rts/storage/MBlock.h - rts/storage/TSO.h - stg/DLL.h - stg/MachRegs.h - stg/MachRegsForHost.h - stg/MiscClosures.h - stg/Prim.h - stg/Regs.h - stg/SMP.h - stg/Ticky.h - stg/Types.h - if flag(64bit) - if flag(leading-underscore) - ld-options: - "-Wl,-u,_hs_atomic_add64" - "-Wl,-u,_hs_atomic_sub64" - "-Wl,-u,_hs_atomic_and64" - "-Wl,-u,_hs_atomic_nand64" - "-Wl,-u,_hs_atomic_or64" - "-Wl,-u,_hs_atomic_xor64" - "-Wl,-u,_hs_atomicread64" - "-Wl,-u,_hs_atomicwrite64" - else - ld-options: - "-Wl,-u,hs_atomic_add64" - "-Wl,-u,hs_atomic_sub64" - "-Wl,-u,hs_atomic_and64" - "-Wl,-u,hs_atomic_nand64" - "-Wl,-u,hs_atomic_or64" - "-Wl,-u,hs_atomic_xor64" - "-Wl,-u,hs_atomicread64" - "-Wl,-u,hs_atomicwrite64" - if flag(leading-underscore) - ld-options: - "-Wl,-u,_base_GHCziTopHandler_runIO_closure" - "-Wl,-u,_base_GHCziTopHandler_runNonIO_closure" - "-Wl,-u,_ghczmprim_GHCziTuple_Z0T_closure" - "-Wl,-u,_ghczmprim_GHCziTypes_True_closure" - "-Wl,-u,_ghczmprim_GHCziTypes_False_closure" - "-Wl,-u,_base_GHCziPack_unpackCString_closure" - "-Wl,-u,_base_GHCziWeak_runFinalizzerBatch_closure" - "-Wl,-u,_base_GHCziIOziException_stackOverflow_closure" - "-Wl,-u,_base_GHCziIOziException_heapOverflow_closure" - "-Wl,-u,_base_GHCziIOziException_allocationLimitExceeded_closure" - "-Wl,-u,_base_GHCziIOziException_blockedIndefinitelyOnMVar_closure" - "-Wl,-u,_base_GHCziIOziException_blockedIndefinitelyOnSTM_closure" - "-Wl,-u,_base_GHCziIOziException_cannotCompactFunction_closure" - "-Wl,-u,_base_GHCziIOziException_cannotCompactPinned_closure" - "-Wl,-u,_base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,_base_GHCziIOPort_doubleReadException_closure" - "-Wl,-u,_base_ControlziExceptionziBase_nonTermination_closure" - "-Wl,-u,_base_ControlziExceptionziBase_nestedAtomically_closure" - "-Wl,-u,_base_GHCziEventziThread_blockedOnBadFD_closure" - "-Wl,-u,_base_GHCziConcziSync_runSparks_closure" - "-Wl,-u,_base_GHCziConcziIO_ensureIOManagerIsRunning_closure" - "-Wl,-u,_base_GHCziConcziIO_interruptIOManager_closure" - "-Wl,-u,_base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure" - "-Wl,-u,_base_GHCziConcziSignal_runHandlersPtr_closure" - "-Wl,-u,_base_GHCziTopHandler_flushStdHandles_closure" - "-Wl,-u,_base_GHCziTopHandler_runMainIO_closure" - "-Wl,-u,_ghczmprim_GHCziTypes_Czh_con_info" - "-Wl,-u,_ghczmprim_GHCziTypes_Izh_con_info" - "-Wl,-u,_ghczmprim_GHCziTypes_Fzh_con_info" - "-Wl,-u,_ghczmprim_GHCziTypes_Dzh_con_info" - "-Wl,-u,_ghczmprim_GHCziTypes_Wzh_con_info" - "-Wl,-u,_base_GHCziPtr_Ptr_con_info" - "-Wl,-u,_base_GHCziPtr_FunPtr_con_info" - "-Wl,-u,_base_GHCziInt_I8zh_con_info" - "-Wl,-u,_base_GHCziInt_I16zh_con_info" - "-Wl,-u,_base_GHCziInt_I32zh_con_info" - "-Wl,-u,_base_GHCziInt_I64zh_con_info" - "-Wl,-u,_base_GHCziWord_W8zh_con_info" - "-Wl,-u,_base_GHCziWord_W16zh_con_info" - "-Wl,-u,_base_GHCziWord_W32zh_con_info" - "-Wl,-u,_base_GHCziWord_W64zh_con_info" - "-Wl,-u,_base_GHCziStable_StablePtr_con_info" - "-Wl,-u,_hs_atomic_add8" - "-Wl,-u,_hs_atomic_add16" - "-Wl,-u,_hs_atomic_add32" - "-Wl,-u,_hs_atomic_sub8" - "-Wl,-u,_hs_atomic_sub16" - "-Wl,-u,_hs_atomic_sub32" - "-Wl,-u,_hs_atomic_and8" - "-Wl,-u,_hs_atomic_and16" - "-Wl,-u,_hs_atomic_and32" - "-Wl,-u,_hs_atomic_nand8" - "-Wl,-u,_hs_atomic_nand16" - "-Wl,-u,_hs_atomic_nand32" - "-Wl,-u,_hs_atomic_or8" - "-Wl,-u,_hs_atomic_or16" - "-Wl,-u,_hs_atomic_or32" - "-Wl,-u,_hs_atomic_xor8" - "-Wl,-u,_hs_atomic_xor16" - "-Wl,-u,_hs_atomic_xor32" - "-Wl,-u,_hs_cmpxchg8" - "-Wl,-u,_hs_cmpxchg16" - "-Wl,-u,_hs_cmpxchg32" - "-Wl,-u,_hs_cmpxchg64" - "-Wl,-u,_hs_xchg8" - "-Wl,-u,_hs_xchg16" - "-Wl,-u,_hs_xchg32" - "-Wl,-u,_hs_xchg64" - "-Wl,-u,_hs_atomicread8" - "-Wl,-u,_hs_atomicread16" - "-Wl,-u,_hs_atomicread32" - "-Wl,-u,_hs_atomicwrite8" - "-Wl,-u,_hs_atomicwrite16" - "-Wl,-u,_hs_atomicwrite32" - "-Wl,-u,_base_GHCziStackziCloneStack_StackSnapshot_closure" - - if flag(find-ptr) - -- This symbol is useful in gdb, but not referred to anywhere, - -- so we need to force it to be included in the binary. - ld-options: "-Wl,-u,_findPtr" - - else - ld-options: - "-Wl,-u,base_GHCziTopHandler_runIO_closure" - "-Wl,-u,base_GHCziTopHandler_runNonIO_closure" - "-Wl,-u,ghczmprim_GHCziTuple_Z0T_closure" - "-Wl,-u,ghczmprim_GHCziTypes_True_closure" - "-Wl,-u,ghczmprim_GHCziTypes_False_closure" - "-Wl,-u,base_GHCziPack_unpackCString_closure" - "-Wl,-u,base_GHCziWeak_runFinalizzerBatch_closure" - "-Wl,-u,base_GHCziIOziException_stackOverflow_closure" - "-Wl,-u,base_GHCziIOziException_heapOverflow_closure" - "-Wl,-u,base_GHCziIOziException_allocationLimitExceeded_closure" - "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure" - "-Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure" - "-Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure" - "-Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure" - "-Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,base_GHCziIOPort_doubleReadException_closure" - "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure" - "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure" - "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure" - "-Wl,-u,base_GHCziConcziSync_runSparks_closure" - "-Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure" - "-Wl,-u,base_GHCziConcziIO_interruptIOManager_closure" - "-Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure" - "-Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure" - "-Wl,-u,base_GHCziTopHandler_flushStdHandles_closure" - "-Wl,-u,base_GHCziTopHandler_runMainIO_closure" - "-Wl,-u,ghczmprim_GHCziTypes_Czh_con_info" - "-Wl,-u,ghczmprim_GHCziTypes_Izh_con_info" - "-Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info" - "-Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info" - "-Wl,-u,ghczmprim_GHCziTypes_Wzh_con_info" - "-Wl,-u,base_GHCziPtr_Ptr_con_info" - "-Wl,-u,base_GHCziPtr_FunPtr_con_info" - "-Wl,-u,base_GHCziInt_I8zh_con_info" - "-Wl,-u,base_GHCziInt_I16zh_con_info" - "-Wl,-u,base_GHCziInt_I32zh_con_info" - "-Wl,-u,base_GHCziInt_I64zh_con_info" - "-Wl,-u,base_GHCziWord_W8zh_con_info" - "-Wl,-u,base_GHCziWord_W16zh_con_info" - "-Wl,-u,base_GHCziWord_W32zh_con_info" - "-Wl,-u,base_GHCziWord_W64zh_con_info" - "-Wl,-u,base_GHCziStable_StablePtr_con_info" - "-Wl,-u,hs_atomic_add8" - "-Wl,-u,hs_atomic_add16" - "-Wl,-u,hs_atomic_add32" - "-Wl,-u,hs_atomic_sub8" - "-Wl,-u,hs_atomic_sub16" - "-Wl,-u,hs_atomic_sub32" - "-Wl,-u,hs_atomic_and8" - "-Wl,-u,hs_atomic_and16" - "-Wl,-u,hs_atomic_and32" - "-Wl,-u,hs_atomic_nand8" - "-Wl,-u,hs_atomic_nand16" - "-Wl,-u,hs_atomic_nand32" - "-Wl,-u,hs_atomic_or8" - "-Wl,-u,hs_atomic_or16" - "-Wl,-u,hs_atomic_or32" - "-Wl,-u,hs_atomic_xor8" - "-Wl,-u,hs_atomic_xor16" - "-Wl,-u,hs_atomic_xor32" - "-Wl,-u,hs_cmpxchg8" - "-Wl,-u,hs_cmpxchg16" - "-Wl,-u,hs_cmpxchg32" - "-Wl,-u,hs_cmpxchg64" - "-Wl,-u,hs_xchg8" - "-Wl,-u,hs_xchg16" - "-Wl,-u,hs_xchg32" - "-Wl,-u,hs_xchg64" - "-Wl,-u,hs_atomicread8" - "-Wl,-u,hs_atomicread16" - "-Wl,-u,hs_atomicread32" - "-Wl,-u,hs_atomicwrite8" - "-Wl,-u,hs_atomicwrite16" - "-Wl,-u,hs_atomicwrite32" - "-Wl,-u,base_GHCziStackziCloneStack_StackSnapshot_closure" - - if flag(find-ptr) - -- This symbol is useful in gdb, but not referred to anywhere, - -- so we need to force it to be included in the binary. - ld-options: "-Wl,-u,findPtr" - -- This symbol is useful in gdb, but not referred to anywhere, - -- so we need to force it to be included in the binary. - "-Wl,-u,findPtr" - - if os(windows) - if flag(leading-underscore) - ld-options: - "-Wl,-u,_base_GHCziEventziWindows_processRemoteCompletion_closure" - else - ld-options: - "-Wl,-u,base_GHCziEventziWindows_processRemoteCompletion_closure" - - if os(osx) - ld-options: "-Wl,-search_paths_first" - -- See Note [fd_set_overflow] - "-Wl,-U,___darwin_check_fd_set_overflow" - if !arch(x86_64) && !arch(aarch64) - ld-options: -read_only_relocs warning - - cmm-sources: Apply.cmm - Compact.cmm - Exception.cmm - HeapStackCheck.cmm - PrimOps.cmm - StgMiscClosures.cmm - StgStartup.cmm - StgStdThunks.cmm - Updates.cmm - -- AutoApply is generated - AutoApply.cmm - - -- Adjustor stuff - if flag(libffi-adjustors) - c-sources: adjustor/LibffiAdjustor.c - else - -- Use GHC's native adjustors - if arch(i386) - asm-sources: AdjustorAsm.S - c-sources: adjustor/Nativei386.c - if arch(x86_64) - if os(mingw32) - asm-sources: adjustor/NativeAmd64MingwAsm.S - c-sources: adjustor/NativeAmd64Mingw.c - else - asm-sources: adjustor/NativeAmd64Asm.S - c-sources: adjustor/NativeAmd64.c - if arch(ppc) || arch(ppc64) - asm-sources: AdjustorAsm.S - c-sources: adjustor/NativePowerPC.c - if arch(ia64) - c-sources: adjustor/NativeIA64.c - - -- Use assembler STG entrypoint on archictures where it is used - if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64) - asm-sources: StgCRunAsm.S - - c-sources: Adjustor.c - adjustor/AdjustorPool.c - ExecPage.c - Arena.c - Capability.c - CheckUnload.c - CloneStack.c - ClosureFlags.c - ClosureSize.c - Disassembler.c - FileLock.c - ForeignExports.c - Globals.c - Hash.c - Heap.c - Hpc.c - HsFFI.c - Inlines.c - Interpreter.c - IOManager.c - LdvProfile.c - Libdw.c - LibdwPool.c - Linker.c - ReportMemoryMap.c - Messages.c - OldARMAtomic.c - PathUtils.c - Pool.c - Printer.c - ProfHeap.c - ProfilerReport.c - ProfilerReportJson.c - Profiling.c - IPE.c - Proftimer.c - RaiseAsync.c - RetainerProfile.c - RetainerSet.c - RtsAPI.c - RtsDllMain.c - RtsFlags.c - RtsMain.c - RtsMessages.c - RtsStartup.c - RtsSymbolInfo.c - RtsSymbols.c - RtsUtils.c - STM.c - Schedule.c - Sparks.c - SpinLock.c - StableName.c - StablePtr.c - StaticPtrTable.c - Stats.c - StgCRun.c - StgPrimFloat.c - Task.c - ThreadLabels.c - ThreadPaused.c - Threads.c - Ticky.c - Timer.c - TopHandler.c - Trace.c - TraverseHeap.c - TraverseHeapTest.c - WSDeque.c - Weak.c - eventlog/EventLog.c - eventlog/EventLogWriter.c - hooks/FlagDefaults.c - hooks/LongGCSync.c - hooks/MallocFail.c - hooks/OnExit.c - hooks/OutOfHeap.c - hooks/StackOverflow.c - linker/CacheFlush.c - linker/Elf.c - linker/LoadArchive.c - linker/M32Alloc.c - linker/MMap.c - linker/MachO.c - linker/macho/plt.c - linker/macho/plt_aarch64.c - linker/PEi386.c - linker/SymbolExtras.c - linker/elf_got.c - linker/elf_plt.c - linker/elf_plt_aarch64.c - linker/elf_plt_arm.c - linker/elf_reloc.c - linker/elf_reloc_aarch64.c - linker/elf_tlsgd.c - linker/elf_util.c - sm/BlockAlloc.c - sm/CNF.c - sm/Compact.c - sm/Evac.c - sm/Evac_thr.c - sm/GC.c - sm/GCAux.c - sm/GCUtils.c - sm/MBlock.c - sm/MarkWeak.c - sm/NonMoving.c - sm/NonMovingCensus.c - sm/NonMovingMark.c - sm/NonMovingScav.c - sm/NonMovingShortcut.c - sm/NonMovingSweep.c - sm/Sanity.c - sm/Scav.c - sm/Scav_thr.c - sm/Storage.c - sm/Sweep.c - fs.c - -- I wish we had wildcards..., this would be: - -- *.c hooks/**/*.c sm/**/*.c eventlog/**/*.c linker/**/*.c - - if os(windows) - c-sources: win32/AsyncMIO.c - win32/AsyncWinIO.c - win32/AwaitEvent.c - win32/ConsoleHandler.c - win32/GetEnv.c - win32/GetTime.c - win32/MIOManager.c - win32/OSMem.c - win32/OSThreads.c - win32/ThrIOManager.c - win32/Ticker.c - win32/WorkQueue.c - win32/veh_excn.c - -- win32/**/*.c - else - c-sources: posix/GetEnv.c - posix/GetTime.c - posix/Ticker.c - posix/OSMem.c - posix/OSThreads.c - posix/Select.c - posix/Signals.c - posix/TTY.c - -- ticker/*.c - -- We don't want to compile posix/ticker/*.c, these will be #included - -- from Ticker.c - - --- Note [fd_set_overflow] --- ~~~~~~~~~~~~~~~~~~~~~~ --- In this note is the very sad tale of __darwin_fd_set_overflow. --- The 8.10.5 release was broken because it was built in an environment --- where the libraries were provided by XCode 12.*, these libraries introduced --- a reference to __darwin_fd_set_overflow via the FD_SET macro which is used in --- Select.c. Unfortunately, this symbol is not available with XCode 11.* which --- led to a linker error when trying to link anything. This is almost certainly --- a bug in XCode but we still have to work around it. - --- Undefined symbols for architecture x86_64: --- "___darwin_check_fd_set_overflow", referenced from: --- _awaitEvent in libHSrts.a(Select.o) --- ld: symbol(s) not found for architecture x86_64 - --- One way to fix this is to upgrade your version of xcode, but this would --- force the upgrade on users prematurely. Fortunately it also seems safe to pass --- the linker option "-Wl,-U,___darwin_check_fd_set_overflow" because the usage of --- the symbol is guarded by a guard to check if it's defined. - --- __header_always_inline int --- __darwin_check_fd_set(int _a, const void *_b) --- { --- if ((uintptr_t)&__darwin_check_fd_set_overflow != (uintptr_t) 0) { ---#if defined(_DARWIN_UNLIMITED_SELECT) || defined(_DARWIN_C_SOURCE) --- return __darwin_check_fd_set_overflow(_a, _b, 1); ---#else --- return __darwin_check_fd_set_overflow(_a, _b, 0); ---#endif --- } else { --- return 1; --- } ---} - --- Across the internet there are many other reports of this issue --- See: https://github.com/mono/mono/issues/19393 --- , https://github.com/sitsofe/fio/commit/b6a1e63a1ff607692a3caf3c2db2c3d575ba2320 - --- The issue was originally reported in #19950 ===================================== testsuite/tests/rts/T9579/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_skip) # the JS backend doesn't detect overflows + # some numbers like "(1 MB)" would still remain. # but let's just assume the actual difference in bytes # is too small to have an effect on the rounded megabyte value. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b82f6e7b7a7acee4bce84a728a5ae8cd539b04ec...5b1174db9df1072cd56009f81ea5d3d8acc22031 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b82f6e7b7a7acee4bce84a728a5ae8cd539b04ec...5b1174db9df1072cd56009f81ea5d3d8acc22031 You're receiving 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 Oct 10 13:57:50 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 10 Oct 2022 09:57:50 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Doc Message-ID: <634424de8d523_1eea6a5181c22483406@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c089b339 by Sylvain Henry at 2022-10-10T16:01:13+02:00 Doc - - - - - 3 changed files: - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/StgToJS.hs Changes: ===================================== compiler/GHC/Driver/Backend.hs ===================================== @@ -280,19 +280,7 @@ llvmBackend = Named LLVM -- | The JavaScript Backend -- --- Compiles Stg code to JS, the relies on the --- JS toolchain to produce workable code. --- --- Notable points are: --- 1. The JS backend /does not/ rely on GHC's native RTS or linker. --- 2. Instead, the JS backend writes its own RTS. This RTS is split between --- Haskell (see "GHC.StgToJS.Rts") and JavaScript (see "js" directory in root of --- GHC project). --- 3. "Linking" in the JS backend is not actually linking, rather it is merging --- JS concrete syntax with static guarentees that all symbols used are defined --- before their call sites (see "GHC.StgToJS.Linker"). --- --- See "GHC.StgToJS" +-- See documentation in GHC.StgToJS jsBackend = Named JavaScript -- | Via-C ("unregisterised") backend. ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -348,6 +348,7 @@ runAsPhase with_cpp pipe_env hsc_env location input_fn = do return output_fn +-- | Embed .js files into .o files runJsPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath runJsPhase pipe_env hsc_env input_fn = do let dflags = hsc_dflags hsc_env ===================================== compiler/GHC/StgToJS.hs ===================================== @@ -18,7 +18,6 @@ import GHC.StgToJS.CodeGen -- -- Tail calls: translated code is tail call optimized through a trampoline, -- since JavaScript implementations don't always support tail calls. --- TODO: add GHCJS optimizer for this to be true -- -- JavaScript ASTs are then optimized. A dataflow analysis is performed and then -- dead code and redundant assignments are removed. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c089b339f4a84a7da964ac31e096a5be7fd4e261 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c089b339f4a84a7da964ac31e096a5be7fd4e261 You're receiving 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 Oct 10 14:25:36 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 10 Oct 2022 10:25:36 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Add perf-js Hadrian flavour Message-ID: <63442b60971da_1eea6a5143c8417ea@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 869bebdd by Sylvain Henry at 2022-10-10T16:28:54+02:00 Add perf-js Hadrian flavour - - - - - 2 changed files: - hadrian/src/Settings.hs - hadrian/src/Settings/Flavours/QuickCross.hs Changes: ===================================== hadrian/src/Settings.hs ===================================== @@ -58,6 +58,7 @@ hadrianFlavours = , quickestFlavour , quickCrossFlavour , quickJsFlavour + , perfJsFlavour , ghcInGhciFlavour, validateFlavour, slowValidateFlavour ] ===================================== hadrian/src/Settings/Flavours/QuickCross.hs ===================================== @@ -1,4 +1,4 @@ -module Settings.Flavours.QuickCross (quickCrossFlavour, quickJsFlavour) where +module Settings.Flavours.QuickCross (quickCrossFlavour, quickJsFlavour, perfJsFlavour) where import qualified Data.Set as Set @@ -16,7 +16,15 @@ quickJsFlavour = defaultFlavour , rtsWays = pure $ Set.singleton vanilla } --- Same as quickCrossArgs (until it bitrots) but don't enable -fllvm +perfJsFlavour :: Flavour +perfJsFlavour = defaultFlavour + { name = "perf-js" + , args = defaultBuilderArgs <> perfJsArgs <> defaultPackageArgs + , dynamicGhcPrograms = pure False + , libraryWays = pure $ Set.singleton vanilla + , rtsWays = pure $ Set.singleton vanilla + } + quickJsArgs :: Args quickJsArgs = sourceArgs SourceArgs { hsDefault = mconcat $ @@ -28,6 +36,14 @@ quickJsArgs = sourceArgs SourceArgs [ stage0 ? arg "-O" , stage1 ? mconcat [ arg "-O0" ] ] } +perfJsArgs :: Args +perfJsArgs = sourceArgs SourceArgs + { hsDefault = mconcat [ arg "-O2", arg "-H64m"] + , hsLibrary = arg "-O2" + , hsCompiler = arg "-O2" + , hsGhc = arg "-O2" + } + -- Please update doc/flavours.md when changing this file. quickCrossFlavour :: Flavour quickCrossFlavour = defaultFlavour View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/869bebdd8442640dde29825c77e0755913432c82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/869bebdd8442640dde29825c77e0755913432c82 You're receiving 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 Oct 10 15:23:00 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Mon, 10 Oct 2022 11:23:00 -0400 Subject: [Git][ghc/ghc][wip/js-staging] JS.Syntax: fix doc wording Message-ID: <634438d49e21b_1eea6a529f4f8c85013@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 1898c183 by doyougnu at 2022-10-10T11:22:51-04:00 JS.Syntax: fix doc wording - - - - - 1 changed file: - compiler/GHC/JS/Syntax.hs Changes: ===================================== compiler/GHC/JS/Syntax.hs ===================================== @@ -37,9 +37,9 @@ -- -- * Strategy -- --- Nothing fancy in this module, this is a classicdeeply embeded AST for JS. --- We define numerous ADTs and pattern synonyms to make pattern matching and --- constructing ASTs easier. +-- Nothing fancy in this module, this is a classic deeply embeded AST for +-- JS. We define numerous ADTs and pattern synonyms to make pattern matching +-- and constructing ASTs easier. -- -- -- * Consumers View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1898c183a8c4c048da7a73529900a893ca7cc672 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1898c183a8c4c048da7a73529900a893ca7cc672 You're receiving 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 Oct 10 15:23:50 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Mon, 10 Oct 2022 11:23:50 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Driver: JS: tweak error message Message-ID: <63443906d7293_1eea6a5fada5c085213e@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 2121147f by doyougnu at 2022-10-10T11:23:34-04:00 Driver: JS: tweak error message - - - - - 1 changed file: - compiler/GHC/Driver/CodeOutput.hs Changes: ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -225,7 +225,7 @@ outputLlvm logger llvm_config dflags filenm cmm_stream = do ************************************************************************ -} outputJS :: Logger -> LlvmConfigCache -> DynFlags -> FilePath -> Stream IO RawCmmGroup a -> IO a -outputJS _ _ _ _ _ = pgmError $ "codeOutput: Hit JavaScript case. You should never reach here!" +outputJS _ _ _ _ _ = pgmError $ "codeOutput: Hit JavaScript case. We should never reach here!" ++ "\nThe JS backend should shortcircuit to StgToJS after Stg." ++ "\nIf you reached this point then you've somehow made it to Cmm!" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2121147f3275a3aaddad397dcf690bee71fe2043 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2121147f3275a3aaddad397dcf690bee71fe2043 You're receiving 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 Oct 10 15:34:28 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 11:34:28 -0400 Subject: [Git][ghc/ghc][wip/T21851-rule-win] Make rewrite rules "win" over inlining Message-ID: <63443b844c4eb_1eea6a529f4f8c856177@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851-rule-win at Glasgow Haskell Compiler / GHC Commits: 0c6b51d9 by Simon Peyton Jones at 2022-10-10T16:36:10+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - 12 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Utils/Monad.hs - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } - - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3668,7 +3714,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -430,3 +430,7 @@ test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c6b51d9deff280b07980905ecc55f79749ea88e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c6b51d9deff280b07980905ecc55f79749ea88e You're receiving 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 Oct 10 15:40:17 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 10 Oct 2022 11:40:17 -0400 Subject: [Git][ghc/ghc][wip/javascript-backend] Add JavaScript code generator Message-ID: <63443ce1d993d_1eea6a529f4f648726d5@gitlab.mail> Sylvain Henry pushed to branch wip/javascript-backend at Glasgow Haskell Compiler / GHC Commits: c71aed7a by doyougnu at 2022-10-10T17:43:37+02:00 Add JavaScript code generator Adapt code generator of GHCJS to GHC head. Currently it is only enabled with the hidden -fjavascript flag. It produces .o files that can't be used yet except by GHCJS's linker. Codegen: doc Codegen: correctly return linkable object Now we can build a static library (-staticlib) Codegen: doc genLit Codegen: use assignAll Codegen: introduce TypedExpr Refactor assignAll et al, add documentation Codegen: minor changes Doc - - - - - 24 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Data/Graph/Directed.hs - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/Backend/Internal.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/StgToCmm.hs - + compiler/GHC/Driver/Config/StgToJS.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Phases.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Foreign/C.hs - compiler/GHC/HsToCore/Foreign/Decl.hs - + compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Tidy/StaticPtrTable.hs - + compiler/GHC/JS/Make.hs - + compiler/GHC/JS/Parser/Header.hs - + compiler/GHC/JS/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c71aed7a1e4efe85fb8748a6d488e13701196da6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c71aed7a1e4efe85fb8748a6d488e13701196da6 You're receiving 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 Oct 10 15:42:12 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 10 Oct 2022 11:42:12 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Factor JS platform constants and h$programArgs/h$rtsArgs into functions with init Message-ID: <63443d54247f4_1eea6a5fc830fc8733b8@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 42256338 by Josh Meredith at 2022-10-10T15:40:51+00:00 Factor JS platform constants and h$programArgs/h$rtsArgs into functions with init - - - - - 7 changed files: - libraries/base/jsbits/base.js - libraries/base/jsbits/platform.js - rts/js/debug.js - rts/js/environment.js - rts/js/gc.js - rts/js/profiling.js - rts/js/thread.js Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -15,7 +15,7 @@ function h$logIO() { h$log.apply(h$log, arguments); } function h$base_access(file, file_off, mode, c) { TRACE_IO("base_access"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.stat(fd, function(err, fs) { if(err) { h$handleErrnoC(err, -1, 0, c); @@ -31,7 +31,7 @@ function h$base_access(file, file_off, mode, c) { function h$base_chmod(file, file_off, mode, c) { TRACE_IO("base_chmod"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.chmod(h$decodeUtf8z(file, file_off), mode, function(err) { h$handleErrnoC(err, -1, 0, c); }); @@ -110,7 +110,7 @@ function h$base_dup2(fd, new_fd, c) { function h$base_fstat(fd, stat, stat_off, c) { TRACE_IO("base_stat"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.fstat(fd, function(err, fs) { if(err) { h$handleErrnoC(err, -1, 0, c); @@ -175,7 +175,7 @@ function h$long_from_number(f,c) { function h$base_lseek(fd, pos_h, pos_l, whence, c) { TRACE_IO("base_lseek"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { var p = CLOSEST_FLOAT_NUMBER(pos_h,pos_l); var o = h$base_fds[fd]; if(!o) { @@ -219,7 +219,7 @@ function h$base_lseek(fd, pos_h, pos_l, whence, c) { function h$base_lstat(file, file_off, stat, stat_off, c) { TRACE_IO("base_lstat"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.lstat(h$decodeUtf8z(file, file_off), function(err, fs) { if(err) { h$handleErrnoC(err, -1, 0, c); @@ -234,7 +234,7 @@ function h$base_lstat(file, file_off, stat, stat_off, c) { } function h$base_open(file, file_off, how, mode, c) { #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { var flags, off; var fp = h$decodeUtf8z(file, file_off); TRACE_IO("base_open: " + fp); @@ -294,7 +294,7 @@ function h$base_read(fd, buf, buf_off, n, c) { function h$base_stat(file, file_off, stat, stat_off, c) { TRACE_IO("base_stat"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.stat(h$decodeUtf8z(file, file_off), function(err, fs) { if(err) { h$handleErrnoC(err, -1, 0, c); @@ -310,7 +310,7 @@ function h$base_stat(file, file_off, stat, stat_off, c) { function h$base_umask(mode) { TRACE_IO("base_umask: " + mode); #ifndef GHCJS_BROWSER - if(h$isNode) return process.umask(mode); + if(h$isNode()) return process.umask(mode); #endif return 0; } @@ -337,7 +337,7 @@ function h$base_write(fd, buf, buf_off, n, c) { function h$base_ftruncate(fd, pos_h, pos_l, c) { TRACE_IO("base_ftruncate"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.ftruncate(fd, CLOSEST_FLOAT_NUMBER(pos_h,pos_l), function(err) { h$handleErrnoC(err, -1, 0, c); }); @@ -348,7 +348,7 @@ function h$base_ftruncate(fd, pos_h, pos_l, c) { function h$base_unlink(file, file_off, c) { TRACE_IO("base_unlink"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.unlink(h$decodeUtf8z(file, file_off), function(err) { h$handleErrnoC(err, -1, 0, c); }); @@ -359,14 +359,14 @@ function h$base_unlink(file, file_off, c) { function h$base_getpid() { TRACE_IO("base_getpid"); #ifndef GHCJS_BROWSER - if(h$isNode) return process.pid; + if(h$isNode()) return process.pid; #endif return 0; } function h$base_link(file1, file1_off, file2, file2_off, c) { TRACE_IO("base_link"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.link(h$decodeUtf8z(file1, file1_off), h$decodeUtf8z(file2, file2_off), function(err) { h$handleErrnoC(err, -1, 0, c); }); @@ -398,7 +398,7 @@ function h$base_tcsetattr(attr, val, termios, termios_off) { function h$base_utime(file, file_off, timbuf, timbuf_off, c) { TRACE_IO("base_utime"); #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { h$fs.fstat(h$decodeUtf8z(file, file_off), function(err, fs) { if(err) { h$handleErrnoC(err, 0, -1, c); // fixme @@ -588,7 +588,7 @@ var h$base_process_stdin = function() { c.processing = false; } -if(h$isNode) { +if(h$isNode()) { h$base_closeFile = function(fd, fdo, c) { TRACE_IO("base_closeFile: " + fd + " (" + fdo.fd + ")"); var real_fd = typeof fdo.fd === 'number' ? fdo.fd : fd; @@ -677,7 +677,7 @@ if(h$isNode) { h$base_isattyStdout = function() { return process.stdout.isTTY; }; h$base_isattyStderr = function() { return process.stderr.isTTY; }; -} else if (h$isJsShell) { +} else if (h$isJsShell()) { h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) { c(0); } @@ -759,8 +759,8 @@ var h$base_fds = [h$base_stdin_fd, h$base_stdout_fd, h$base_stderr_fd]; function h$shutdownHaskellAndExit(code, fast) { #ifndef GHCJS_BROWSER #ifdef GHCJS_LOG_BUFFER - if(h$isNode) console.log(h$logBuffer); - if(h$isJsShell || h$isJsCore) print(h$logBuffer); + if(h$isNode()) console.log(h$logBuffer); + if(h$isJsShell() || h$isJsCore) print(h$logBuffer); #endif #endif h$exitProcess(code); ===================================== libraries/base/jsbits/platform.js ===================================== @@ -13,17 +13,41 @@ more platforms should be added here in the future */ #ifndef GHCJS_BROWSER -var h$isNode = false; // runtime is node.js -var h$isJvm = false; // runtime is JVM -var h$isJsShell = false; // runtime is SpiderMonkey jsshell -var h$isJsCore = false; // runtime is JavaScriptCore jsc -var h$isBrowser = false; // running in browser or everything else +var h$isNode_ = false; // runtime is node.js +var h$isJvm_ = false; // runtime is JVM +var h$isJsShell_ = false; // runtime is SpiderMonkey jsshell +var h$isJsCore_ = false; // runtime is JavaScriptCore jsc +var h$isBrowser_ = false; // running in browser or everything else -var h$isGHCJSi = false; // Code is GHCJSi (browser or node) +var h$isGHCJSi_ = false; // Code is GHCJSi (browser or node) + +function h$isNode() { + return h$isNode_; +} + +function h$isJvm() { + return h$isJvm_; +} + +function h$isJsShell() { + return h$isJsShell_; +} + +function h$isJsCore() { + return h$isJsCore_; +} + +function h$isBrowser() { + return h$isBrowser_; +} + +function h$isGHCJSi() { + return h$isGHCJSi_; +} // load all required node.js modules if(typeof process !== 'undefined' && (typeof h$TH !== 'undefined' || (typeof require !== 'undefined' && typeof module !== 'undefined' && module.exports))) { - h$isNode = true; + h$isNode_ = true; // we have to use these names for the closure compiler externs to work var fs = require('fs'); var path = require('path'); @@ -53,22 +77,22 @@ if(typeof process !== 'undefined' && (typeof h$TH !== 'undefined' || (typeof req } var h$processConstants = h$getProcessConstants(); } else if(typeof Java !== 'undefined') { - h$isJvm = true; + h$isJvm_ = true; this.console = { log: function(s) { java.lang.System.out.print(s); } }; } else if(typeof snarf !== 'undefined' && typeof print !== 'undefined' && typeof quit !== 'undefined') { - h$isJsShell = true; + h$isJsShell_ = true; this.console = { log: this.print }; } else if(typeof numberOfDFGCompiles !== 'undefined' && typeof jscStack !== 'undefined') { - h$isJsCore = true; + h$isJsCore_ = true; } else { - h$isBrowser = true; + h$isBrowser_ = true; } if(typeof global !== 'undefined' && global.h$GHCJSi) { - h$isGHCJSi = true; + h$isGHCJSi_ = true; } #endif ===================================== rts/js/debug.js ===================================== @@ -73,7 +73,7 @@ function h$debugAlloc_init_internal() { }; #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { try { // the 'weak' package provides the same functionality, but segfaults // try this first @@ -237,7 +237,7 @@ var h$debug = {}; function h$loadDebugTools() { function load(m, p) { - if(h$isNode) { + if(h$isNode()) { try { var t = require(m); h$debug[p] = t; @@ -247,7 +247,7 @@ function h$loadDebugTools() { load('gc-stats', 'gcStats'); load('v8-natives', 'v8'); var t; - if(h$isNode) { + if(h$isNode()) { try { t = require('gc-stats'); h$debug.gcStats = t; ===================================== rts/js/environment.js ===================================== @@ -74,78 +74,95 @@ function h$collectProps(o) { // load the command line arguments in h$programArgs // the first element is the program name -var h$programArgs; -#ifdef GHCJS_BROWSER -h$programArgs = [ "a.js" ]; -#else -if(h$isNode) { - h$programArgs = process.argv.slice(1); -} else if(h$isJvm) { - h$programArgs = h$getGlobal(this).arguments.slice(0); - h$programArgs.unshift("a.js"); -} else if(h$isJsShell && typeof h$getGlobal(this).scriptArgs !== 'undefined') { - h$programArgs = h$getGlobal(this).scriptArgs.slice(0); - h$programArgs.unshift("a.js"); -} else if((h$isJsShell || h$isJsCore) && typeof h$getGlobal(this).arguments !== 'undefined') { - h$programArgs = h$getGlobal(this).arguments.slice(0); - h$programArgs.unshift("a.js"); -} else { - h$programArgs = [ "a.js" ]; +var h$programArgs_; +var h$rtsArgs_; + +function h$programArgs() { + if (!h$programArgs_) { + h$initArgs(); + } + return h$programArgs_; } -#endif -//filter RTS arguments -var h$rtsArgs = []; -{ - var prog_args = []; - var rts_args = []; - var in_rts = false; - var i = 0; - for(i=0;i " + val); - if(h$isNode) process.env[name] = val; + if(h$isNode()) process.env[name] = val; } #endif return 0; @@ -303,7 +320,7 @@ function h$append_prog_name(str) { } // only works for node for now - if(h$isNode) { + if(h$isNode()) { return basename(process.argv[1]) + ": " + str; } @@ -326,15 +343,15 @@ function h$errorMsg(pat) { str = str.replace(/%s/, arguments[i]); } #ifndef GHCJS_BROWSER - if(h$isGHCJSi) { + if(h$isGHCJSi()) { // ignore message - } else if(h$isNode) { + } else if(h$isNode()) { process.stderr.write(str); - } else if (h$isJsShell && typeof printErr !== 'undefined') { + } else if (h$isJsShell() && typeof printErr !== 'undefined') { if(str.length) printErr(stripTrailingNewline(str)); - } else if (h$isJsShell && typeof putstr !== 'undefined') { + } else if (h$isJsShell() && typeof putstr !== 'undefined') { putstr(str); - } else if (h$isJsCore) { + } else if (h$isJsCore()) { if(str.length) { if(h$base_stderrLeftover.val !== null) { debug(h$base_stderrLeftover.val + stripTrailingNewline(str)); ===================================== rts/js/gc.js ===================================== @@ -175,7 +175,7 @@ function h$gc(t) { #ifndef GHCJS_BROWSER // fixme, should enable again later when proper CAF management // and retention of the standard handles in GHCJSi work - if(h$isGHCJSi) return; + if(h$isGHCJSi()) return; #endif if(h$currentThread !== null) throw "h$gc: GC can only be run when no thread is running"; ===================================== rts/js/profiling.js ===================================== @@ -27,7 +27,7 @@ var h$registerCC = null, h$registerCCS = null, h$setCCS = null; var h$runProf = function(f) { f(); } -if(h$isNode) { +if(h$isNode()) { (function() { try { var p = require('ghcjs-profiling'); @@ -331,4 +331,4 @@ function h$buildCCSPtr(o) { // run the action with an empty CCS function h$clearCCS(a) { throw new Error("ClearCCSOp not implemented"); -} \ No newline at end of file +} ===================================== rts/js/thread.js ===================================== @@ -812,7 +812,7 @@ function h$reportMainLoopException(e, isMainThread) { var main = isMainThread ? " main" : ""; h$log("uncaught exception in Haskell" + main + " thread: " + e.toString()); if(e.stack) h$log(e.stack); - if (h$isNode) { + if (h$isNode()) { process.exit(1); } } @@ -1112,7 +1112,7 @@ function h$main(a) { //TRACE_SCHEDULER("sched: starting main thread"); t.stack[0] = h$doneMain_e; #ifndef GHCJS_BROWSER - if(!h$isBrowser && !h$isGHCJSi) { + if(!h$isBrowser() && !h$isGHCJSi()) { t.stack[2] = h$baseZCGHCziTopHandlerzitopHandler; } #endif @@ -1131,7 +1131,7 @@ function h$main(a) { function h$doneMain() { #ifndef GHCJS_BROWSER - if(h$isGHCJSi) { + if(h$isGHCJSi()) { if(h$currentThread.stack) { global.h$GHCJSi.done(h$currentThread); } @@ -1156,13 +1156,13 @@ h$ThreadAbortedError.prototype.toString = function() { function h$exitProcess(code) { #ifndef GHCJS_BROWSER - if(h$isNode) { + if(h$isNode()) { process.exit(code); - } else if(h$isJvm) { + } else if(h$isJvm()) { java.lang.System.exit(code); - } else if(h$isJsShell) { + } else if(h$isJsShell()) { quit(code); - } else if(h$isJsCore) { + } else if(h$isJsCore()) { if(h$base_stdoutLeftover.val !== null) print(h$base_stdoutLeftover.val); if(h$base_stderrLeftover.val !== null) debug(h$base_stderrLeftover.val); // jsc does not support returning a nonzero value, print it instead View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42256338080732fd8be10c8c2dfee438826897b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42256338080732fd8be10c8c2dfee438826897b9 You're receiving 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 Oct 10 15:46:24 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 11:46:24 -0400 Subject: [Git][ghc/ghc][wip/T22084] Make SpecConstr bale out less often Message-ID: <63443e50686b_1eea6a529f4f64873541@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22084 at Glasgow Haskell Compiler / GHC Commits: b749bf93 by Simon Peyton Jones at 2022-10-10T16:45:49+01:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 1 changed file: - compiler/GHC/Core/Opt/SpecConstr.hs Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -881,7 +881,7 @@ data SpecConstrOpts = SpecConstrOpts , sc_count :: !(Maybe Int) -- ^ Max # of specialisations for any one function. Nothing => no limit. - -- See Note [Avoiding exponential blowup]. + -- See Note [Avoiding exponential blowup] and decreaseSpecCount , sc_recursive :: !Int -- ^ Max # of specialisations over recursive type. Stops @@ -1098,16 +1098,20 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs decreaseSpecCount :: ScEnv -> Int -> ScEnv -- See Note [Avoiding exponential blowup] -decreaseSpecCount env n_specs +decreaseSpecCount env _n_specs = env { sc_force = False -- See Note [Forcing specialisation] - , sc_opts = (sc_opts env) - { sc_count = case sc_count $ sc_opts env of - Nothing -> Nothing - Just n -> Just $! (n `div` (n_specs + 1)) + , sc_opts = opts { sc_count = case sc_count opts of + Nothing -> Nothing + Just n -> Just $! dec n } } - -- The "+1" takes account of the original function; - -- See Note [Avoiding exponential blowup] + where + opts = sc_opts env + dec n = n `div` 2 -- See Note [Avoiding exponential blowup] + + -- Or: n `div` (n_specs + 1) + -- See the historical note part of Note [Avoiding exponential blowup] + -- The "+1" takes account of the original function; --------------------------------------------------- -- See Note [Forcing specialisation] @@ -1183,9 +1187,20 @@ we can specialise $j2, and similarly $j3. Even if we make just *one* specialisation of each, because we also have the original we'll get 2^n copies of $j3, which is not good. -So when recursively specialising we divide the sc_count by the number of -copies we are making at this level, including the original. - +So when recursively specialising we divide the sc_count (the maximum +number of specialisations, in the ScEnv) by two. You might think that +gives us n*(n/2)*(n/4)... copies of the innnermost thing, which is +still exponential the depth. But we use integer division, rounding +down, so if the starting sc_count is 3, we'll get 3 -> 1 -> 0, and +stop. In fact, simply subtracting 1 would be good enough, for the same +reason. + +Historical note: in the past we divided by (n_specs+1), where n_specs +is the number of specialisations at this level; but that gets us down +to zero jolly quickly, which I found led to some regressions. (An +example is nofib/spectral/fibheaps, the getMin' function inside the +outer function $sfibToList, which has several interesting call +patterns.) ************************************************************************ * * @@ -1794,16 +1809,19 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs , not (null arg_bndrs) -- Only specialise functions , Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it = -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $ - do { (boring_call, new_pats) <- callsToNewPats env fn spec_info arg_occs all_calls + do { (boring_call, pats_discarded, new_pats) + <- callsToNewPats env fn spec_info arg_occs all_calls ; let n_pats = length new_pats --- ; if (not (null new_pats) || isJust mb_unspec) then --- pprTrace "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" --- , text "mb_unspec" <+> ppr (isJust mb_unspec) --- , text "arg_occs" <+> ppr arg_occs --- , text "good pats" <+> ppr new_pats]) $ --- return () --- else return () +-- ; when (not (null new_pats) || isJust mb_unspec) $ +-- pprTraceM "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" +-- , text "boring_call:" <+> ppr boring_call +-- , text "pats_discarded:" <+> ppr pats_discarded +-- , text "old spec_count" <+> ppr spec_count +-- , text "spec count limit" <+> ppr (sc_count (sc_opts env)) +-- , text "mb_unspec" <+> ppr (isJust mb_unspec) +-- , text "arg_occs" <+> ppr arg_occs +-- , text "new_pats" <+> ppr new_pats]) ; let spec_env = decreaseSpecCount env n_pats ; (spec_usgs, new_specs) <- mapAndUnzipM (spec_one spec_env fn arg_bndrs body) @@ -1812,7 +1830,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ; let spec_usg = combineUsages spec_usgs - unspec_rhs_needed = boring_call || isExportedId fn + unspec_rhs_needed = pats_discarded || boring_call || isExportedId fn -- If there were any boring calls among the seeds (= all_calls), then those -- calls will call the un-specialised function. So we should use the seeds @@ -1823,15 +1841,14 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs -> (spec_usg `combineUsage` rhs_usg, Nothing) _ -> (spec_usg, mb_unspec) --- ; pprTrace "specialise return }" --- (vcat [ ppr fn --- , text "boring_call:" <+> ppr boring_call --- , text "new calls:" <+> ppr (scu_calls new_usg)]) $ --- return () +-- ; pprTraceM "specialise return }" $ +-- vcat [ ppr fn +-- , text "unspec_rhs_needed:" <+> ppr unspec_rhs_needed +-- , text "new calls:" <+> ppr (scu_calls new_usg)] - ; return (new_usg, SI { si_specs = new_specs ++ specs - , si_n_specs = spec_count + n_pats - , si_mb_unspec = mb_unspec' }) } + ; return (new_usg, SI { si_specs = new_specs ++ specs + , si_n_specs = spec_count + n_pats + , si_mb_unspec = mb_unspec' }) } | otherwise -- No calls, inactive, or not a function -- Behave as if there was a single, boring call @@ -1874,7 +1891,9 @@ spec_one :: ScEnv spec_one env fn arg_bndrs body (call_pat, rule_number) | CP { cp_qvars = qvars, cp_args = pats, cp_strict_args = cbv_args } <- call_pat - = do { spec_uniq <- getUniqueM + = do { -- pprTraceM "spec_one {" (ppr fn <+> ppr pats) + + ; spec_uniq <- getUniqueM ; let env1 = extendScSubstList (extendScInScope env qvars) (arg_bndrs `zip` pats) (body_env, extra_bndrs) = extendBndrs env1 (dropList pats arg_bndrs) @@ -1900,9 +1919,6 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) -- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env) ; (spec_usg, spec_body) <- scExpr body_env body --- ; pprTrace "done spec_one }" (ppr fn $$ ppr (scu_calls spec_usg)) $ --- return () - -- And build the results ; (qvars', pats') <- generaliseDictPats qvars pats ; let spec_body_ty = exprType spec_body @@ -1946,21 +1962,22 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) fn_name qvars' pats' rule_rhs -- See Note [Transfer activation] - -- ; pprTraceM "spec_one {" (vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) - -- , text "sc_count:" <+> ppr (sc_count env) - -- , text "pats:" <+> ppr pats - -- , text "call_pat:" <+> ppr call_pat - -- , text "-->" <+> ppr spec_name - -- , text "bndrs" <+> ppr arg_bndrs - -- , text "extra_bndrs" <+> ppr extra_bndrs - -- , text "cbv_args" <+> ppr cbv_args - -- , text "spec_lam_args" <+> ppr spec_lam_args - -- , text "spec_call_args" <+> ppr spec_call_args - -- , text "rule_rhs" <+> ppr rule_rhs - -- , text "adds_void_worker_arg" <+> ppr add_void_arg - -- , text "body" <+> ppr body - -- , text "spec_rhs" <+> ppr spec_rhs - -- , text "how_bound" <+> ppr (sc_how_bound env) ]) +-- ; pprTraceM "spec_one end }" $ +-- vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) +-- , text "pats:" <+> ppr pats +-- , text "call_pat:" <+> ppr call_pat +-- , text "-->" <+> ppr spec_name +-- , text "bndrs" <+> ppr arg_bndrs +-- , text "extra_bndrs" <+> ppr extra_bndrs +-- , text "cbv_args" <+> ppr cbv_args +-- , text "spec_lam_args" <+> ppr spec_lam_args +-- , text "spec_call_args" <+> ppr spec_call_args +-- , text "rule_rhs" <+> ppr rule_rhs +-- , text "adds_void_worker_arg" <+> ppr add_void_arg +---- , text "body" <+> ppr body +---- , text "spec_rhs" <+> ppr spec_rhs +---- , text "how_bound" <+> ppr (sc_how_bound env) ] +-- ] ; return (spec_usg, OS { os_pat = call_pat, os_rule = rule , os_id = spec_id , os_rhs = spec_rhs }) } @@ -2330,7 +2347,9 @@ instance Outputable CallPat where callsToNewPats :: ScEnv -> Id -> SpecInfo -> [ArgOcc] -> [Call] - -> UniqSM (Bool, [CallPat]) + -> UniqSM ( Bool -- At least one boring call + , Bool -- Patterns were discarded + , [CallPat] ) -- Patterns to specialise -- Result has no duplicate patterns, -- nor ones mentioned in si_specs (hence "new" patterns) -- Bool indicates that there was at least one boring pattern @@ -2362,12 +2381,11 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Discard specialisations if there are too many of them (pats_were_discarded, trimmed_pats) = trim_pats env fn spec_info small_pats --- ; pprTrace "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls --- , text "done_specs:" <+> ppr (map os_pat done_specs) --- , text "good_pats:" <+> ppr good_pats ]) $ --- return () +-- ; pprTraceM "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls +-- , text "done_specs:" <+> ppr (map os_pat done_specs) +-- , text "trimmed_pats:" <+> ppr trimmed_pats ]) - ; return (have_boring_call || pats_were_discarded, trimmed_pats) } + ; return (have_boring_call, pats_were_discarded, trimmed_pats) } -- If any of the calls does not give rise to a specialisation, either -- because it is boring, or because there are too many specialisations, -- return a flag to say so, so that we know to keep the original function. @@ -2476,29 +2494,29 @@ callToPats env bndr_occs call@(Call fn args con_env) sanitise id = updateIdTypeAndMult expandTypeSynonyms id -- See Note [Free type variables of the qvar types] - -- Bad coercion variables: see Note [SpecConstr and casts] - bad_covars :: CoVarSet + + -- Check for bad coercion variables: see Note [SpecConstr and casts] + ; let bad_covars :: CoVarSet bad_covars = mapUnionVarSet get_bad_covars pats get_bad_covars :: CoreArg -> CoVarSet get_bad_covars (Type ty) = filterVarSet bad_covar (tyCoVarsOfType ty) get_bad_covars _ = emptyVarSet bad_covar v = isId v && not (is_in_scope v) - ; -- pprTrace "callToPats" (ppr args $$ ppr bndr_occs) $ - warnPprTrace (not (isEmptyVarSet bad_covars)) + ; warnPprTrace (not (isEmptyVarSet bad_covars)) "SpecConstr: bad covars" (ppr bad_covars $$ ppr call) $ + if interesting && isEmptyVarSet bad_covars - then do - -- pprTraceM "callToPatsOut" ( - -- text "fn:" <+> ppr fn $$ - -- text "args:" <+> ppr args $$ - -- text "in_scope:" <+> ppr in_scope $$ - -- -- text "in_scope:" <+> ppr in_scope $$ - -- text "pat_fvs:" <+> ppr pat_fvs - -- ) - -- ppr (CP { cp_qvars = qvars', cp_args = pats })) >> - return (Just (CP { cp_qvars = qvars', cp_args = pats, cp_strict_args = concat cbv_ids })) + then do { let cp_res = CP { cp_qvars = qvars', cp_args = pats + , cp_strict_args = concat cbv_ids } +-- ; pprTraceM "callToPatsOut" $ +-- vcat [ text "fn:" <+> ppr fn +-- , text "args:" <+> ppr args +-- , text "bndr_occs:" <+> ppr bndr_occs +-- , text "pat_fvs:" <+> ppr pat_fvs +-- , text "cp_res:" <+> ppr cp_res ] + ; return (Just cp_res) } else return Nothing } -- argToPat takes an actual argument, and returns an abstracted View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b749bf933f5a4ee5c7c26c3f29eba0873fc9a371 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b749bf933f5a4ee5c7c26c3f29eba0873fc9a371 You're receiving 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 Oct 10 16:09:17 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 12:09:17 -0400 Subject: [Git][ghc/ghc][wip/T21470] 13 commits: Boxity: Don't update Boxity unless worker/wrapper follows (#21754) Message-ID: <634443ad3bfee_1eea6a5fada5c0877837@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21470 at Glasgow Haskell Compiler / GHC Commits: f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - e1f618a0 by Simon Peyton Jones at 2022-10-10T17:09:52+01:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 2a05c9bc by Simon Peyton Jones at 2022-10-10T17:10:28+01:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Config/Core/Lint.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Llvm/Types.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Unit/State.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e57eefb80e83061c03e49dd2fd91f29635181625...2a05c9bcb2b65f07b1e0fd58f8ded880fa759e9c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e57eefb80e83061c03e49dd2fd91f29635181625...2a05c9bcb2b65f07b1e0fd58f8ded880fa759e9c You're receiving 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 Oct 10 18:53:40 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 14:53:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Remove mention of make from README.md Message-ID: <63446a3436fc_1eea6a5181c22489572a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - dccbfbf8 by Bodigrim at 2022-10-10T14:53:23-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - e08165be by Vladislav Zavialov at 2022-10-10T14:53:24-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 3 changed files: - README.md - compiler/GHC/Parser/PostProcess.hs - libraries/base/Data/Array/Byte.hs Changes: ===================================== README.md ===================================== @@ -53,19 +53,22 @@ For building library documentation, you'll need [Haddock][6]. To build the compiler documentation, you need [Sphinx](http://www.sphinx-doc.org/) and Xelatex (only for PDF output). -**Quick start**: the following gives you a default build: +**Quick start**: GHC is built using the [Hadrian build system](hadrian/README.md). +The following gives you a default build: $ ./boot $ ./configure - $ make # can also say 'make -jX' for X number of jobs - $ make install + $ hadrian/build # can also say '-jX' for X number of jobs On Windows, you need an extra repository containing some build tools. These can be downloaded for you by configure. This only needs to be done once by running: $ ./configure --enable-tarballs-autodownload -(NB: **Do you have multiple cores? Be sure to tell that to `make`!** This can + Additionally, on Windows, to run Hadrian you should run `hadrian/build.bat` + instead of `hadrian/build`. + +(NB: **Do you have multiple cores? Be sure to tell that to `hadrian`!** This can save you hours of build time depending on your system configuration, and is almost always a win regardless of how many cores you have. As a simple rule, you should have about N+1 jobs, where `N` is the amount of cores you have.) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29ea16516cd914e7d2941763b0e533b8aa6e04d6...e08165be99a93eeed2cff1c71c7dbe48d96db0f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29ea16516cd914e7d2941763b0e533b8aa6e04d6...e08165be99a93eeed2cff1c71c7dbe48d96db0f1 You're receiving 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 Oct 10 21:13:47 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 17:13:47 -0400 Subject: [Git][ghc/ghc][master] Add a newline before since pragma in Data.Array.Byte Message-ID: <63448b0b39cd8_1eea6a529f4f6491854e@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/945e8e491441c1efdab7c0e1bd2e04d0224a4ad5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/945e8e491441c1efdab7c0e1bd2e04d0224a4ad5 You're receiving 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 Oct 10 21:14:24 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 17:14:24 -0400 Subject: [Git][ghc/ghc][master] Parser/PostProcess: rename failOp* functions Message-ID: <63448b3033bd4_1eea6a6375ad889219b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 1 changed file: - compiler/GHC/Parser/PostProcess.hs Changes: ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44fcdb04467c23b794a82451c64cbfaed6f4ef62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44fcdb04467c23b794a82451c64cbfaed6f4ef62 You're receiving 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 Oct 10 21:30:43 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 17:30:43 -0400 Subject: [Git][ghc/ghc][wip/T21851-rule-win] 3 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <63448f0361002_1eea6a5143c92646c@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851-rule-win at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - 14 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Utils/Monad.hs - libraries/base/Data/Array/Byte.hs - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } - - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3668,7 +3714,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -430,3 +430,7 @@ test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c6b51d9deff280b07980905ecc55f79749ea88e...96d32ff289f87b8c78f0a8d1b11295c9563ec020 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c6b51d9deff280b07980905ecc55f79749ea88e...96d32ff289f87b8c78f0a8d1b11295c9563ec020 You're receiving 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 Oct 10 21:33:01 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 17:33:01 -0400 Subject: [Git][ghc/ghc][wip/T22084] 4 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <63448f8d417ed_1eea6a6375ad88927630@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22084 at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - ad0b9687 by Simon Peyton Jones at 2022-10-10T22:32:44+01:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - af740ff6 by Simon Peyton Jones at 2022-10-10T22:32:44+01:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 13 changed files: - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Parser/PostProcess.hs - libraries/base/Data/Array/Byte.hs - + testsuite/tests/simplCore/should_compile/T21148.hs - + testsuite/tests/simplCore/should_compile/T21148.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/T21128.hs - testsuite/tests/stranal/should_compile/T21128.stderr Changes: ===================================== compiler/GHC/Core/Opt/Exitify.hs ===================================== @@ -433,6 +433,7 @@ inlining. Exit join points, recognizable using `isExitJoinId` are join points with an occurrence in a recursive group, and can be recognized (after the occurrence analyzer ran!) using `isExitJoinId`. + This function detects joinpoints with `occ_in_lam (idOccinfo id) == True`, because the lambdas of a non-recursive join point are not considered for `occ_in_lam`. For example, in the following code, `j1` is /not/ marked @@ -446,6 +447,29 @@ To prevent inlining, we check for isExitJoinId * In `simplLetUnfolding` we simply give exit join points no unfolding, which prevents inlining in `postInlineUnconditionally` and call sites. +But see Note [Be selective about not-inlining exit join points] + +Note [Be selective about not-inlining exit join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If we follow "do not inline exit join points" mantra throughout, +some bad things happen. + +* We can lose CPR information: see #21148 + +* We get useless clutter (#22084) that + - makes the program bigger (including duplicated code #20739), and + - adds extra jumps (and maybe stack saves) at runtime + +So instead we follow "do not inline exit join points" for a /single run/ +of the simplifier, right after Exitification. That should give a +sufficient chance for used-once things to inline, but subsequent runs +will inline them back in. (Annoyingly, as things stand, only with -O2 +is there a subsequent run, but that might change, and it's not a huge +deal anyway.) + +This is controlled by the Simplifier's sm_keep_exits flag; see +GHC.Core.Opt.Pipeline. + Note [Placement of the exitification pass] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I (Joachim) experimented with multiple positions for the Exitification pass in ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Driver.Plugins ( withPlugins, installCoreToDos ) import GHC.Driver.Env import GHC.Driver.Config.Core.Lint ( endPass ) import GHC.Driver.Config.Core.Opt.LiberateCase ( initLiberateCaseOpts ) -import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode, initGentleSimplMode ) +import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode ) import GHC.Driver.Config.Core.Opt.WorkWrap ( initWorkWrapOpts ) import GHC.Driver.Config.Core.Rules ( initRuleOpts ) import GHC.Platform.Ways ( hasWay, Way(WayProf) ) @@ -28,6 +28,7 @@ import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.Lint ( lintAnnots ) import GHC.Core.Lint.Interactive ( interactiveInScope ) import GHC.Core.Opt.Simplify ( simplifyExpr, simplifyPgm ) +import GHC.Core.Opt.Simplify.Env( SimplMode(..) ) import GHC.Core.Opt.Simplify.Monad import GHC.Core.Opt.Monad import GHC.Core.Opt.Pipeline.Types @@ -154,32 +155,45 @@ getCoreToDo dflags rule_base extra_vars maybe_strictness_before _ = CoreDoNothing - simpl_phase phase name iter - = CoreDoPasses - $ [ maybe_strictness_before phase - , CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter - (initSimplMode dflags phase name) rule_base - , maybe_rule_check phase ] + ---------------------------- + base_simpl_mode :: SimplMode + base_simpl_mode = initSimplMode dflags - -- Run GHC's internal simplification phase, after all rules have run. - -- See Note [Compiler phases] in GHC.Types.Basic - simplify name = simpl_phase FinalPhase name max_iter - - -- initial simplify: mk specialiser happy: minimum effort please + -- gentle_mode: make specialiser happy: minimum effort please -- See Note [Inline in InitialPhase] -- See Note [RULEs enabled in InitialPhase] - simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter - (initGentleSimplMode dflags) rule_base + gentle_mode = base_simpl_mode { sm_names = ["Gentle"] + , sm_phase = InitialPhase + , sm_case_case = False } + + simpl_mode phase name + = base_simpl_mode { sm_names = [name], sm_phase = phase } + + keep_exits :: SimplMode -> SimplMode + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + keep_exits mode = mode { sm_keep_exits = True } + + ---------------------------- + run_simplifier mode iter + = CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter mode rule_base + simpl_phase phase name iter = CoreDoPasses $ + [ maybe_strictness_before phase + , run_simplifier (simpl_mode phase name) iter + , maybe_rule_check phase ] + + -- Run GHC's internal simplification phase, after all rules have run. + -- See Note [Compiler phases] in GHC.Types.Basic + simpl_gently = run_simplifier gentle_mode max_iter + simplify_final name = run_simplifier ( simpl_mode FinalPhase name) max_iter + simpl_keep_exits name = run_simplifier (keep_exits $ simpl_mode FinalPhase name) max_iter + + ---------------------------- dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] - demand_analyser = (CoreDoPasses ( - dmd_cpr_ww ++ - [simplify "post-worker-wrapper"] - )) - -- Static forms are moved to the top level with the FloatOut pass. -- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable. static_ptrs_float_outwards = @@ -269,14 +283,16 @@ getCoreToDo dflags rule_base extra_vars runWhen call_arity $ CoreDoPasses [ CoreDoCallArity - , simplify "post-call-arity" + , simplify_final "post-call-arity" ], -- Strictness analysis - runWhen strictness demand_analyser, + runWhen strictness $ CoreDoPasses + (dmd_cpr_ww ++ [simplify_final "post-worker-wrapper"]), runWhen exitification CoreDoExitify, -- See Note [Placement of the exitification pass] + -- in GHC.Core.Opt.Exitify runWhen full_laziness $ CoreDoFloatOutwards FloatOutSwitches { @@ -298,7 +314,17 @@ getCoreToDo dflags rule_base extra_vars runWhen do_float_in CoreDoFloatInwards, - simplify "final", -- Final tidy-up + -- Final tidy-up run of the simplifier + simpl_keep_exits "final tidy up", + -- Keep exit join point because this is the first + -- Simplifier run after Exitify. Subsequent runs will + -- re-inline those exit join points; their work is done. + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + -- + -- Annoyingly, we only /have/ a subsequent run with -O2. With + -- plain -O we'll still have those exit join points hanging around. + -- Oh well. maybe_rule_check FinalPhase, @@ -308,31 +334,31 @@ getCoreToDo dflags rule_base extra_vars -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. runWhen liberate_case $ CoreDoPasses - [ CoreLiberateCase, simplify "post-liberate-case" ], + [ CoreLiberateCase, simplify_final "post-liberate-case" ], -- Run the simplifier after LiberateCase to vastly -- reduce the possibility of shadowing -- Reason: see Note [Shadowing] in GHC.Core.Opt.SpecConstr runWhen spec_constr $ CoreDoPasses - [ CoreDoSpecConstr, simplify "post-spec-constr"], + [ CoreDoSpecConstr, simplify_final "post-spec-constr"], -- See Note [Simplify after SpecConstr] maybe_rule_check FinalPhase, runWhen late_specialise $ CoreDoPasses - [ CoreDoSpecialising, simplify "post-late-spec"], + [ CoreDoSpecialising, simplify_final "post-late-spec"], -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this -- in wheel-sieve1), and I'm guessing that SpecConstr can too -- And CSE is a very cheap pass. So it seems worth doing here. runWhen ((liberate_case || spec_constr) && cse) $ CoreDoPasses - [ CoreCSE, simplify "post-final-cse" ], + [ CoreCSE, simplify_final "post-final-cse" ], --------- End of -O2 passes -------------- runWhen late_dmd_anal $ CoreDoPasses ( - dmd_cpr_ww ++ [simplify "post-late-ww"] + dmd_cpr_ww ++ [simplify_final "post-late-ww"] ), -- Final run of the demand_analyser, ensures that one-shot thunks are ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -248,13 +248,16 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad , sm_uf_opts :: !UnfoldingOpts -- ^ Unfolding options , sm_case_case :: !Bool -- ^ Whether case-of-case is enabled , sm_pre_inline :: !Bool -- ^ Whether pre-inlining is enabled - , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out + , sm_keep_exits :: !Bool -- ^ True <=> keep ExitJoinIds + -- See Note [Do not inline exit join points] + -- in GHC.Core.Opt.Exitify + , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out , sm_do_eta_reduction :: !Bool - , sm_arity_opts :: !ArityOpts - , sm_rule_opts :: !RuleOpts - , sm_case_folding :: !Bool - , sm_case_merge :: !Bool - , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options + , sm_arity_opts :: !ArityOpts + , sm_rule_opts :: !RuleOpts + , sm_case_folding :: !Bool + , sm_case_merge :: !Bool + , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options } instance Outputable SimplMode where ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1320,11 +1320,11 @@ preInlineUnconditionally -- Reason: we don't want to inline single uses, or discard dead bindings, -- for unlifted, side-effect-ful bindings preInlineUnconditionally env top_lvl bndr rhs rhs_env - | not pre_inline_unconditionally = Nothing + | not pre_inline = Nothing | not active = Nothing | isTopLevel top_lvl && isDeadEndId bndr = Nothing -- Note [Top-level bottoming Ids] | isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally] - | isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] + | keep_exits, isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] -- in module Exitify | not (one_occ (idOccInfo bndr)) = Nothing | not (isStableUnfolding unf) = Just $! (extend_subst_with rhs) @@ -1334,19 +1334,36 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env , Just inl <- maybeUnfoldingTemplate unf = Just $! (extend_subst_with inl) | otherwise = Nothing where + mode = seMode env + phase = sm_phase mode + keep_exits = sm_keep_exits mode + pre_inline = sm_pre_inline mode + unf = idUnfolding bndr extend_subst_with inl_rhs = extendIdSubst env bndr $! (mkContEx rhs_env inl_rhs) one_occ IAmDead = True -- Happens in ((\x.1) v) + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = NotInsideLam } = isNotTopLevel top_lvl || early_phase + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = IsInsideLam , occ_int_cxt = IsInteresting } = canInlineInLam rhs - one_occ _ = False - pre_inline_unconditionally = sePreInline env - active = isActive (sePhase env) (inlinePragmaActivation inline_prag) + one_occ OneOcc{ occ_n_br = 1 } -- Inline join point that are used once, even inside + | isJoinId bndr = True -- lambdas (which are presumably other join points) + -- E.g. join j x = rhs in + -- joinrec k y = ....j x.... + -- Here j must be an exit for k, and we can safely inline it under the lambda + -- This includes the case where j is nullary: a nullary join point is just the + -- same as an arity-1 one. So we don't look at occ_int_cxt. + -- All of this only applies if keep_exits is False, otherwise the + -- earlier guard on preInlineUnconditionally would have fired + + one_occ _ = False + + active = isActive phase (inlinePragmaActivation inline_prag) -- See Note [pre/postInlineUnconditionally in gentle mode] inline_prag = idInlinePragma bndr @@ -1378,7 +1395,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = sePhase env /= FinalPhase + early_phase = phase /= FinalPhase -- If we don't have this early_phase test, consider -- x = length [1,2,3] -- The full laziness pass carefully floats all the cons cells to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -881,7 +881,7 @@ data SpecConstrOpts = SpecConstrOpts , sc_count :: !(Maybe Int) -- ^ Max # of specialisations for any one function. Nothing => no limit. - -- See Note [Avoiding exponential blowup]. + -- See Note [Avoiding exponential blowup] and decreaseSpecCount , sc_recursive :: !Int -- ^ Max # of specialisations over recursive type. Stops @@ -1098,16 +1098,20 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs decreaseSpecCount :: ScEnv -> Int -> ScEnv -- See Note [Avoiding exponential blowup] -decreaseSpecCount env n_specs +decreaseSpecCount env _n_specs = env { sc_force = False -- See Note [Forcing specialisation] - , sc_opts = (sc_opts env) - { sc_count = case sc_count $ sc_opts env of - Nothing -> Nothing - Just n -> Just $! (n `div` (n_specs + 1)) + , sc_opts = opts { sc_count = case sc_count opts of + Nothing -> Nothing + Just n -> Just $! dec n } } - -- The "+1" takes account of the original function; - -- See Note [Avoiding exponential blowup] + where + opts = sc_opts env + dec n = n `div` 2 -- See Note [Avoiding exponential blowup] + + -- Or: n `div` (n_specs + 1) + -- See the historical note part of Note [Avoiding exponential blowup] + -- The "+1" takes account of the original function; --------------------------------------------------- -- See Note [Forcing specialisation] @@ -1183,9 +1187,20 @@ we can specialise $j2, and similarly $j3. Even if we make just *one* specialisation of each, because we also have the original we'll get 2^n copies of $j3, which is not good. -So when recursively specialising we divide the sc_count by the number of -copies we are making at this level, including the original. - +So when recursively specialising we divide the sc_count (the maximum +number of specialisations, in the ScEnv) by two. You might think that +gives us n*(n/2)*(n/4)... copies of the innnermost thing, which is +still exponential the depth. But we use integer division, rounding +down, so if the starting sc_count is 3, we'll get 3 -> 1 -> 0, and +stop. In fact, simply subtracting 1 would be good enough, for the same +reason. + +Historical note: in the past we divided by (n_specs+1), where n_specs +is the number of specialisations at this level; but that gets us down +to zero jolly quickly, which I found led to some regressions. (An +example is nofib/spectral/fibheaps, the getMin' function inside the +outer function $sfibToList, which has several interesting call +patterns.) ************************************************************************ * * @@ -1512,8 +1527,10 @@ scExpr' env (Case scrut b ty alts) scrut_occ = case con of DataAlt dc -- See Note [Do not specialise evals] | not (single_alt && all deadArgOcc arg_occs) - -> ScrutOcc (unitUFM dc arg_occs) - _ -> UnkOcc + -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + ScrutOcc (unitUFM dc arg_occs) + _ -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + UnkOcc ; return (usg', b_occ `combineOcc` scrut_occ, Alt con bs2 rhs') } @@ -1792,16 +1809,19 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs , not (null arg_bndrs) -- Only specialise functions , Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it = -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $ - do { (boring_call, new_pats) <- callsToNewPats env fn spec_info arg_occs all_calls + do { (boring_call, pats_discarded, new_pats) + <- callsToNewPats env fn spec_info arg_occs all_calls ; let n_pats = length new_pats --- ; if (not (null new_pats) || isJust mb_unspec) then --- pprTrace "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" --- , text "mb_unspec" <+> ppr (isJust mb_unspec) --- , text "arg_occs" <+> ppr arg_occs --- , text "good pats" <+> ppr new_pats]) $ --- return () --- else return () +-- ; when (not (null new_pats) || isJust mb_unspec) $ +-- pprTraceM "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" +-- , text "boring_call:" <+> ppr boring_call +-- , text "pats_discarded:" <+> ppr pats_discarded +-- , text "old spec_count" <+> ppr spec_count +-- , text "spec count limit" <+> ppr (sc_count (sc_opts env)) +-- , text "mb_unspec" <+> ppr (isJust mb_unspec) +-- , text "arg_occs" <+> ppr arg_occs +-- , text "new_pats" <+> ppr new_pats]) ; let spec_env = decreaseSpecCount env n_pats ; (spec_usgs, new_specs) <- mapAndUnzipM (spec_one spec_env fn arg_bndrs body) @@ -1810,7 +1830,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ; let spec_usg = combineUsages spec_usgs - unspec_rhs_needed = boring_call || isExportedId fn + unspec_rhs_needed = pats_discarded || boring_call || isExportedId fn -- If there were any boring calls among the seeds (= all_calls), then those -- calls will call the un-specialised function. So we should use the seeds @@ -1821,15 +1841,14 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs -> (spec_usg `combineUsage` rhs_usg, Nothing) _ -> (spec_usg, mb_unspec) --- ; pprTrace "specialise return }" --- (vcat [ ppr fn --- , text "boring_call:" <+> ppr boring_call --- , text "new calls:" <+> ppr (scu_calls new_usg)]) $ --- return () +-- ; pprTraceM "specialise return }" $ +-- vcat [ ppr fn +-- , text "unspec_rhs_needed:" <+> ppr unspec_rhs_needed +-- , text "new calls:" <+> ppr (scu_calls new_usg)] - ; return (new_usg, SI { si_specs = new_specs ++ specs - , si_n_specs = spec_count + n_pats - , si_mb_unspec = mb_unspec' }) } + ; return (new_usg, SI { si_specs = new_specs ++ specs + , si_n_specs = spec_count + n_pats + , si_mb_unspec = mb_unspec' }) } | otherwise -- No calls, inactive, or not a function -- Behave as if there was a single, boring call @@ -1872,7 +1891,9 @@ spec_one :: ScEnv spec_one env fn arg_bndrs body (call_pat, rule_number) | CP { cp_qvars = qvars, cp_args = pats, cp_strict_args = cbv_args } <- call_pat - = do { spec_uniq <- getUniqueM + = do { -- pprTraceM "spec_one {" (ppr fn <+> ppr pats) + + ; spec_uniq <- getUniqueM ; let env1 = extendScSubstList (extendScInScope env qvars) (arg_bndrs `zip` pats) (body_env, extra_bndrs) = extendBndrs env1 (dropList pats arg_bndrs) @@ -1898,9 +1919,6 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) -- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env) ; (spec_usg, spec_body) <- scExpr body_env body --- ; pprTrace "done spec_one }" (ppr fn $$ ppr (scu_calls spec_usg)) $ --- return () - -- And build the results ; (qvars', pats') <- generaliseDictPats qvars pats ; let spec_body_ty = exprType spec_body @@ -1944,21 +1962,22 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) fn_name qvars' pats' rule_rhs -- See Note [Transfer activation] - -- ; pprTraceM "spec_one {" (vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) - -- , text "sc_count:" <+> ppr (sc_count env) - -- , text "pats:" <+> ppr pats - -- , text "call_pat:" <+> ppr call_pat - -- , text "-->" <+> ppr spec_name - -- , text "bndrs" <+> ppr arg_bndrs - -- , text "extra_bndrs" <+> ppr extra_bndrs - -- , text "cbv_args" <+> ppr cbv_args - -- , text "spec_lam_args" <+> ppr spec_lam_args - -- , text "spec_call_args" <+> ppr spec_call_args - -- , text "rule_rhs" <+> ppr rule_rhs - -- , text "adds_void_worker_arg" <+> ppr add_void_arg - -- , text "body" <+> ppr body - -- , text "spec_rhs" <+> ppr spec_rhs - -- , text "how_bound" <+> ppr (sc_how_bound env) ]) +-- ; pprTraceM "spec_one end }" $ +-- vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) +-- , text "pats:" <+> ppr pats +-- , text "call_pat:" <+> ppr call_pat +-- , text "-->" <+> ppr spec_name +-- , text "bndrs" <+> ppr arg_bndrs +-- , text "extra_bndrs" <+> ppr extra_bndrs +-- , text "cbv_args" <+> ppr cbv_args +-- , text "spec_lam_args" <+> ppr spec_lam_args +-- , text "spec_call_args" <+> ppr spec_call_args +-- , text "rule_rhs" <+> ppr rule_rhs +-- , text "adds_void_worker_arg" <+> ppr add_void_arg +---- , text "body" <+> ppr body +---- , text "spec_rhs" <+> ppr spec_rhs +---- , text "how_bound" <+> ppr (sc_how_bound env) ] +-- ] ; return (spec_usg, OS { os_pat = call_pat, os_rule = rule , os_id = spec_id , os_rhs = spec_rhs }) } @@ -2328,7 +2347,9 @@ instance Outputable CallPat where callsToNewPats :: ScEnv -> Id -> SpecInfo -> [ArgOcc] -> [Call] - -> UniqSM (Bool, [CallPat]) + -> UniqSM ( Bool -- At least one boring call + , Bool -- Patterns were discarded + , [CallPat] ) -- Patterns to specialise -- Result has no duplicate patterns, -- nor ones mentioned in si_specs (hence "new" patterns) -- Bool indicates that there was at least one boring pattern @@ -2360,12 +2381,11 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Discard specialisations if there are too many of them (pats_were_discarded, trimmed_pats) = trim_pats env fn spec_info small_pats --- ; pprTrace "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls --- , text "done_specs:" <+> ppr (map os_pat done_specs) --- , text "good_pats:" <+> ppr good_pats ]) $ --- return () +-- ; pprTraceM "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls +-- , text "done_specs:" <+> ppr (map os_pat done_specs) +-- , text "trimmed_pats:" <+> ppr trimmed_pats ]) - ; return (have_boring_call || pats_were_discarded, trimmed_pats) } + ; return (have_boring_call, pats_were_discarded, trimmed_pats) } -- If any of the calls does not give rise to a specialisation, either -- because it is boring, or because there are too many specialisations, -- return a flag to say so, so that we know to keep the original function. @@ -2474,29 +2494,29 @@ callToPats env bndr_occs call@(Call fn args con_env) sanitise id = updateIdTypeAndMult expandTypeSynonyms id -- See Note [Free type variables of the qvar types] - -- Bad coercion variables: see Note [SpecConstr and casts] - bad_covars :: CoVarSet + + -- Check for bad coercion variables: see Note [SpecConstr and casts] + ; let bad_covars :: CoVarSet bad_covars = mapUnionVarSet get_bad_covars pats get_bad_covars :: CoreArg -> CoVarSet get_bad_covars (Type ty) = filterVarSet bad_covar (tyCoVarsOfType ty) get_bad_covars _ = emptyVarSet bad_covar v = isId v && not (is_in_scope v) - ; -- pprTrace "callToPats" (ppr args $$ ppr bndr_occs) $ - warnPprTrace (not (isEmptyVarSet bad_covars)) + ; warnPprTrace (not (isEmptyVarSet bad_covars)) "SpecConstr: bad covars" (ppr bad_covars $$ ppr call) $ + if interesting && isEmptyVarSet bad_covars - then do - -- pprTraceM "callToPatsOut" ( - -- text "fn:" <+> ppr fn $$ - -- text "args:" <+> ppr args $$ - -- text "in_scope:" <+> ppr in_scope $$ - -- -- text "in_scope:" <+> ppr in_scope $$ - -- text "pat_fvs:" <+> ppr pat_fvs - -- ) - -- ppr (CP { cp_qvars = qvars', cp_args = pats })) >> - return (Just (CP { cp_qvars = qvars', cp_args = pats, cp_strict_args = concat cbv_ids })) + then do { let cp_res = CP { cp_qvars = qvars', cp_args = pats + , cp_strict_args = concat cbv_ids } +-- ; pprTraceM "callToPatsOut" $ +-- vcat [ text "fn:" <+> ppr fn +-- , text "args:" <+> ppr args +-- , text "bndr_occs:" <+> ppr bndr_occs +-- , text "pat_fvs:" <+> ppr pat_fvs +-- , text "cp_res:" <+> ppr cp_res ] + ; return (Just cp_res) } else return Nothing } -- argToPat takes an actual argument, and returns an abstracted ===================================== compiler/GHC/Driver/Config/Core/Opt/Simplify.hs ===================================== @@ -2,7 +2,6 @@ module GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyExprOpts , initSimplifyOpts , initSimplMode - , initGentleSimplMode ) where import GHC.Prelude @@ -27,12 +26,13 @@ import GHC.Types.Var ( Var ) initSimplifyExprOpts :: DynFlags -> InteractiveContext -> SimplifyExprOpts initSimplifyExprOpts dflags ic = SimplifyExprOpts { se_fam_inst = snd $ ic_instances ic - , se_mode = (initSimplMode dflags InitialPhase "GHCi") - { sm_inline = False - -- Do not do any inlining, in case we expose some - -- unboxed tuple stuff that confuses the bytecode + + , se_mode = (initSimplMode dflags) { sm_names = ["GHCi"] + , sm_inline = False } + -- sm_inline: do not do any inlining, in case we expose + -- some unboxed tuple stuff that confuses the bytecode -- interpreter - } + , se_top_env_cfg = TopEnvConfig { te_history_size = historySize dflags , te_tick_factor = simplTickFactor dflags @@ -57,31 +57,25 @@ initSimplifyOpts dflags extra_vars iterations mode rule_base = let } in opts -initSimplMode :: DynFlags -> CompilerPhase -> String -> SimplMode -initSimplMode dflags phase name = SimplMode - { sm_names = [name] - , sm_phase = phase - , sm_rules = gopt Opt_EnableRewriteRules dflags - , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags - , sm_cast_swizzle = True - , sm_inline = True - , sm_uf_opts = unfoldingOpts dflags - , sm_case_case = True - , sm_pre_inline = gopt Opt_SimplPreInlining dflags - , sm_float_enable = floatEnable dflags +initSimplMode :: DynFlags -> SimplMode +initSimplMode dflags = SimplMode + { sm_names = ["Unknown simplifier run"] -- Always overriden + , sm_phase = InitialPhase + , sm_rules = gopt Opt_EnableRewriteRules dflags + , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags + , sm_pre_inline = gopt Opt_SimplPreInlining dflags , sm_do_eta_reduction = gopt Opt_DoEtaReduction dflags - , sm_arity_opts = initArityOpts dflags - , sm_rule_opts = initRuleOpts dflags - , sm_case_folding = gopt Opt_CaseFolding dflags - , sm_case_merge = gopt Opt_CaseMerge dflags - , sm_co_opt_opts = initOptCoercionOpts dflags - } - -initGentleSimplMode :: DynFlags -> SimplMode -initGentleSimplMode dflags = (initSimplMode dflags InitialPhase "Gentle") - { -- Don't do case-of-case transformations. - -- This makes full laziness work better - sm_case_case = False + , sm_uf_opts = unfoldingOpts dflags + , sm_float_enable = floatEnable dflags + , sm_arity_opts = initArityOpts dflags + , sm_rule_opts = initRuleOpts dflags + , sm_case_folding = gopt Opt_CaseFolding dflags + , sm_case_merge = gopt Opt_CaseMerge dflags + , sm_co_opt_opts = initOptCoercionOpts dflags + , sm_cast_swizzle = True + , sm_inline = True + , sm_case_case = True + , sm_keep_exits = False } floatEnable :: DynFlags -> FloatEnable ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) ===================================== testsuite/tests/simplCore/should_compile/T21148.hs ===================================== @@ -0,0 +1,12 @@ +module T211148 where + +-- The point of this test is that f should get a (nested) +-- CPR property, with a worker of type +-- $wf :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +{-# NOINLINE f #-} +-- The NOINLINE makes GHC do a worker/wrapper split +-- even though f is small +f :: Int -> IO Int +f x = return $! sum [0..x] + ===================================== testsuite/tests/simplCore/should_compile/T21148.stderr ===================================== @@ -0,0 +1,126 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 73, types: 80, coercions: 6, joins: 2/2} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T211148.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule3 = GHC.Types.TrNameS T211148.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T211148.$trModule2 = "T211148"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule1 = GHC.Types.TrNameS T211148.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule + = GHC.Types.Module T211148.$trModule3 T211148.$trModule1 + +-- RHS size: {terms: 41, types: 35, coercions: 0, joins: 2/2} +T211148.$wf [InlPrag=NOINLINE] + :: GHC.Prim.Int# + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) +[GblId, Arity=2, Str=, Unf=OtherCon []] +T211148.$wf + = \ (ww_s179 :: GHC.Prim.Int#) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case GHC.Prim.># 0# ww_s179 of { + __DEFAULT -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (x_s16Z [OS=OneShot] :: GHC.Prim.Int#) + (ww1_s172 [OS=OneShot] :: GHC.Prim.Int#) + = (# eta_s17b, GHC.Prim.+# ww1_s172 x_s16Z #) } in + joinrec { + $wgo3_s175 [InlPrag=[2], Occ=LoopBreaker, Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=, Unf=OtherCon []] + $wgo3_s175 (x_s16Z :: GHC.Prim.Int#) (ww1_s172 :: GHC.Prim.Int#) + = case GHC.Prim.==# x_s16Z ww_s179 of { + __DEFAULT -> + jump $wgo3_s175 + (GHC.Prim.+# x_s16Z 1#) (GHC.Prim.+# ww1_s172 x_s16Z); + 1# -> jump exit_X0 x_s16Z ww1_s172 + }; } in + jump $wgo3_s175 0# 0#; + 1# -> (# eta_s17b, 0# #) + } + +-- RHS size: {terms: 14, types: 19, coercions: 0, joins: 0/0} +T211148.f1 [InlPrag=NOINLINE[final]] + :: Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (x_s177 [Occ=Once1!] :: Int) + (eta_s17b [Occ=Once1, OS=OneShot] + :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 [Occ=Once1] -> + case T211148.$wf ww_s179 eta_s17b of + { (# ww1_s17e [Occ=Once1], ww2_s17j [Occ=Once1] #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + }}] +T211148.f1 + = \ (x_s177 :: Int) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 -> + case T211148.$wf ww_s179 eta_s17b of { (# ww1_s17e, ww2_s17j #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + } + +-- RHS size: {terms: 1, types: 0, coercions: 6, joins: 0/0} +f [InlPrag=NOINLINE[final]] :: Int -> IO Int +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +f = T211148.f1 + `cast` (_R %<'Many>_N ->_R Sym (GHC.Types.N:IO[0] _R) + :: (Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) + ~R# (Int -> IO Int)) + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -429,4 +429,5 @@ test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21148', [grep_errmsg(r'Cpr=') ], compile, ['-O -ddump-simpl']) ===================================== testsuite/tests/stranal/should_compile/T21128.hs ===================================== @@ -2,6 +2,10 @@ module T21128 where import T21128a +{- This test originally had some unnecessary reboxing of y +in the hot path of $wtheresCrud. That reboxing should +not happen. -} + theresCrud :: Int -> Int -> Int theresCrud x y = go x where @@ -9,3 +13,4 @@ theresCrud x y = go x go 1 = index x y 1 go n = go (n-1) {-# NOINLINE theresCrud #-} + ===================================== testsuite/tests/stranal/should_compile/T21128.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 137, types: 92, coercions: 4, joins: 0/0} + = {terms: 125, types: 68, coercions: 4, joins: 0/0} lvl = "error"# @@ -29,17 +29,11 @@ lvl9 = SrcLoc lvl2 lvl3 lvl5 lvl6 lvl7 lvl6 lvl8 lvl10 = PushCallStack lvl1 lvl9 EmptyCallStack -$windexError - = \ @a @b ww eta eta1 eta2 -> - error - (lvl10 `cast` :: CallStack ~R# (?callStack::CallStack)) - (++ (ww eta) (++ (ww eta1) (ww eta2))) - indexError = \ @a @b $dShow eta eta1 eta2 -> - case $dShow of { C:Show ww ww1 ww2 -> - $windexError ww1 eta eta1 eta2 - } + error + (lvl10 `cast` :: ...) + (++ (show $dShow eta) (++ (show $dShow eta1) (show $dShow eta2))) $trModule3 = TrNameS $trModule4 @@ -48,8 +42,7 @@ $trModule1 = TrNameS $trModule2 $trModule = Module $trModule3 $trModule1 $wlvl - = \ ww ww1 ww2 -> - $windexError $fShowInt_$cshow (I# ww2) (I# ww1) (I# ww) + = \ ww ww1 ww2 -> indexError $fShowInt (I# ww2) (I# ww1) (I# ww) index = \ l u i -> @@ -73,7 +66,7 @@ index ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 108, types: 47, coercions: 0, joins: 3/4} + = {terms: 108, types: 46, coercions: 0, joins: 3/3} $trModule4 = "main"# @@ -89,35 +82,34 @@ i = I# 1# l = I# 0# -lvl = \ y -> $windexError $fShowInt_$cshow l y l +lvl = \ x ww -> indexError $fShowInt x (I# ww) i -lvl1 = \ ww y -> $windexError $fShowInt_$cshow (I# ww) y i +lvl1 = \ ww -> indexError $fShowInt l (I# ww) l $wtheresCrud = \ ww ww1 -> - let { y = I# ww1 } in join { - lvl2 + exit + = case <# 0# ww1 of { + __DEFAULT -> case lvl1 ww1 of wild { }; + 1# -> 0# + } } in + join { + exit1 = case <=# ww 1# of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> case <# 1# ww1 of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> -# 1# ww } } } in - join { - lvl3 - = case <# 0# ww1 of { - __DEFAULT -> case lvl y of wild { }; - 1# -> 0# - } } in joinrec { $wgo ww2 = case ww2 of wild { __DEFAULT -> jump $wgo (-# wild 1#); - 0# -> jump lvl3; - 1# -> jump lvl2 + 0# -> jump exit; + 1# -> jump exit1 }; } in jump $wgo ww View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b749bf933f5a4ee5c7c26c3f29eba0873fc9a371...af740ff6ebbe2fb378f7cb2d25223a816979d892 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b749bf933f5a4ee5c7c26c3f29eba0873fc9a371...af740ff6ebbe2fb378f7cb2d25223a816979d892 You're receiving 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 Oct 10 21:34:18 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Oct 2022 17:34:18 -0400 Subject: [Git][ghc/ghc][wip/T21470] 4 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <63448fda15c7e_1eea6a5181c224928238@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21470 at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 7f23cfe0 by Simon Peyton Jones at 2022-10-10T22:33:58+01:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 06a937f7 by Simon Peyton Jones at 2022-10-10T22:33:58+01:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 14 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Parser/PostProcess.hs - libraries/base/Data/Array/Byte.hs - testsuite/tests/linters/notes.stdout - testsuite/tests/numeric/should_compile/T19641.stderr - testsuite/tests/simplCore/should_compile/T8331.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -19,7 +19,7 @@ core expression with (hopefully) improved usage information. module GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr, - zapLambdaBndrs + zapLambdaBndrs, scrutBinderSwap_maybe ) where import GHC.Prelude @@ -27,11 +27,12 @@ import GHC.Prelude import GHC.Core import GHC.Core.FVs import GHC.Core.Utils ( exprIsTrivial, isDefaultAlt, isExpandableApp, - stripTicksTopE, mkTicks ) + mkCastMCo, mkTicks ) import GHC.Core.Opt.Arity ( joinRhsArity, isOneShotBndr ) import GHC.Core.Coercion +import GHC.Core.Predicate ( isDictId ) import GHC.Core.Type -import GHC.Core.TyCo.FVs( tyCoVarsOfMCo ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfMCo ) import GHC.Data.Maybe( isJust, orElse ) import GHC.Data.Graph.Directed ( SCC(..), Node(..) @@ -2462,8 +2463,8 @@ data OccEnv -- See Note [The binder-swap substitution] -- If x :-> (y, co) is in the env, - -- then please replace x by (y |> sym mco) - -- Invariant of course: idType x = exprType (y |> sym mco) + -- then please replace x by (y |> mco) + -- Invariant of course: idType x = exprType (y |> mco) , occ_bs_env :: !(VarEnv (OutId, MCoercion)) , occ_bs_rng :: !VarSet -- Vars free in the range of occ_bs_env -- Domain is Global and Local Ids @@ -2669,7 +2670,7 @@ The binder-swap is implemented by the occ_bs_env field of OccEnv. There are two main pieces: * Given case x |> co of b { alts } - we add [x :-> (b, co)] to the occ_bs_env environment; this is + 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 @@ -2737,30 +2738,8 @@ Some tricky corners: (BS5) We have to apply the occ_bs_env substitution uniformly, including to (local) 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. +(BS6) We must be very careful with dictionaries. + See Note [Care with binder-swap on dictionaries] Note [Case of cast] ~~~~~~~~~~~~~~~~~~~ @@ -2770,6 +2749,54 @@ 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 [Care with binder-swap on dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This Note explains why we need isDictId in scrutBinderSwap_maybe. +Consider this tricky example (#21229, #21470): + + class Sing (b :: Bool) where sing :: Bool + instance Sing 'True where sing = True + instance Sing 'False where sing = False + + f :: forall a. Sing a => blah + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a dSing + +Now do a binder-swap on the case-expression: + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (wild |> sym the_co) + +And now substitute `False` for `wild` (since wild=False in the False branch): + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (False |> sym the_co) + +And now we have a problem. The specialiser will specialise (f @a d)a (for all +vtypes a and dictionaries d!!) with the dictionary (False |> sym the_co), using +Note [Specialising polymorphic dictionaries] in GHC.Core.Opt.Specialise. + +The real problem is the binder-swap. It swaps a dictionary variable $dSing +(of kind Constraint) for a term variable wild (of kind Type). And that is +dangerous: a dictionary is a /singleton/ type whereas a general term variable is +not. In this particular example, Bool is most certainly not a singleton type! + +Conclusion: + for a /dictionary variable/ do not perform + the clever cast version of the binder-swap + +Hence the subtle isDictId in scrutBinderSwap_maybe. + Note [Zap case binders in proxy bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the original @@ -2784,8 +2811,87 @@ binding x = cb. See #5028. NB: the OccInfo on /occurrences/ really doesn't matter much; the simplifier doesn't use it. So this is only to satisfy the perhaps-over-picky Lint. +-} + +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 (scrut_var, mco) <- scrutBinderSwap_maybe scrut + , scrut_var /= case_bndr + -- Consider: case x of x { ... } + -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop + = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) + , occ_bs_rng = rng_vars `extendVarSet` case_bndr' + `unionVarSet` tyCoVarsOfMCo mco } + + | otherwise + = env + where + case_bndr' = zapIdOccInfo case_bndr + -- See Note [Zap case binders in proxy bindings] + +scrutBinderSwap_maybe :: OutExpr -> Maybe (OutVar, MCoercion) +-- If (scrutBinderSwap_maybe e = Just (v, mco), then +-- v = e |> mco +-- See Note [Case of cast] +-- See Note [Care with binder-swap on dictionaries] +-- +-- We use this same function in SpecConstr, and Simplify.Iteration, +-- when something binder-swap-like is happening +scrutBinderSwap_maybe (Var v) = Just (v, MRefl) +scrutBinderSwap_maybe (Cast (Var v) co) + | not (isDictId v) = Just (v, MCo (mkSymCo co)) + -- Cast: see Note [Case of cast] + -- isDictId: see Note [Care with binder-swap on dictionaries] + -- The isDictId rejects a Constraint/Constraint binder-swap, perhaps + -- over-conservatively. But I have never seen one, so I'm leaving + -- the code as simple as possible. Losing the binder-swap in a + -- rare case probably has very low impact. +scrutBinderSwap_maybe (Tick _ e) = scrutBinderSwap_maybe e -- Drop ticks +scrutBinderSwap_maybe _ = Nothing + +lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) +-- See Note [The binder-swap substitution] +-- Returns an expression of the same type as Id +lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr + = case lookupVarEnv bs_env bndr of { + Nothing -> (Var bndr, bndr) ; + Just (bndr1, mco) -> + + -- Why do we iterate here? + -- See (BS2) in Note [The binder-swap substitution] + case lookupBndrSwap env bndr1 of + (fun, fun_id) -> (mkCastMCo fun mco, fun_id) } + + +{- Historical note [Proxy let-bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. + Historical Note [no-case-of-case] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We *used* to suppress the binder-swap in case expressions when -fno-case-of-case is on. Old remarks: "This happens in the first simplifier pass, @@ -2844,53 +2950,8 @@ binder-swap in OccAnal: It's fixed by doing the binder-swap in OccAnal because we can do the binder-swap unconditionally and still get occurrence analysis information right. --} -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 (scrut_var, mco) <- get_scrut_var (stripTicksTopE (const True) scrut) - , scrut_var /= case_bndr - -- Consider: case x of x { ... } - -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop - = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) - , occ_bs_rng = rng_vars `extendVarSet` case_bndr' - `unionVarSet` tyCoVarsOfMCo mco } - - | otherwise - = env - where - get_scrut_var :: OutExpr -> Maybe (OutVar, MCoercion) - get_scrut_var (Var v) = Just (v, MRefl) - get_scrut_var (Cast (Var v) co) = Just (v, MCo co) -- See Note [Case of cast] - get_scrut_var _ = Nothing - - case_bndr' = zapIdOccInfo case_bndr - -- See Note [Zap case binders in proxy bindings] -lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) --- See Note [The binder-swap substitution] --- Returns an expression of the same type as Id -lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr - = case lookupVarEnv bs_env bndr of { - Nothing -> (Var bndr, bndr) ; - Just (bndr1, mco) -> - - -- Why do we iterate here? - -- See (BS2) in Note [The binder-swap substitution] - case lookupBndrSwap env bndr1 of - (fun, fun_id) -> (add_cast fun mco, fun_id) } - - where - add_cast fun MRefl = fun - add_cast fun (MCo co) = Cast fun (mkSymCo co) - -- We must switch that 'co' to 'sym co'; - -- see the comment with occ_bs_env - -- No need to test for isReflCo, because 'co' came from - -- a (Cast e co) and hence is unlikely to be Refl - -{- ************************************************************************ * * \subsection[OccurAnal-types]{OccEnv} ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -51,17 +51,6 @@ The simplifier tries to get rid of occurrences of x, in favour of wild, in the hope that there will only be one remaining occurrence of x, namely the scrutinee of the case, and we can inline it. - - This can only work if @wild@ is an unrestricted binder. Indeed, even with the - extended typing rule (in the linter) for case expressions, if - case x of wild % 1 { p -> e} - is well-typed, then - case x of wild % 1 { p -> e[wild\x] } - is only well-typed if @e[wild\x] = e@ (that is, if @wild@ is not used in @e@ - at all). In which case, it is, of course, pointless to do the substitution - anyway. So for a linear binder (and really anything which isn't unrestricted), - doing this substitution would either produce ill-typed terms or be the - identity. -} module GHC.Core.Opt.SetLevels ( @@ -1602,7 +1591,9 @@ extendCaseBndrEnv :: LevelEnv -> LevelEnv extendCaseBndrEnv le@(LE { le_subst = subst, le_env = id_env }) case_bndr (Var scrut_var) - | Many <- varMult case_bndr + -- We could use OccurAnal. scrutBinderSwap_maybe here, and perhaps + -- get a bit more floating. But we didn't in the past and it's + -- an unforced change, so I'm leaving it. = le { le_subst = extendSubstWithVar subst case_bndr scrut_var , le_env = add_id id_env (case_bndr, scrut_var) } extendCaseBndrEnv env _ _ = env ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -71,7 +71,8 @@ import GHC.Core.Make ( mkWildValBinder, mkCoreLet ) import GHC.Builtin.Types import GHC.Core.TyCo.Rep ( TyCoBinder(..) ) import qualified GHC.Core.Type as Type -import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, extendTvSubst, extendCvSubst ) +import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, substCo + , extendTvSubst, extendCvSubst ) import qualified GHC.Core.Coercion as Coercion import GHC.Core.Coercion hiding ( substCo, substCoVar, substCoVarBndr ) import GHC.Platform ( Platform ) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.Opt.Simplify.Env import GHC.Core.Opt.Simplify.Utils -import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs ) +import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutBinderSwap_maybe ) import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr ) import qualified GHC.Core.Make import GHC.Core.Coercion hiding ( substCo, substCoVar ) @@ -3240,19 +3240,21 @@ zapIdOccInfoAndSetEvald str v = -- see Note [Case alternative occ info] addAltUnfoldings :: SimplEnv -> Maybe OutExpr -> OutId -> OutExpr -> SimplM SimplEnv -addAltUnfoldings env scrut case_bndr con_app +addAltUnfoldings env mb_scrut case_bndr con_app = do { let con_app_unf = mk_simple_unf con_app env1 = addBinderUnfolding env case_bndr con_app_unf -- See Note [Add unfolding for scrutinee] - env2 | Many <- idMult case_bndr = case scrut of - Just (Var v) -> addBinderUnfolding env1 v con_app_unf - Just (Cast (Var v) co) -> addBinderUnfolding env1 v $ - mk_simple_unf (Cast con_app (mkSymCo co)) - _ -> env1 + env2 | Just scrut <- mb_scrut + , Just (v,mco) <- scrutBinderSwap_maybe scrut + = addBinderUnfolding env1 v $ + if isReflMCo mco -- isReflMCo: avoid calling mk_simple_unf + then con_app_unf -- twice in the common case + else mk_simple_unf (mkCastMCo con_app mco) + | otherwise = env1 - ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr scrut, ppr con_app]) + ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr mb_scrut, ppr con_app]) ; return env2 } where -- Force the opts, so that the whole SimplEnv isn't retained @@ -3315,9 +3317,6 @@ 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. -Exactly the same issue arises in GHC.Core.Opt.SpecConstr; -see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr - HOWEVER, given case x of y { Just a -> r1; Nothing -> r2 } we do not want to add the unfolding x -> y to 'x', which might seem cool, @@ -3328,8 +3327,11 @@ piece of information. So instead we add the unfolding x -> Just a, and x -> Nothing in the respective RHSs. -Since this transformation is tantamount to a binder swap, the same caveat as in -Note [Suppressing binder-swaps on linear case] in OccurAnal apply. +Since this transformation is tantamount to a binder swap, we use +GHC.Core.Opt.OccurAnal.scrutBinderSwap_maybe to do the check. + +Exactly the same issue arises in GHC.Core.Opt.SpecConstr; +see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Core.Unfold import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils +import GHC.Core.Opt.OccurAnal( scrutBinderSwap_maybe ) import GHC.Core.DataCon import GHC.Core.Class( classTyVars ) import GHC.Core.Coercion hiding( substCo ) @@ -1073,8 +1074,8 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs = (env2, alt_bndrs') where live_case_bndr = not (isDeadBinder case_bndr) - env1 | Var v <- stripTicksTopE (const True) scrut - = extendValEnv env v cval + env1 | Just (v, mco) <- scrutBinderSwap_maybe scrut + , isReflMCo mco = extendValEnv env v cval | otherwise = env -- See Note [Add scrutinee to ValueEnv too] env2 | live_case_bndr = extendValEnv env1 case_bndr cval | otherwise = env1 @@ -1164,6 +1165,10 @@ though the simplifier has systematically replaced uses of 'x' with 'y' and 'b' with 'c' in the code. The use of 'b' in the ValueEnv came from outside the case. See #4908 for the live example. +It's very like the binder-swap story, so we use scrutBinderSwap_maybe +to identify suitable scrutinees -- but only if there is no cast +(isReflMCo) because that's all that the ValueEnv allows. + Note [Avoiding exponential blowup] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The sc_count field of the ScEnv says how many times we are prepared to ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -15,9 +15,7 @@ import GHC.Driver.Config import GHC.Driver.Config.Diagnostic import GHC.Driver.Config.Core.Rules ( initRuleOpts ) -import GHC.Tc.Utils.TcType hiding( substTy ) - -import GHC.Core.Type hiding( substTy, extendTvSubstList, zapSubst ) +import GHC.Core.Type hiding( substTy, substCo, extendTvSubstList, zapSubst ) import GHC.Core.Multiplicity import GHC.Core.Predicate import GHC.Core.Coercion( Coercion ) @@ -25,12 +23,15 @@ import GHC.Core.Opt.Monad import qualified GHC.Core.Subst as Core import GHC.Core.Unfold.Make import GHC.Core +import GHC.Core.Make ( mkLitRubbish ) +import GHC.Core.Unify ( tcMatchTy ) import GHC.Core.Rules import GHC.Core.Utils ( exprIsTrivial , mkCast, exprType , stripTicksTop ) import GHC.Core.FVs -import GHC.Core.TyCo.Rep (TyCoBinder (..)) +import GHC.Core.TyCo.Rep ( TyCoBinder (..) ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfTypeList ) import GHC.Core.Opt.Arity( collectBindersPushingCo ) import GHC.Builtin.Types ( unboxedUnitTy ) @@ -531,6 +532,48 @@ like f :: Eq [(a,b)] => ... +Note [Specialisation and overlapping instances] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Here is at tricky case (see a comment in MR !8916): + + module A where + class C a where + meth :: a -> String + instance {-# OVERLAPPABLE #-} C (Maybe a) where + meth _ = "Maybe" + + {-# SPECIALISE f :: Maybe a -> Bool -> String #-} + f :: C a => a -> Bool -> String + f a True = f a False + f a _ = meth a + + module B where + import A + + instance C (Maybe Int) where + meth _ = "Int" + + main = putStrLn $ f (Just 42 :: Maybe Int) True + +Running main without optimisations yields "Int", the correct answer. +Activating optimisations yields "Maybe" due to a rewrite rule in module +A generated by the SPECIALISE pragma: + + RULE "USPEC f" forall a (d :: C a). f @a d = $sf + +In B we get the call (f @(Maybe Int) (d :: C (Maybe Int))), and +that rewrites to $sf, but that isn't really right. + +Overlapping instances mean that `C (Maybe Int)` is not a singleton +type: there two distinct dictionaries that have this type. And that +spells trouble for specialistion, which really asssumes singleton +types. + +For now, we just accept this problem, but it may bite us one day. +One solution would be to decline to expose any specialisation rules +to an importing module -- but that seems a bit drastic. + + ************************************************************************ * * \subsubsection{The new specialiser} @@ -802,8 +845,12 @@ spec_import top_env callers rb dict_binds cis@(CIS fn _) canSpecImport :: DynFlags -> Id -> Maybe CoreExpr canSpecImport dflags fn + | isDataConWrapId fn + = Nothing -- Don't specialise data-con wrappers, even if they + -- have dict args; there is no benefit. + | CoreUnfolding { uf_tmpl = rhs } <- unf - -- See Note [Specialising imported functions] point (1). + -- CoreUnfolding: see Note [Specialising imported functions] point (1). , isAnyInlinePragma (idInlinePragma fn) -- See Note [Specialising imported functions] point (2). = Just rhs @@ -1506,12 +1553,12 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs | otherwise -- No calls or RHS doesn't fit our preconceptions = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me) - "Missed specialisation opportunity" (ppr fn $$ _trace_doc) $ + "Missed specialisation opportunity for" (ppr fn $$ trace_doc) $ -- Note [Specialisation shape] -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] fn_type = idType fn fn_arity = idArity fn @@ -1575,8 +1622,16 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs else 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_bndrs1 ++ leftover_bndrs) rhs_body - ; let spec_fn_ty1 = exprType spec_rhs1 + ; (rhs_body', rhs_uds) <- specExpr rhs_env2 rhs_body + -- Add the { d1' = dx1; d2' = dx2 } usage stuff + -- to the rhs_uds; see Note [Specialising Calls] + ; let rhs_uds_w_dx = foldr consDictBind rhs_uds dx_binds + spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs + (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx + spec_rhs1 = mkLams spec_rhs_bndrs $ + wrapDictBindsE dumped_dbs rhs_body' + + spec_fn_ty1 = exprType spec_rhs1 -- Maybe add a void arg to the specialised function, -- to avoid unlifted bindings @@ -1610,10 +1665,6 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - -- Add the { d1' = dx1; d2' = dx2 } usage stuff - -- See Note [Specialising Calls] - spec_uds = foldr consDictBind rhs_uds dx_binds - simpl_opts = initSimpleOpts dflags -------------------------------------- @@ -1796,11 +1847,23 @@ in the specialisation: {-# 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: +worker/wrapper, anyway, but it’s easy to do. - 1. We don’t specialise on them. - 2. They come before an argument we do specialise on. +Wrinkles + +* Note 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. + +* If the function has a stable unfolding, specHeader has to come up with + arguments to pass to that stable unfolding, when building the stable + unfolding of the specialised function: this is the last field in specHeader's + big result tuple. The right thing to do is to produce a LitRubbish; it should rapidly disappear. Rather like GHC.Core.Opt.WorkWrap.Utils.mk_absent_let. @@ -2251,11 +2314,11 @@ instance Outputable SpecArg where 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 +specArgFreeIds :: SpecArg -> IdSet +specArgFreeIds (SpecType {}) = emptyVarSet +specArgFreeIds (SpecDict dx) = exprFreeIds dx +specArgFreeIds UnspecType = emptyVarSet +specArgFreeIds UnspecArg = emptyVarSet isSpecDict :: SpecArg -> Bool isSpecDict (SpecDict {}) = True @@ -2325,24 +2388,30 @@ specHeader , [OutBndr] -- Binders for $sf , [DictBind] -- Auxiliary dictionary bindings , [OutExpr] -- Specialised arguments for unfolding - -- Same length as "args for LHS of rule" + -- Same length as "Args for LHS of rule" ) -- 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 +specHeader env (bndr : bndrs) (SpecType ty : args) + = do { let in_scope = Core.getSubstInScope (se_subst env) + qvars = scopedSort $ + filterOut (`elemInScopeSet` in_scope) $ + tyCoVarsOfTypeList ty + (env1, qvars') = substBndrs env qvars + ty' = substTy env1 ty + env2 = extendTvSubstList env1 [(bndr, ty')] + ; (useful, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env2 bndrs args ; pure ( useful - , env'' + , env3 , leftover_bndrs - , rule_bs - , Type t : rule_es - , bs' + , qvars' ++ rule_bs + , Type ty' : rule_es + , qvars' ++ bs' , dx - , Type t : spec_args + , Type ty' : spec_args ) } @@ -2369,6 +2438,7 @@ specHeader env (bndr : bndrs) (UnspecType : args) -- 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) + | not (isDeadBinder bndr) = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) @@ -2385,29 +2455,44 @@ specHeader env (bndr : bndrs) (SpecDict d : 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. +-- Finally, we don't want to specialise on this argument 'i': +-- - It's an UnSpecArg, or +-- - It's a dead dictionary +-- 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) +specHeader env (bndr : bndrs) (_ : args) + -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead = 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 + + ; let bndr_ty = idType bndr' + + -- See Note [Drop dead args from specialisations] + -- C.f. GHC.Core.Opt.WorkWrap.Utils.mk_absent_let + (mb_spec_bndr, spec_arg) + | isDeadBinder bndr + , Just lit_expr <- mkLitRubbish bndr_ty + = (Nothing, lit_expr) + | otherwise + = (Just bndr', varToCoreExpr bndr') + ; 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' + , case mb_spec_bndr of + Just b' -> b' : bs' + Nothing -> bs' , dx - , varToCoreExpr bndr' : spec_args + , spec_arg : spec_args ) } @@ -2533,6 +2618,88 @@ successfully specialise 'f'. So the DictBinds in (ud_binds :: OrdList DictBind) may contain non-dictionary bindings too. + +Note [Specialising polymorphic dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + class M a where { foo :: a -> Int } + + instance M (ST s) where ... + -- dMST :: forall s. M (ST s) + + wimwam :: forall a. M a => a -> Int + wimwam = /\a \(d::M a). body + + f :: ST s -> Int + f = /\s \(x::ST s). wimwam @(ST s) (dMST @s) dx + 1 + +We'd like to specialise wimwam at (ST s), thus + $swimwam :: forall s. ST s -> Int + $swimwam = /\s. body[ST s/a, (dMST @s)/d] + + RULE forall s (d :: M (ST s)). + wimwam @(ST s) d = $swimwam @s + +Here are the moving parts: + +* We must /not/ dump the CallInfo + CIS wimwam (CI { ci_key = [@(ST s), dMST @s] + , ci_fvs = {dMST} }) + when we come to the /\s. Instead, we simply let it continue to float + upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that + are free in the call, but not the /TyVars/. Hence using specArgFreeIds + in singleCall. + + NB to be fully kosher we should explicitly quantifying the CallInfo + over 's', but we don't bother. This would matter if there was an + enclosing binding of the same 's', which I don't expect to happen. + +* Whe we come to specialise the call, we must remember to quantify + over 's'. That is done in the SpecType case of specHeader, where + we add 's' (called qvars) to the binders of the RULE and the specialised + function. + +* If we have f :: forall m. Monoid m => blah, and two calls + (f @(Endo b) (d :: Monoid (Endo b)) + (f @(Endo (c->c)) (d :: Monoid (Endo (c->c))) + we want to generate a specialisation only for the first. The second + is just a substitution instance of the first, with no greater specialisation. + Hence the call to `remove_dups` in `filterCalls`. + +All this arose in #13873, in the unexpected form that a SPECIALISE +pragma made the program slower! The reason was that the specialised +function $sinsertWith arising from the pragma looked rather like `f` +above, and failed to specialise a call in its body like wimwam. +Without the pragma, the original call to `insertWith` was completely +monomorpic, and specialised in one go. + +Wrinkles. + +* With -XOverlappingInstances you might worry about this: + class C a where ... + instance C (Maybe Int) where ... -- $df1 :: C (Maybe Int) + instance C (Maybe a) where ... -- $df2 :: forall a. C (Maybe a) + + f :: C a => blah + f = rhs + + g = /\a. ...(f @(Maybe a) ($df2 a))... + h = ...f @(Maybe Int) $df1 + + There are two calls to f, but with different evidence. This patch will + combine them into one. But it's OK: this code will never arise unless you + use -XIncoherentInstances. Even with -XOverlappingInstances, GHC tries hard + to keep dictionaries as singleton types. But that goes out of the window + with -XIncoherentInstances -- and that is true even with ordianry type-class + specialisation (at least if any inlining has taken place). + + GHC makes very few guarantees when you use -XIncoherentInstances, and its + not worth crippling the normal case for the incoherent corner. (The best + thing might be to switch off specialisation altogether if incoherence is + involved... but incoherence is a property of an instance, not a class, so + it's a hard test to make.) + + But see Note [Specialisation and overlapping instances]. -} instance Outputable DictBind where @@ -2571,8 +2738,9 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments , ci_fvs :: IdSet -- Free Ids of the ci_key call - -- _not_ including the main id itself, of course + -- /not/ including the main id itself, of course -- NB: excluding tyvars: + -- See Note [Specialising polymorphic dictionaries] } type DictExpr = CoreExpr @@ -2621,7 +2789,7 @@ singleCall id args unitBag (CI { ci_key = args -- used to be tys , ci_fvs = call_fvs }) } where - call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args + call_fvs = foldr (unionVarSet . specArgFreeIds) 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 @@ -2951,15 +3119,15 @@ callsForMe fn uds at MkUD { ud_binds = orig_dbs, ud_calls = orig_calls } ---------------------- filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo] --- Remove dominated calls +-- Remove dominated calls (Note [Specialising polymorphic dictionaries]) -- and loopy DFuns (Note [Avoiding loops (DFuns)]) filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) | isDFunId fn -- Note [Avoiding loops (DFuns)] applies only to DFuns - = filter ok_call unfiltered_calls + = filter ok_call de_dupd_calls | otherwise -- Do not apply it to non-DFuns - = unfiltered_calls -- See Note [Avoiding loops (non-DFuns)] + = de_dupd_calls -- See Note [Avoiding loops (non-DFuns)] where - unfiltered_calls = bagToList call_bag + de_dupd_calls = remove_dups call_bag dump_set = foldl' go (unitVarSet fn) dbs -- This dump-set could also be computed by splitDictBinds @@ -2973,6 +3141,29 @@ filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set +remove_dups :: Bag CallInfo -> [CallInfo] +remove_dups calls = foldr add [] calls + where + add :: CallInfo -> [CallInfo] -> [CallInfo] + add ci [] = [ci] + add ci1 (ci2:cis) | ci2 `beats_or_same` ci1 = ci2:cis + | ci1 `beats_or_same` ci2 = ci1:cis + | otherwise = ci2 : add ci1 cis + +beats_or_same :: CallInfo -> CallInfo -> Bool +beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 }) + = go args1 args2 + where + go [] _ = True + go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2 + go (_:_) [] = False + + go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2) + go_arg UnspecType UnspecType = True + go_arg (SpecDict {}) (SpecDict {}) = True + go_arg UnspecArg UnspecArg = True + go_arg _ _ = False + ---------------------- splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet) -- splitDictBinds dbs bndrs returns @@ -3003,15 +3194,18 @@ splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set ---------------------- deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails --- Remove calls *mentioning* bs in any way -deleteCallsMentioning bs calls +-- Remove calls mentioning any Id in bndrs +-- NB: The call is allowed to mention TyVars in bndrs +-- Note [Specialising polymorphic dictionaries] +-- ci_fvs are just the free /Ids/ +deleteCallsMentioning bndrs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs deleteCallsFor :: [Id] -> CallDetails -> CallDetails --- Remove calls *for* bs -deleteCallsFor bs calls = delDVarEnvList calls bs +-- Remove calls *for* bndrs +deleteCallsFor bndrs calls = delDVarEnvList calls bndrs {- ************************************************************************ ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -26,7 +26,8 @@ module GHC.Core.Subst ( extendIdSubstWithClone, extendSubst, extendSubstList, extendSubstWithVar, extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, - isInScope, setInScope, extendTvSubst, extendCvSubst, + isInScope, setInScope, getSubstInScope, + extendTvSubst, extendCvSubst, delBndr, delBndrs, zapSubst, -- ** Substituting and cloning binders @@ -41,7 +42,6 @@ import GHC.Core import GHC.Core.FVs import GHC.Core.Seq import GHC.Core.Utils -import GHC.Core.TyCo.Subst ( substCo ) -- We are defining local versions import GHC.Core.Type hiding ( substTy ) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -219,7 +219,7 @@ module GHC.Core.Type ( substTyAddInScope, substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked, substThetaUnchecked, substTyWithUnchecked, - substCoUnchecked, substCoWithUnchecked, + substCo, substCoUnchecked, substCoWithUnchecked, substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars, substVarBndr, substVarBndrs, substTyCoBndr, ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) ===================================== testsuite/tests/linters/notes.stdout ===================================== @@ -2,7 +2,6 @@ ref compiler/GHC/Core/Coercion/Axiom.hs:461:2: Note [RoughMap and rm_empt ref compiler/GHC/Core/Opt/OccurAnal.hs:857:15: Note [Loop breaking] ref compiler/GHC/Core/Opt/SetLevels.hs:1580:30: Note [Top level scope] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:2675:13: Note [Case binder next] -ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3303:0: Note [Suppressing binder-swaps on linear case] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3854:8: Note [Lambda-bound unfoldings] ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1257:37: Note [Gentle mode] ref compiler/GHC/Core/Opt/Specialise.hs:1623:28: Note [Arity decrease] ===================================== testsuite/tests/numeric/should_compile/T19641.stderr ===================================== @@ -3,30 +3,30 @@ Result size of Tidy Core = {terms: 22, types: 20, coercions: 0, joins: 0/0} -integer_to_int +natural_to_word = \ eta -> case eta of { - IS ipv -> Just (I# ipv); - IP x1 -> Nothing; - IN ds -> Nothing + NS x1 -> Just (W# x1); + NB ds -> Nothing } -natural_to_word +integer_to_int = \ eta -> case eta of { - NS x1 -> Just (W# x1); - NB ds -> Nothing + IS ipv -> Just (I# ipv); + IP x1 -> Nothing; + IN ds -> Nothing } ------ Local rules for imported ids -------- -"SPEC/Test toIntegralSized @Natural @Word" - forall $dIntegral $dIntegral1 $dBits $dBits1. - toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 - = natural_to_word "SPEC/Test toIntegralSized @Integer @Int" forall $dIntegral $dIntegral1 $dBits $dBits1. toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 = integer_to_int +"SPEC/Test toIntegralSized @Natural @Word" + forall $dIntegral $dIntegral1 $dBits $dBits1. + toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 + = natural_to_word ===================================== testsuite/tests/simplCore/should_compile/T8331.stderr ===================================== @@ -1,5 +1,60 @@ ==================== Tidy Core rules ==================== +"SPEC $c*> @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$c*> @(ST s) @r $dApplicative + = ($fApplicativeReaderT3 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s b) + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) b)) +"SPEC $c>> @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT1 @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$c>> @s @r +"SPEC $cliftA2 @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cliftA2 @(ST s) @r $dApplicative + = ($fApplicativeReaderT1 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N) (c :: <*>_N). + b -> c>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s c) + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) c)) +"SPEC $cp1Applicative @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cp1Applicative @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $cp1Monad @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT_$cp1Monad @(ST s) @r $dMonad + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $fApplicativeReaderT @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $fFunctorReaderT @(ST s) @_" + forall (@s) (@r) ($dFunctor :: Functor (ST s)). + $fFunctorReaderT @(ST s) @r $dFunctor + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $fMonadReaderT @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$fMonadReaderT @s @r "USPEC useAbstractMonad @(ReaderT Int (ST s))" forall (@s) ($dMonadAbstractIOST :: MonadAbstractIOST (ReaderT Int (ST s))). ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -359,7 +359,6 @@ test('T19586', normal, compile, ['']) test('T19599', normal, compile, ['-O -ddump-rules']) test('T19599a', normal, compile, ['-O -ddump-rules']) -test('T13873', [expect_broken(21229), grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) # Look for a specialisation rule for wimwam test('T19672', normal, compile, ['-O2 -ddump-rules']) @@ -429,4 +428,4 @@ test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) - +test('T13873', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a05c9bcb2b65f07b1e0fd58f8ded880fa759e9c...06a937f784301f9522f20cc1a2d3c821e7f3175b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a05c9bcb2b65f07b1e0fd58f8ded880fa759e9c...06a937f784301f9522f20cc1a2d3c821e7f3175b You're receiving 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 Oct 11 00:15:55 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 20:15:55 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <6344b5bb28a79_1eea6a5fada5c09404e9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - f6085913 by Joachim Breitner at 2022-10-10T20:15:31-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 15 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - libraries/base/Data/Array/Byte.hs - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } - - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3668,7 +3714,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -96,8 +96,8 @@ module GHC.Parser.PostProcess ( warnStarIsType, warnPrepositiveQualifiedModule, failOpFewArgs, - failOpNotEnabledImportQualifiedPost, - failOpImportQualifiedTwice, + failNotEnabledImportQualifiedPost, + failImportQualifiedTwice, SumOrTuple (..), @@ -1133,13 +1133,13 @@ checkImportDecl mPre mPost = do -- 'ImportQualifiedPost' is not in effect. whenJust mPost $ \post -> when (not importQualifiedPostEnabled) $ - failOpNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failNotEnabledImportQualifiedPost (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Error if 'qualified' occurs in both pre and postpositive -- positions. whenJust mPost $ \post -> when (isJust mPre) $ - failOpImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) + failImportQualifiedTwice (RealSrcSpan (epaLocationRealSrcSpan post) Strict.Nothing) -- Warn if 'qualified' found in prepositive position and -- 'Opt_WarnPrepositiveQualifiedModule' is enabled. @@ -2873,12 +2873,12 @@ warnPrepositiveQualifiedModule :: SrcSpan -> P () warnPrepositiveQualifiedModule span = addPsMessage span PsWarnImportPreQualified -failOpNotEnabledImportQualifiedPost :: SrcSpan -> P () -failOpNotEnabledImportQualifiedPost loc = +failNotEnabledImportQualifiedPost :: SrcSpan -> P () +failNotEnabledImportQualifiedPost loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportPostQualified -failOpImportQualifiedTwice :: SrcSpan -> P () -failOpImportQualifiedTwice loc = +failImportQualifiedTwice :: SrcSpan -> P () +failImportQualifiedTwice loc = addError $ mkPlainErrorMsgEnvelope loc $ PsErrImportQualifiedTwice warnStarIsType :: SrcSpan -> P () ===================================== compiler/GHC/Utils/Json.hs ===================================== @@ -14,6 +14,7 @@ data JsonDoc where JSBool :: Bool -> JsonDoc JSInt :: Int -> JsonDoc JSString :: String -> JsonDoc + -- ^ The 'String' is unescaped JSArray :: [JsonDoc] -> JsonDoc JSObject :: [(String, JsonDoc)] -> JsonDoc @@ -57,7 +58,7 @@ class ToJson a where json :: a -> JsonDoc instance ToJson String where - json = JSString . escapeJsonString + json = JSString instance ToJson Int where json = JSInt ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -205,6 +205,7 @@ instance Eq (MutableByteArray s) where -- | Non-lexicographic ordering. This compares the lengths of -- the byte arrays first and uses a lexicographic ordering if -- the lengths are equal. Subject to change between major versions. +-- -- @since 4.17.0.0 instance Ord ByteArray where ba1@(ByteArray ba1#) `compare` ba2@(ByteArray ba2#) ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -430,3 +430,7 @@ test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e08165be99a93eeed2cff1c71c7dbe48d96db0f1...f6085913ec38ecead100fbe186ae77291fb8e4db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e08165be99a93eeed2cff1c71c7dbe48d96db0f1...f6085913ec38ecead100fbe186ae77291fb8e4db You're receiving 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 Oct 11 00:32:44 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 10 Oct 2022 20:32:44 -0400 Subject: [Git][ghc/ghc][wip/T22077] 139 commits: Fix arityType: -fpedantic-bottoms, join points, etc Message-ID: <6344b9ac32c5a_1eea6a5face52c94619@gitlab.mail> Ben Gamari pushed to branch wip/T22077 at Glasgow Haskell Compiler / GHC Commits: a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 8c430540 by Ben Gamari at 2022-10-10T20:31:21-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - a1e01a32 by Ben Gamari at 2022-10-10T20:31:22-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - 84612d1e by Ben Gamari at 2022-10-10T20:31:22-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - fb6c2dd2 by Ben Gamari at 2022-10-10T20:31:22-04:00 rts: Refactor IPE tracing support - - - - - 4112e3ca by Ben Gamari at 2022-10-10T20:32:37-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 806223ba by Ben Gamari at 2022-10-10T20:32:37-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 30 changed files: - − .appveyor.sh - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Liveness.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Reg.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/Switch.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f932de0a2e9734bcac44c6d1eab0274dfba9d55a...806223ba7431ffe63ac30ec2305a26d34c3f55a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f932de0a2e9734bcac44c6d1eab0274dfba9d55a...806223ba7431ffe63ac30ec2305a26d34c3f55a1 You're receiving 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 Oct 11 03:15:57 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 23:15:57 -0400 Subject: [Git][ghc/ghc][master] Make rewrite rules "win" over inlining Message-ID: <6344dfed67e52_1eea6a529f4f8c9672e2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - 12 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Utils/Monad.hs - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } - - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3668,7 +3714,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -430,3 +430,7 @@ test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96d32ff289f87b8c78f0a8d1b11295c9563ec020 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96d32ff289f87b8c78f0a8d1b11295c9563ec020 You're receiving 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 Oct 11 03:16:33 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 10 Oct 2022 23:16:33 -0400 Subject: [Git][ghc/ghc][master] Utils.JSON: do not escapeJsonString in ToJson String instance Message-ID: <6344e0114c2ea_1eea6a6375ad889695a9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 1 changed file: - compiler/GHC/Utils/Json.hs Changes: ===================================== compiler/GHC/Utils/Json.hs ===================================== @@ -14,6 +14,7 @@ data JsonDoc where JSBool :: Bool -> JsonDoc JSInt :: Int -> JsonDoc JSString :: String -> JsonDoc + -- ^ The 'String' is unescaped JSArray :: [JsonDoc] -> JsonDoc JSObject :: [(String, JsonDoc)] -> JsonDoc @@ -57,7 +58,7 @@ class ToJson a where json :: a -> JsonDoc instance ToJson String where - json = JSString . escapeJsonString + json = JSString instance ToJson Int where json = JSInt View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed4b5885bdac7b986655bb40f8c9ece2f8735c98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed4b5885bdac7b986655bb40f8c9ece2f8735c98 You're receiving 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 Oct 11 07:40:39 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 03:40:39 -0400 Subject: [Git][ghc/ghc][wip/T22084] 4 commits: Make rewrite rules "win" over inlining Message-ID: <63451df7da2dd_1eea6a529f4f8c10007d1@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22084 at Glasgow Haskell Compiler / GHC Commits: 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 2fb056d7 by Simon Peyton Jones at 2022-10-11T08:42:27+01:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - e4cac1b8 by Simon Peyton Jones at 2022-10-11T08:42:27+01:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 22 changed files: - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21148.hs - + testsuite/tests/simplCore/should_compile/T21148.stderr - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/T21128.hs - testsuite/tests/stranal/should_compile/T21128.stderr Changes: ===================================== compiler/GHC/Core/Opt/Exitify.hs ===================================== @@ -433,6 +433,7 @@ inlining. Exit join points, recognizable using `isExitJoinId` are join points with an occurrence in a recursive group, and can be recognized (after the occurrence analyzer ran!) using `isExitJoinId`. + This function detects joinpoints with `occ_in_lam (idOccinfo id) == True`, because the lambdas of a non-recursive join point are not considered for `occ_in_lam`. For example, in the following code, `j1` is /not/ marked @@ -446,6 +447,29 @@ To prevent inlining, we check for isExitJoinId * In `simplLetUnfolding` we simply give exit join points no unfolding, which prevents inlining in `postInlineUnconditionally` and call sites. +But see Note [Be selective about not-inlining exit join points] + +Note [Be selective about not-inlining exit join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If we follow "do not inline exit join points" mantra throughout, +some bad things happen. + +* We can lose CPR information: see #21148 + +* We get useless clutter (#22084) that + - makes the program bigger (including duplicated code #20739), and + - adds extra jumps (and maybe stack saves) at runtime + +So instead we follow "do not inline exit join points" for a /single run/ +of the simplifier, right after Exitification. That should give a +sufficient chance for used-once things to inline, but subsequent runs +will inline them back in. (Annoyingly, as things stand, only with -O2 +is there a subsequent run, but that might change, and it's not a huge +deal anyway.) + +This is controlled by the Simplifier's sm_keep_exits flag; see +GHC.Core.Opt.Pipeline. + Note [Placement of the exitification pass] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I (Joachim) experimented with multiple positions for the Exitification pass in ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Driver.Plugins ( withPlugins, installCoreToDos ) import GHC.Driver.Env import GHC.Driver.Config.Core.Lint ( endPass ) import GHC.Driver.Config.Core.Opt.LiberateCase ( initLiberateCaseOpts ) -import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode, initGentleSimplMode ) +import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode ) import GHC.Driver.Config.Core.Opt.WorkWrap ( initWorkWrapOpts ) import GHC.Driver.Config.Core.Rules ( initRuleOpts ) import GHC.Platform.Ways ( hasWay, Way(WayProf) ) @@ -28,6 +28,7 @@ import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.Lint ( lintAnnots ) import GHC.Core.Lint.Interactive ( interactiveInScope ) import GHC.Core.Opt.Simplify ( simplifyExpr, simplifyPgm ) +import GHC.Core.Opt.Simplify.Env( SimplMode(..) ) import GHC.Core.Opt.Simplify.Monad import GHC.Core.Opt.Monad import GHC.Core.Opt.Pipeline.Types @@ -154,32 +155,45 @@ getCoreToDo dflags rule_base extra_vars maybe_strictness_before _ = CoreDoNothing - simpl_phase phase name iter - = CoreDoPasses - $ [ maybe_strictness_before phase - , CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter - (initSimplMode dflags phase name) rule_base - , maybe_rule_check phase ] + ---------------------------- + base_simpl_mode :: SimplMode + base_simpl_mode = initSimplMode dflags - -- Run GHC's internal simplification phase, after all rules have run. - -- See Note [Compiler phases] in GHC.Types.Basic - simplify name = simpl_phase FinalPhase name max_iter - - -- initial simplify: mk specialiser happy: minimum effort please + -- gentle_mode: make specialiser happy: minimum effort please -- See Note [Inline in InitialPhase] -- See Note [RULEs enabled in InitialPhase] - simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter - (initGentleSimplMode dflags) rule_base + gentle_mode = base_simpl_mode { sm_names = ["Gentle"] + , sm_phase = InitialPhase + , sm_case_case = False } + + simpl_mode phase name + = base_simpl_mode { sm_names = [name], sm_phase = phase } + + keep_exits :: SimplMode -> SimplMode + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + keep_exits mode = mode { sm_keep_exits = True } + + ---------------------------- + run_simplifier mode iter + = CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter mode rule_base + simpl_phase phase name iter = CoreDoPasses $ + [ maybe_strictness_before phase + , run_simplifier (simpl_mode phase name) iter + , maybe_rule_check phase ] + + -- Run GHC's internal simplification phase, after all rules have run. + -- See Note [Compiler phases] in GHC.Types.Basic + simpl_gently = run_simplifier gentle_mode max_iter + simplify_final name = run_simplifier ( simpl_mode FinalPhase name) max_iter + simpl_keep_exits name = run_simplifier (keep_exits $ simpl_mode FinalPhase name) max_iter + + ---------------------------- dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] - demand_analyser = (CoreDoPasses ( - dmd_cpr_ww ++ - [simplify "post-worker-wrapper"] - )) - -- Static forms are moved to the top level with the FloatOut pass. -- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable. static_ptrs_float_outwards = @@ -269,14 +283,16 @@ getCoreToDo dflags rule_base extra_vars runWhen call_arity $ CoreDoPasses [ CoreDoCallArity - , simplify "post-call-arity" + , simplify_final "post-call-arity" ], -- Strictness analysis - runWhen strictness demand_analyser, + runWhen strictness $ CoreDoPasses + (dmd_cpr_ww ++ [simplify_final "post-worker-wrapper"]), runWhen exitification CoreDoExitify, -- See Note [Placement of the exitification pass] + -- in GHC.Core.Opt.Exitify runWhen full_laziness $ CoreDoFloatOutwards FloatOutSwitches { @@ -298,7 +314,17 @@ getCoreToDo dflags rule_base extra_vars runWhen do_float_in CoreDoFloatInwards, - simplify "final", -- Final tidy-up + -- Final tidy-up run of the simplifier + simpl_keep_exits "final tidy up", + -- Keep exit join point because this is the first + -- Simplifier run after Exitify. Subsequent runs will + -- re-inline those exit join points; their work is done. + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + -- + -- Annoyingly, we only /have/ a subsequent run with -O2. With + -- plain -O we'll still have those exit join points hanging around. + -- Oh well. maybe_rule_check FinalPhase, @@ -308,31 +334,31 @@ getCoreToDo dflags rule_base extra_vars -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. runWhen liberate_case $ CoreDoPasses - [ CoreLiberateCase, simplify "post-liberate-case" ], + [ CoreLiberateCase, simplify_final "post-liberate-case" ], -- Run the simplifier after LiberateCase to vastly -- reduce the possibility of shadowing -- Reason: see Note [Shadowing] in GHC.Core.Opt.SpecConstr runWhen spec_constr $ CoreDoPasses - [ CoreDoSpecConstr, simplify "post-spec-constr"], + [ CoreDoSpecConstr, simplify_final "post-spec-constr"], -- See Note [Simplify after SpecConstr] maybe_rule_check FinalPhase, runWhen late_specialise $ CoreDoPasses - [ CoreDoSpecialising, simplify "post-late-spec"], + [ CoreDoSpecialising, simplify_final "post-late-spec"], -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this -- in wheel-sieve1), and I'm guessing that SpecConstr can too -- And CSE is a very cheap pass. So it seems worth doing here. runWhen ((liberate_case || spec_constr) && cse) $ CoreDoPasses - [ CoreCSE, simplify "post-final-cse" ], + [ CoreCSE, simplify_final "post-final-cse" ], --------- End of -O2 passes -------------- runWhen late_dmd_anal $ CoreDoPasses ( - dmd_cpr_ww ++ [simplify "post-late-ww"] + dmd_cpr_ww ++ [simplify_final "post-late-ww"] ), -- Final run of the demand_analyser, ensures that one-shot thunks are ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -248,13 +248,16 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad , sm_uf_opts :: !UnfoldingOpts -- ^ Unfolding options , sm_case_case :: !Bool -- ^ Whether case-of-case is enabled , sm_pre_inline :: !Bool -- ^ Whether pre-inlining is enabled - , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out + , sm_keep_exits :: !Bool -- ^ True <=> keep ExitJoinIds + -- See Note [Do not inline exit join points] + -- in GHC.Core.Opt.Exitify + , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out , sm_do_eta_reduction :: !Bool - , sm_arity_opts :: !ArityOpts - , sm_rule_opts :: !RuleOpts - , sm_case_folding :: !Bool - , sm_case_merge :: !Bool - , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options + , sm_arity_opts :: !ArityOpts + , sm_rule_opts :: !RuleOpts + , sm_case_folding :: !Bool + , sm_case_merge :: !Bool + , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options } instance Outputable SimplMode where ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } - - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3668,7 +3714,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1320,11 +1333,11 @@ preInlineUnconditionally -- Reason: we don't want to inline single uses, or discard dead bindings, -- for unlifted, side-effect-ful bindings preInlineUnconditionally env top_lvl bndr rhs rhs_env - | not pre_inline_unconditionally = Nothing + | not pre_inline = Nothing | not active = Nothing | isTopLevel top_lvl && isDeadEndId bndr = Nothing -- Note [Top-level bottoming Ids] | isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally] - | isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] + | keep_exits, isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] -- in module Exitify | not (one_occ (idOccInfo bndr)) = Nothing | not (isStableUnfolding unf) = Just $! (extend_subst_with rhs) @@ -1334,19 +1347,36 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env , Just inl <- maybeUnfoldingTemplate unf = Just $! (extend_subst_with inl) | otherwise = Nothing where + mode = seMode env + phase = sm_phase mode + keep_exits = sm_keep_exits mode + pre_inline = sm_pre_inline mode + unf = idUnfolding bndr extend_subst_with inl_rhs = extendIdSubst env bndr $! (mkContEx rhs_env inl_rhs) one_occ IAmDead = True -- Happens in ((\x.1) v) + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = NotInsideLam } = isNotTopLevel top_lvl || early_phase + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = IsInsideLam , occ_int_cxt = IsInteresting } = canInlineInLam rhs - one_occ _ = False - pre_inline_unconditionally = sePreInline env - active = isActive (sePhase env) (inlinePragmaActivation inline_prag) + one_occ OneOcc{ occ_n_br = 1 } -- Inline join point that are used once, even inside + | isJoinId bndr = True -- lambdas (which are presumably other join points) + -- E.g. join j x = rhs in + -- joinrec k y = ....j x.... + -- Here j must be an exit for k, and we can safely inline it under the lambda + -- This includes the case where j is nullary: a nullary join point is just the + -- same as an arity-1 one. So we don't look at occ_int_cxt. + -- All of this only applies if keep_exits is False, otherwise the + -- earlier guard on preInlineUnconditionally would have fired + + one_occ _ = False + + active = isActive phase (inlinePragmaActivation inline_prag) -- See Note [pre/postInlineUnconditionally in gentle mode] inline_prag = idInlinePragma bndr @@ -1378,7 +1408,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = sePhase env /= FinalPhase + early_phase = phase /= FinalPhase -- If we don't have this early_phase test, consider -- x = length [1,2,3] -- The full laziness pass carefully floats all the cons cells to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -881,7 +881,7 @@ data SpecConstrOpts = SpecConstrOpts , sc_count :: !(Maybe Int) -- ^ Max # of specialisations for any one function. Nothing => no limit. - -- See Note [Avoiding exponential blowup]. + -- See Note [Avoiding exponential blowup] and decreaseSpecCount , sc_recursive :: !Int -- ^ Max # of specialisations over recursive type. Stops @@ -1098,16 +1098,20 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs decreaseSpecCount :: ScEnv -> Int -> ScEnv -- See Note [Avoiding exponential blowup] -decreaseSpecCount env n_specs +decreaseSpecCount env _n_specs = env { sc_force = False -- See Note [Forcing specialisation] - , sc_opts = (sc_opts env) - { sc_count = case sc_count $ sc_opts env of - Nothing -> Nothing - Just n -> Just $! (n `div` (n_specs + 1)) + , sc_opts = opts { sc_count = case sc_count opts of + Nothing -> Nothing + Just n -> Just $! dec n } } - -- The "+1" takes account of the original function; - -- See Note [Avoiding exponential blowup] + where + opts = sc_opts env + dec n = n `div` 2 -- See Note [Avoiding exponential blowup] + + -- Or: n `div` (n_specs + 1) + -- See the historical note part of Note [Avoiding exponential blowup] + -- The "+1" takes account of the original function; --------------------------------------------------- -- See Note [Forcing specialisation] @@ -1183,9 +1187,20 @@ we can specialise $j2, and similarly $j3. Even if we make just *one* specialisation of each, because we also have the original we'll get 2^n copies of $j3, which is not good. -So when recursively specialising we divide the sc_count by the number of -copies we are making at this level, including the original. - +So when recursively specialising we divide the sc_count (the maximum +number of specialisations, in the ScEnv) by two. You might think that +gives us n*(n/2)*(n/4)... copies of the innnermost thing, which is +still exponential the depth. But we use integer division, rounding +down, so if the starting sc_count is 3, we'll get 3 -> 1 -> 0, and +stop. In fact, simply subtracting 1 would be good enough, for the same +reason. + +Historical note: in the past we divided by (n_specs+1), where n_specs +is the number of specialisations at this level; but that gets us down +to zero jolly quickly, which I found led to some regressions. (An +example is nofib/spectral/fibheaps, the getMin' function inside the +outer function $sfibToList, which has several interesting call +patterns.) ************************************************************************ * * @@ -1512,8 +1527,10 @@ scExpr' env (Case scrut b ty alts) scrut_occ = case con of DataAlt dc -- See Note [Do not specialise evals] | not (single_alt && all deadArgOcc arg_occs) - -> ScrutOcc (unitUFM dc arg_occs) - _ -> UnkOcc + -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + ScrutOcc (unitUFM dc arg_occs) + _ -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + UnkOcc ; return (usg', b_occ `combineOcc` scrut_occ, Alt con bs2 rhs') } @@ -1792,16 +1809,19 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs , not (null arg_bndrs) -- Only specialise functions , Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it = -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $ - do { (boring_call, new_pats) <- callsToNewPats env fn spec_info arg_occs all_calls + do { (boring_call, pats_discarded, new_pats) + <- callsToNewPats env fn spec_info arg_occs all_calls ; let n_pats = length new_pats --- ; if (not (null new_pats) || isJust mb_unspec) then --- pprTrace "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" --- , text "mb_unspec" <+> ppr (isJust mb_unspec) --- , text "arg_occs" <+> ppr arg_occs --- , text "good pats" <+> ppr new_pats]) $ --- return () --- else return () +-- ; when (not (null new_pats) || isJust mb_unspec) $ +-- pprTraceM "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" +-- , text "boring_call:" <+> ppr boring_call +-- , text "pats_discarded:" <+> ppr pats_discarded +-- , text "old spec_count" <+> ppr spec_count +-- , text "spec count limit" <+> ppr (sc_count (sc_opts env)) +-- , text "mb_unspec" <+> ppr (isJust mb_unspec) +-- , text "arg_occs" <+> ppr arg_occs +-- , text "new_pats" <+> ppr new_pats]) ; let spec_env = decreaseSpecCount env n_pats ; (spec_usgs, new_specs) <- mapAndUnzipM (spec_one spec_env fn arg_bndrs body) @@ -1810,7 +1830,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ; let spec_usg = combineUsages spec_usgs - unspec_rhs_needed = boring_call || isExportedId fn + unspec_rhs_needed = pats_discarded || boring_call || isExportedId fn -- If there were any boring calls among the seeds (= all_calls), then those -- calls will call the un-specialised function. So we should use the seeds @@ -1821,15 +1841,14 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs -> (spec_usg `combineUsage` rhs_usg, Nothing) _ -> (spec_usg, mb_unspec) --- ; pprTrace "specialise return }" --- (vcat [ ppr fn --- , text "boring_call:" <+> ppr boring_call --- , text "new calls:" <+> ppr (scu_calls new_usg)]) $ --- return () +-- ; pprTraceM "specialise return }" $ +-- vcat [ ppr fn +-- , text "unspec_rhs_needed:" <+> ppr unspec_rhs_needed +-- , text "new calls:" <+> ppr (scu_calls new_usg)] - ; return (new_usg, SI { si_specs = new_specs ++ specs - , si_n_specs = spec_count + n_pats - , si_mb_unspec = mb_unspec' }) } + ; return (new_usg, SI { si_specs = new_specs ++ specs + , si_n_specs = spec_count + n_pats + , si_mb_unspec = mb_unspec' }) } | otherwise -- No calls, inactive, or not a function -- Behave as if there was a single, boring call @@ -1872,7 +1891,9 @@ spec_one :: ScEnv spec_one env fn arg_bndrs body (call_pat, rule_number) | CP { cp_qvars = qvars, cp_args = pats, cp_strict_args = cbv_args } <- call_pat - = do { spec_uniq <- getUniqueM + = do { -- pprTraceM "spec_one {" (ppr fn <+> ppr pats) + + ; spec_uniq <- getUniqueM ; let env1 = extendScSubstList (extendScInScope env qvars) (arg_bndrs `zip` pats) (body_env, extra_bndrs) = extendBndrs env1 (dropList pats arg_bndrs) @@ -1898,9 +1919,6 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) -- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env) ; (spec_usg, spec_body) <- scExpr body_env body --- ; pprTrace "done spec_one }" (ppr fn $$ ppr (scu_calls spec_usg)) $ --- return () - -- And build the results ; (qvars', pats') <- generaliseDictPats qvars pats ; let spec_body_ty = exprType spec_body @@ -1944,21 +1962,22 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) fn_name qvars' pats' rule_rhs -- See Note [Transfer activation] - -- ; pprTraceM "spec_one {" (vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) - -- , text "sc_count:" <+> ppr (sc_count env) - -- , text "pats:" <+> ppr pats - -- , text "call_pat:" <+> ppr call_pat - -- , text "-->" <+> ppr spec_name - -- , text "bndrs" <+> ppr arg_bndrs - -- , text "extra_bndrs" <+> ppr extra_bndrs - -- , text "cbv_args" <+> ppr cbv_args - -- , text "spec_lam_args" <+> ppr spec_lam_args - -- , text "spec_call_args" <+> ppr spec_call_args - -- , text "rule_rhs" <+> ppr rule_rhs - -- , text "adds_void_worker_arg" <+> ppr add_void_arg - -- , text "body" <+> ppr body - -- , text "spec_rhs" <+> ppr spec_rhs - -- , text "how_bound" <+> ppr (sc_how_bound env) ]) +-- ; pprTraceM "spec_one end }" $ +-- vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) +-- , text "pats:" <+> ppr pats +-- , text "call_pat:" <+> ppr call_pat +-- , text "-->" <+> ppr spec_name +-- , text "bndrs" <+> ppr arg_bndrs +-- , text "extra_bndrs" <+> ppr extra_bndrs +-- , text "cbv_args" <+> ppr cbv_args +-- , text "spec_lam_args" <+> ppr spec_lam_args +-- , text "spec_call_args" <+> ppr spec_call_args +-- , text "rule_rhs" <+> ppr rule_rhs +-- , text "adds_void_worker_arg" <+> ppr add_void_arg +---- , text "body" <+> ppr body +---- , text "spec_rhs" <+> ppr spec_rhs +---- , text "how_bound" <+> ppr (sc_how_bound env) ] +-- ] ; return (spec_usg, OS { os_pat = call_pat, os_rule = rule , os_id = spec_id , os_rhs = spec_rhs }) } @@ -2328,7 +2347,9 @@ instance Outputable CallPat where callsToNewPats :: ScEnv -> Id -> SpecInfo -> [ArgOcc] -> [Call] - -> UniqSM (Bool, [CallPat]) + -> UniqSM ( Bool -- At least one boring call + , Bool -- Patterns were discarded + , [CallPat] ) -- Patterns to specialise -- Result has no duplicate patterns, -- nor ones mentioned in si_specs (hence "new" patterns) -- Bool indicates that there was at least one boring pattern @@ -2360,12 +2381,11 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Discard specialisations if there are too many of them (pats_were_discarded, trimmed_pats) = trim_pats env fn spec_info small_pats --- ; pprTrace "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls --- , text "done_specs:" <+> ppr (map os_pat done_specs) --- , text "good_pats:" <+> ppr good_pats ]) $ --- return () +-- ; pprTraceM "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls +-- , text "done_specs:" <+> ppr (map os_pat done_specs) +-- , text "trimmed_pats:" <+> ppr trimmed_pats ]) - ; return (have_boring_call || pats_were_discarded, trimmed_pats) } + ; return (have_boring_call, pats_were_discarded, trimmed_pats) } -- If any of the calls does not give rise to a specialisation, either -- because it is boring, or because there are too many specialisations, -- return a flag to say so, so that we know to keep the original function. @@ -2474,29 +2494,29 @@ callToPats env bndr_occs call@(Call fn args con_env) sanitise id = updateIdTypeAndMult expandTypeSynonyms id -- See Note [Free type variables of the qvar types] - -- Bad coercion variables: see Note [SpecConstr and casts] - bad_covars :: CoVarSet + + -- Check for bad coercion variables: see Note [SpecConstr and casts] + ; let bad_covars :: CoVarSet bad_covars = mapUnionVarSet get_bad_covars pats get_bad_covars :: CoreArg -> CoVarSet get_bad_covars (Type ty) = filterVarSet bad_covar (tyCoVarsOfType ty) get_bad_covars _ = emptyVarSet bad_covar v = isId v && not (is_in_scope v) - ; -- pprTrace "callToPats" (ppr args $$ ppr bndr_occs) $ - warnPprTrace (not (isEmptyVarSet bad_covars)) + ; warnPprTrace (not (isEmptyVarSet bad_covars)) "SpecConstr: bad covars" (ppr bad_covars $$ ppr call) $ + if interesting && isEmptyVarSet bad_covars - then do - -- pprTraceM "callToPatsOut" ( - -- text "fn:" <+> ppr fn $$ - -- text "args:" <+> ppr args $$ - -- text "in_scope:" <+> ppr in_scope $$ - -- -- text "in_scope:" <+> ppr in_scope $$ - -- text "pat_fvs:" <+> ppr pat_fvs - -- ) - -- ppr (CP { cp_qvars = qvars', cp_args = pats })) >> - return (Just (CP { cp_qvars = qvars', cp_args = pats, cp_strict_args = concat cbv_ids })) + then do { let cp_res = CP { cp_qvars = qvars', cp_args = pats + , cp_strict_args = concat cbv_ids } +-- ; pprTraceM "callToPatsOut" $ +-- vcat [ text "fn:" <+> ppr fn +-- , text "args:" <+> ppr args +-- , text "bndr_occs:" <+> ppr bndr_occs +-- , text "pat_fvs:" <+> ppr pat_fvs +-- , text "cp_res:" <+> ppr cp_res ] + ; return (Just cp_res) } else return Nothing } -- argToPat takes an actual argument, and returns an abstracted ===================================== compiler/GHC/Driver/Config/Core/Opt/Simplify.hs ===================================== @@ -2,7 +2,6 @@ module GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyExprOpts , initSimplifyOpts , initSimplMode - , initGentleSimplMode ) where import GHC.Prelude @@ -27,12 +26,13 @@ import GHC.Types.Var ( Var ) initSimplifyExprOpts :: DynFlags -> InteractiveContext -> SimplifyExprOpts initSimplifyExprOpts dflags ic = SimplifyExprOpts { se_fam_inst = snd $ ic_instances ic - , se_mode = (initSimplMode dflags InitialPhase "GHCi") - { sm_inline = False - -- Do not do any inlining, in case we expose some - -- unboxed tuple stuff that confuses the bytecode + + , se_mode = (initSimplMode dflags) { sm_names = ["GHCi"] + , sm_inline = False } + -- sm_inline: do not do any inlining, in case we expose + -- some unboxed tuple stuff that confuses the bytecode -- interpreter - } + , se_top_env_cfg = TopEnvConfig { te_history_size = historySize dflags , te_tick_factor = simplTickFactor dflags @@ -57,31 +57,25 @@ initSimplifyOpts dflags extra_vars iterations mode rule_base = let } in opts -initSimplMode :: DynFlags -> CompilerPhase -> String -> SimplMode -initSimplMode dflags phase name = SimplMode - { sm_names = [name] - , sm_phase = phase - , sm_rules = gopt Opt_EnableRewriteRules dflags - , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags - , sm_cast_swizzle = True - , sm_inline = True - , sm_uf_opts = unfoldingOpts dflags - , sm_case_case = True - , sm_pre_inline = gopt Opt_SimplPreInlining dflags - , sm_float_enable = floatEnable dflags +initSimplMode :: DynFlags -> SimplMode +initSimplMode dflags = SimplMode + { sm_names = ["Unknown simplifier run"] -- Always overriden + , sm_phase = InitialPhase + , sm_rules = gopt Opt_EnableRewriteRules dflags + , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags + , sm_pre_inline = gopt Opt_SimplPreInlining dflags , sm_do_eta_reduction = gopt Opt_DoEtaReduction dflags - , sm_arity_opts = initArityOpts dflags - , sm_rule_opts = initRuleOpts dflags - , sm_case_folding = gopt Opt_CaseFolding dflags - , sm_case_merge = gopt Opt_CaseMerge dflags - , sm_co_opt_opts = initOptCoercionOpts dflags - } - -initGentleSimplMode :: DynFlags -> SimplMode -initGentleSimplMode dflags = (initSimplMode dflags InitialPhase "Gentle") - { -- Don't do case-of-case transformations. - -- This makes full laziness work better - sm_case_case = False + , sm_uf_opts = unfoldingOpts dflags + , sm_float_enable = floatEnable dflags + , sm_arity_opts = initArityOpts dflags + , sm_rule_opts = initRuleOpts dflags + , sm_case_folding = gopt Opt_CaseFolding dflags + , sm_case_merge = gopt Opt_CaseMerge dflags + , sm_co_opt_opts = initOptCoercionOpts dflags + , sm_cast_swizzle = True + , sm_inline = True + , sm_case_case = True + , sm_keep_exits = False } floatEnable :: DynFlags -> FloatEnable ===================================== compiler/GHC/Utils/Json.hs ===================================== @@ -14,6 +14,7 @@ data JsonDoc where JSBool :: Bool -> JsonDoc JSInt :: Int -> JsonDoc JSString :: String -> JsonDoc + -- ^ The 'String' is unescaped JSArray :: [JsonDoc] -> JsonDoc JSObject :: [(String, JsonDoc)] -> JsonDoc @@ -57,7 +58,7 @@ class ToJson a where json :: a -> JsonDoc instance ToJson String where - json = JSString . escapeJsonString + json = JSString instance ToJson Int where json = JSInt ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/simplCore/should_compile/T21148.hs ===================================== @@ -0,0 +1,12 @@ +module T211148 where + +-- The point of this test is that f should get a (nested) +-- CPR property, with a worker of type +-- $wf :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +{-# NOINLINE f #-} +-- The NOINLINE makes GHC do a worker/wrapper split +-- even though f is small +f :: Int -> IO Int +f x = return $! sum [0..x] + ===================================== testsuite/tests/simplCore/should_compile/T21148.stderr ===================================== @@ -0,0 +1,126 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 73, types: 80, coercions: 6, joins: 2/2} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T211148.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule3 = GHC.Types.TrNameS T211148.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T211148.$trModule2 = "T211148"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule1 = GHC.Types.TrNameS T211148.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule + = GHC.Types.Module T211148.$trModule3 T211148.$trModule1 + +-- RHS size: {terms: 41, types: 35, coercions: 0, joins: 2/2} +T211148.$wf [InlPrag=NOINLINE] + :: GHC.Prim.Int# + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) +[GblId, Arity=2, Str=, Unf=OtherCon []] +T211148.$wf + = \ (ww_s179 :: GHC.Prim.Int#) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case GHC.Prim.># 0# ww_s179 of { + __DEFAULT -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (x_s16Z [OS=OneShot] :: GHC.Prim.Int#) + (ww1_s172 [OS=OneShot] :: GHC.Prim.Int#) + = (# eta_s17b, GHC.Prim.+# ww1_s172 x_s16Z #) } in + joinrec { + $wgo3_s175 [InlPrag=[2], Occ=LoopBreaker, Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=, Unf=OtherCon []] + $wgo3_s175 (x_s16Z :: GHC.Prim.Int#) (ww1_s172 :: GHC.Prim.Int#) + = case GHC.Prim.==# x_s16Z ww_s179 of { + __DEFAULT -> + jump $wgo3_s175 + (GHC.Prim.+# x_s16Z 1#) (GHC.Prim.+# ww1_s172 x_s16Z); + 1# -> jump exit_X0 x_s16Z ww1_s172 + }; } in + jump $wgo3_s175 0# 0#; + 1# -> (# eta_s17b, 0# #) + } + +-- RHS size: {terms: 14, types: 19, coercions: 0, joins: 0/0} +T211148.f1 [InlPrag=NOINLINE[final]] + :: Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (x_s177 [Occ=Once1!] :: Int) + (eta_s17b [Occ=Once1, OS=OneShot] + :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 [Occ=Once1] -> + case T211148.$wf ww_s179 eta_s17b of + { (# ww1_s17e [Occ=Once1], ww2_s17j [Occ=Once1] #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + }}] +T211148.f1 + = \ (x_s177 :: Int) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 -> + case T211148.$wf ww_s179 eta_s17b of { (# ww1_s17e, ww2_s17j #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + } + +-- RHS size: {terms: 1, types: 0, coercions: 6, joins: 0/0} +f [InlPrag=NOINLINE[final]] :: Int -> IO Int +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +f = T211148.f1 + `cast` (_R %<'Many>_N ->_R Sym (GHC.Types.N:IO[0] _R) + :: (Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) + ~R# (Int -> IO Int)) + + + ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -429,4 +429,9 @@ test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21148', [grep_errmsg(r'Cpr=') ], compile, ['-O -ddump-simpl']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/stranal/should_compile/T21128.hs ===================================== @@ -2,6 +2,10 @@ module T21128 where import T21128a +{- This test originally had some unnecessary reboxing of y +in the hot path of $wtheresCrud. That reboxing should +not happen. -} + theresCrud :: Int -> Int -> Int theresCrud x y = go x where @@ -9,3 +13,4 @@ theresCrud x y = go x go 1 = index x y 1 go n = go (n-1) {-# NOINLINE theresCrud #-} + ===================================== testsuite/tests/stranal/should_compile/T21128.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 137, types: 92, coercions: 4, joins: 0/0} + = {terms: 125, types: 68, coercions: 4, joins: 0/0} lvl = "error"# @@ -29,17 +29,11 @@ lvl9 = SrcLoc lvl2 lvl3 lvl5 lvl6 lvl7 lvl6 lvl8 lvl10 = PushCallStack lvl1 lvl9 EmptyCallStack -$windexError - = \ @a @b ww eta eta1 eta2 -> - error - (lvl10 `cast` :: CallStack ~R# (?callStack::CallStack)) - (++ (ww eta) (++ (ww eta1) (ww eta2))) - indexError = \ @a @b $dShow eta eta1 eta2 -> - case $dShow of { C:Show ww ww1 ww2 -> - $windexError ww1 eta eta1 eta2 - } + error + (lvl10 `cast` :: ...) + (++ (show $dShow eta) (++ (show $dShow eta1) (show $dShow eta2))) $trModule3 = TrNameS $trModule4 @@ -48,8 +42,7 @@ $trModule1 = TrNameS $trModule2 $trModule = Module $trModule3 $trModule1 $wlvl - = \ ww ww1 ww2 -> - $windexError $fShowInt_$cshow (I# ww2) (I# ww1) (I# ww) + = \ ww ww1 ww2 -> indexError $fShowInt (I# ww2) (I# ww1) (I# ww) index = \ l u i -> @@ -73,7 +66,7 @@ index ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 108, types: 47, coercions: 0, joins: 3/4} + = {terms: 108, types: 46, coercions: 0, joins: 3/3} $trModule4 = "main"# @@ -89,35 +82,34 @@ i = I# 1# l = I# 0# -lvl = \ y -> $windexError $fShowInt_$cshow l y l +lvl = \ x ww -> indexError $fShowInt x (I# ww) i -lvl1 = \ ww y -> $windexError $fShowInt_$cshow (I# ww) y i +lvl1 = \ ww -> indexError $fShowInt l (I# ww) l $wtheresCrud = \ ww ww1 -> - let { y = I# ww1 } in join { - lvl2 + exit + = case <# 0# ww1 of { + __DEFAULT -> case lvl1 ww1 of wild { }; + 1# -> 0# + } } in + join { + exit1 = case <=# ww 1# of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> case <# 1# ww1 of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> -# 1# ww } } } in - join { - lvl3 - = case <# 0# ww1 of { - __DEFAULT -> case lvl y of wild { }; - 1# -> 0# - } } in joinrec { $wgo ww2 = case ww2 of wild { __DEFAULT -> jump $wgo (-# wild 1#); - 0# -> jump lvl3; - 1# -> jump lvl2 + 0# -> jump exit; + 1# -> jump exit1 }; } in jump $wgo ww View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af740ff6ebbe2fb378f7cb2d25223a816979d892...e4cac1b86f350d837a4b02eebb4cd5c637181cfc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af740ff6ebbe2fb378f7cb2d25223a816979d892...e4cac1b86f350d837a4b02eebb4cd5c637181cfc You're receiving 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 Oct 11 07:43:05 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 03:43:05 -0400 Subject: [Git][ghc/ghc][wip/T21470] 4 commits: Make rewrite rules "win" over inlining Message-ID: <63451e8939cc8_1eea6a514c8100511e@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21470 at Glasgow Haskell Compiler / GHC Commits: 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 42112508 by Simon Peyton Jones at 2022-10-11T08:44:53+01:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 3c4220c9 by Simon Peyton Jones at 2022-10-11T08:44:53+01:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 23 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - testsuite/tests/lib/integer/Makefile - testsuite/tests/linters/notes.stdout - testsuite/tests/numeric/should_compile/T19641.stderr - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs - + testsuite/tests/simplCore/should_compile/T22097.stderr - + testsuite/tests/simplCore/should_compile/T22097a.hs - testsuite/tests/simplCore/should_compile/T6056.stderr - testsuite/tests/simplCore/should_compile/T8331.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -19,7 +19,7 @@ core expression with (hopefully) improved usage information. module GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr, - zapLambdaBndrs + zapLambdaBndrs, scrutBinderSwap_maybe ) where import GHC.Prelude @@ -27,11 +27,12 @@ import GHC.Prelude import GHC.Core import GHC.Core.FVs import GHC.Core.Utils ( exprIsTrivial, isDefaultAlt, isExpandableApp, - stripTicksTopE, mkTicks ) + mkCastMCo, mkTicks ) import GHC.Core.Opt.Arity ( joinRhsArity, isOneShotBndr ) import GHC.Core.Coercion +import GHC.Core.Predicate ( isDictId ) import GHC.Core.Type -import GHC.Core.TyCo.FVs( tyCoVarsOfMCo ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfMCo ) import GHC.Data.Maybe( isJust, orElse ) import GHC.Data.Graph.Directed ( SCC(..), Node(..) @@ -2462,8 +2463,8 @@ data OccEnv -- See Note [The binder-swap substitution] -- If x :-> (y, co) is in the env, - -- then please replace x by (y |> sym mco) - -- Invariant of course: idType x = exprType (y |> sym mco) + -- then please replace x by (y |> mco) + -- Invariant of course: idType x = exprType (y |> mco) , occ_bs_env :: !(VarEnv (OutId, MCoercion)) , occ_bs_rng :: !VarSet -- Vars free in the range of occ_bs_env -- Domain is Global and Local Ids @@ -2669,7 +2670,7 @@ The binder-swap is implemented by the occ_bs_env field of OccEnv. There are two main pieces: * Given case x |> co of b { alts } - we add [x :-> (b, co)] to the occ_bs_env environment; this is + 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 @@ -2737,30 +2738,8 @@ Some tricky corners: (BS5) We have to apply the occ_bs_env substitution uniformly, including to (local) 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. +(BS6) We must be very careful with dictionaries. + See Note [Care with binder-swap on dictionaries] Note [Case of cast] ~~~~~~~~~~~~~~~~~~~ @@ -2770,6 +2749,54 @@ 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 [Care with binder-swap on dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This Note explains why we need isDictId in scrutBinderSwap_maybe. +Consider this tricky example (#21229, #21470): + + class Sing (b :: Bool) where sing :: Bool + instance Sing 'True where sing = True + instance Sing 'False where sing = False + + f :: forall a. Sing a => blah + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a dSing + +Now do a binder-swap on the case-expression: + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (wild |> sym the_co) + +And now substitute `False` for `wild` (since wild=False in the False branch): + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (False |> sym the_co) + +And now we have a problem. The specialiser will specialise (f @a d)a (for all +vtypes a and dictionaries d!!) with the dictionary (False |> sym the_co), using +Note [Specialising polymorphic dictionaries] in GHC.Core.Opt.Specialise. + +The real problem is the binder-swap. It swaps a dictionary variable $dSing +(of kind Constraint) for a term variable wild (of kind Type). And that is +dangerous: a dictionary is a /singleton/ type whereas a general term variable is +not. In this particular example, Bool is most certainly not a singleton type! + +Conclusion: + for a /dictionary variable/ do not perform + the clever cast version of the binder-swap + +Hence the subtle isDictId in scrutBinderSwap_maybe. + Note [Zap case binders in proxy bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the original @@ -2784,8 +2811,87 @@ binding x = cb. See #5028. NB: the OccInfo on /occurrences/ really doesn't matter much; the simplifier doesn't use it. So this is only to satisfy the perhaps-over-picky Lint. +-} + +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 (scrut_var, mco) <- scrutBinderSwap_maybe scrut + , scrut_var /= case_bndr + -- Consider: case x of x { ... } + -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop + = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) + , occ_bs_rng = rng_vars `extendVarSet` case_bndr' + `unionVarSet` tyCoVarsOfMCo mco } + + | otherwise + = env + where + case_bndr' = zapIdOccInfo case_bndr + -- See Note [Zap case binders in proxy bindings] + +scrutBinderSwap_maybe :: OutExpr -> Maybe (OutVar, MCoercion) +-- If (scrutBinderSwap_maybe e = Just (v, mco), then +-- v = e |> mco +-- See Note [Case of cast] +-- See Note [Care with binder-swap on dictionaries] +-- +-- We use this same function in SpecConstr, and Simplify.Iteration, +-- when something binder-swap-like is happening +scrutBinderSwap_maybe (Var v) = Just (v, MRefl) +scrutBinderSwap_maybe (Cast (Var v) co) + | not (isDictId v) = Just (v, MCo (mkSymCo co)) + -- Cast: see Note [Case of cast] + -- isDictId: see Note [Care with binder-swap on dictionaries] + -- The isDictId rejects a Constraint/Constraint binder-swap, perhaps + -- over-conservatively. But I have never seen one, so I'm leaving + -- the code as simple as possible. Losing the binder-swap in a + -- rare case probably has very low impact. +scrutBinderSwap_maybe (Tick _ e) = scrutBinderSwap_maybe e -- Drop ticks +scrutBinderSwap_maybe _ = Nothing + +lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) +-- See Note [The binder-swap substitution] +-- Returns an expression of the same type as Id +lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr + = case lookupVarEnv bs_env bndr of { + Nothing -> (Var bndr, bndr) ; + Just (bndr1, mco) -> + + -- Why do we iterate here? + -- See (BS2) in Note [The binder-swap substitution] + case lookupBndrSwap env bndr1 of + (fun, fun_id) -> (mkCastMCo fun mco, fun_id) } + + +{- Historical note [Proxy let-bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. + Historical Note [no-case-of-case] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We *used* to suppress the binder-swap in case expressions when -fno-case-of-case is on. Old remarks: "This happens in the first simplifier pass, @@ -2844,53 +2950,8 @@ binder-swap in OccAnal: It's fixed by doing the binder-swap in OccAnal because we can do the binder-swap unconditionally and still get occurrence analysis information right. --} -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 (scrut_var, mco) <- get_scrut_var (stripTicksTopE (const True) scrut) - , scrut_var /= case_bndr - -- Consider: case x of x { ... } - -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop - = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) - , occ_bs_rng = rng_vars `extendVarSet` case_bndr' - `unionVarSet` tyCoVarsOfMCo mco } - - | otherwise - = env - where - get_scrut_var :: OutExpr -> Maybe (OutVar, MCoercion) - get_scrut_var (Var v) = Just (v, MRefl) - get_scrut_var (Cast (Var v) co) = Just (v, MCo co) -- See Note [Case of cast] - get_scrut_var _ = Nothing - - case_bndr' = zapIdOccInfo case_bndr - -- See Note [Zap case binders in proxy bindings] -lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) --- See Note [The binder-swap substitution] --- Returns an expression of the same type as Id -lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr - = case lookupVarEnv bs_env bndr of { - Nothing -> (Var bndr, bndr) ; - Just (bndr1, mco) -> - - -- Why do we iterate here? - -- See (BS2) in Note [The binder-swap substitution] - case lookupBndrSwap env bndr1 of - (fun, fun_id) -> (add_cast fun mco, fun_id) } - - where - add_cast fun MRefl = fun - add_cast fun (MCo co) = Cast fun (mkSymCo co) - -- We must switch that 'co' to 'sym co'; - -- see the comment with occ_bs_env - -- No need to test for isReflCo, because 'co' came from - -- a (Cast e co) and hence is unlikely to be Refl - -{- ************************************************************************ * * \subsection[OccurAnal-types]{OccEnv} ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -51,17 +51,6 @@ The simplifier tries to get rid of occurrences of x, in favour of wild, in the hope that there will only be one remaining occurrence of x, namely the scrutinee of the case, and we can inline it. - - This can only work if @wild@ is an unrestricted binder. Indeed, even with the - extended typing rule (in the linter) for case expressions, if - case x of wild % 1 { p -> e} - is well-typed, then - case x of wild % 1 { p -> e[wild\x] } - is only well-typed if @e[wild\x] = e@ (that is, if @wild@ is not used in @e@ - at all). In which case, it is, of course, pointless to do the substitution - anyway. So for a linear binder (and really anything which isn't unrestricted), - doing this substitution would either produce ill-typed terms or be the - identity. -} module GHC.Core.Opt.SetLevels ( @@ -1602,7 +1591,9 @@ extendCaseBndrEnv :: LevelEnv -> LevelEnv extendCaseBndrEnv le@(LE { le_subst = subst, le_env = id_env }) case_bndr (Var scrut_var) - | Many <- varMult case_bndr + -- We could use OccurAnal. scrutBinderSwap_maybe here, and perhaps + -- get a bit more floating. But we didn't in the past and it's + -- an unforced change, so I'm leaving it. = le { le_subst = extendSubstWithVar subst case_bndr scrut_var , le_env = add_id id_env (case_bndr, scrut_var) } extendCaseBndrEnv env _ _ = env ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -71,7 +71,8 @@ import GHC.Core.Make ( mkWildValBinder, mkCoreLet ) import GHC.Builtin.Types import GHC.Core.TyCo.Rep ( TyCoBinder(..) ) import qualified GHC.Core.Type as Type -import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, extendTvSubst, extendCvSubst ) +import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, substCo + , extendTvSubst, extendCvSubst ) import qualified GHC.Core.Coercion as Coercion import GHC.Core.Coercion hiding ( substCo, substCoVar, substCoVarBndr ) import GHC.Platform ( Platform ) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.Opt.Simplify.Env import GHC.Core.Opt.Simplify.Utils -import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs ) +import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutBinderSwap_maybe ) import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr ) import qualified GHC.Core.Make import GHC.Core.Coercion hiding ( substCo, substCoVar ) @@ -1919,7 +1919,9 @@ wrapJoinCont env cont thing_inside -------------------- -trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont +trimJoinCont :: Id -- Used only in error message + -> Maybe JoinArity + -> SimplCont -> SimplCont -- Drop outer context from join point invocation (jump) -- See Note [Join points and case-of-case] @@ -2017,6 +2019,17 @@ outside. Surprisingly tricky! Variables * * ************************************************************************ + +Note [zapSubstEnv] +~~~~~~~~~~~~~~~~~~ +When simplifying something that has already been simplified, be sure to +zap the SubstEnv. This is VITAL. Consider + let x = e in + let y = \z -> ...x... in + \ x -> ...y... + +We'll clone the inner \x, adding x->x' in the id_subst Then when we +inline y, we must *not* replace x by x' in the inlined copy!! -} simplVar :: SimplEnv -> InVar -> SimplM OutExpr @@ -2035,86 +2048,28 @@ simplVar env var simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) simplIdF env var cont = case substId env var of - ContEx tvs cvs ids e -> - let env' = setSubstEnv env tvs cvs ids - in simplExprF env' e cont - -- Don't trim; haven't already simplified e, - -- so the cont is not embodied in e - - DoneId var1 -> do - logger <- getLogger - let cont' = trimJoinCont var (isJoinId_maybe var1) cont - completeCall logger env var1 cont' - - DoneEx e mb_join -> - let env' = zapSubstEnv env - cont' = trimJoinCont var mb_join cont - in simplExprF env' e cont' - -- Note [zapSubstEnv] - -- ~~~~~~~~~~~~~~~~~~ - -- The template is already simplified, so don't re-substitute. - -- This is VITAL. Consider - -- let x = e in - -- let y = \z -> ...x... in - -- \ x -> ...y... - -- We'll clone the inner \x, adding x->x' in the id_subst - -- Then when we inline y, we must *not* replace x by x' in - -- the inlined copy!! - ---------------------------------------------------------- --- Dealing with a call site - -completeCall :: Logger -> SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr) -completeCall logger env var cont - | Just expr <- callSiteInline logger uf_opts case_depth var active_unf - lone_variable arg_infos interesting_cont - -- Inline the variable's RHS - = do { checkedTick (UnfoldingDone var) - ; dump_inline expr cont - ; let env1 = zapSubstEnv env - ; simplExprF env1 expr cont } + ContEx tvs cvs ids e -> simplExprF env' e cont + -- Don't trimJoinCont; haven't already simplified e, + -- so the cont is not embodied in e + where + env' = setSubstEnv env tvs cvs ids - | otherwise - -- Don't inline; instead rebuild the call - = do { rule_base <- getSimplRules - ; let rules = getRules rule_base var - info = mkArgInfo env var rules - n_val_args call_cont - ; rebuildCall env info cont } + DoneId var1 -> + do { rule_base <- getSimplRules + ; let cont' = trimJoinCont var1 (isJoinId_maybe var1) cont + info = mkArgInfo env rule_base var1 cont' + ; rebuildCall env info cont' } - where - uf_opts = seUnfoldingOpts env - case_depth = seCaseDepth env - (lone_variable, arg_infos, call_cont) = contArgs cont - n_val_args = length arg_infos - interesting_cont = interestingCallContext env call_cont - active_unf = activeUnfolding (seMode env) var - - log_inlining doc - = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) - Opt_D_dump_inlinings - "" FormatText doc + DoneEx e mb_join -> simplExprF env' e cont' + where + cont' = trimJoinCont var mb_join cont + env' = zapSubstEnv env -- See Note [zapSubstEnv] - dump_inline unfolding cont - | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () - | not (logHasDumpFlag logger Opt_D_verbose_core2core) - = when (isExternalName (idName var)) $ - log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] - | otherwise - = log_inlining $ - sep [text "Inlining done: " <> ppr var, - nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), - text "Cont: " <+> ppr cont])] +--------------------------------------------------------- +-- Dealing with a call site -rebuildCall :: SimplEnv - -> ArgInfo - -> SimplCont +rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, OutExpr) --- We decided not to inline, so --- - simplify the arguments --- - try rewrite rules --- - and rebuild ---------- Bottoming applications -------------- rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont @@ -2137,27 +2092,48 @@ rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) con res = argInfoExpr fun rev_args cont_ty = contResultType cont ----------- Try rewrite RULES -------------- --- See Note [Trying rewrite rules] +---------- Try inlining, if ai_rewrite = TryInlining -------- +-- In the TryInlining case we try inlining immediately, before simplifying +-- any (more) arguments. Why? See Note [Rewrite rules and inlining]. +-- +-- If there are rewrite rules we'll skip this case until we have +-- simplified enough args to satisfy nr_wanted==0 in the TryRules case below +-- Then we'll try the rules, and if that fails, we'll do TryInlining rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rules = Just (nr_wanted, rules) }) cont + , ai_rewrite = TryInlining }) cont + = do { logger <- getLogger + ; let full_cont = pushSimplifiedRevArgs env rev_args cont + ; mb_inline <- tryInlining env logger fun full_cont + ; case mb_inline of + Just expr -> do { checkedTick (UnfoldingDone fun) + ; let env1 = zapSubstEnv env + ; simplExprF env1 expr full_cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryNothing }) cont + } + +---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- +-- See Note [Rewrite rules and inlining] +-- See also Note [Trying rewrite rules] +rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryRules nr_wanted rules }) cont | nr_wanted == 0 || no_more_args - , let info' = info { ai_rules = Nothing } = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] do { mb_match <- tryRules env rules fun (reverse rev_args) cont ; case mb_match of Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env info' cont } + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } where + -- If we have run out of arguments, just try the rules; there might + -- be some with lower arity. Casts get in the way -- they aren't + -- allowed on rule LHSs no_more_args = case cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True - ----------- Simplify applications and casts -------------- +---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont @@ -2202,6 +2178,7 @@ rebuildCall env (ArgInfo { ai_fun = fun_id, ai_args = rev_args }) call' = mkApps (Var fun_id) [mkTyArg rr', mkTyArg ty', arg'] ; return (emptyFloats env, call') } +---------- Simplify value arguments -------------------- rebuildCall env fun_info (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_hole_ty = fun_ty @@ -2237,6 +2214,42 @@ rebuildCall env fun_info rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) cont = rebuild env (argInfoExpr fun rev_args) cont +----------------------------------- +tryInlining :: SimplEnv -> Logger -> OutId -> SimplCont -> SimplM (Maybe OutExpr) +tryInlining env logger var cont + | Just expr <- callSiteInline logger uf_opts case_depth var active_unf + lone_variable arg_infos interesting_cont + = do { dump_inline expr cont + ; return (Just expr) } + + | otherwise + = return Nothing + + where + uf_opts = seUnfoldingOpts env + case_depth = seCaseDepth env + (lone_variable, arg_infos, call_cont) = contArgs cont + interesting_cont = interestingCallContext env call_cont + active_unf = activeUnfolding (seMode env) var + + log_inlining doc + = liftIO $ logDumpFile logger (mkDumpStyle alwaysQualify) + Opt_D_dump_inlinings + "" FormatText doc + + dump_inline unfolding cont + | not (logHasDumpFlag logger Opt_D_dump_inlinings) = return () + | not (logHasDumpFlag logger Opt_D_verbose_core2core) + = when (isExternalName (idName var)) $ + log_inlining $ + sep [text "Inlining done:", nest 4 (ppr var)] + | otherwise + = log_inlining $ + sep [text "Inlining done: " <> ppr var, + nest 4 (vcat [text "Inlined fn: " <+> nest 2 (ppr unfolding), + text "Cont: " <+> ppr cont])] + + {- Note [Trying rewrite rules] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider an application (f e1 e2 e3) where the e1,e2,e3 are not yet @@ -2272,6 +2285,38 @@ makes a particularly big difference when superclass selectors are involved: op ($p1 ($p2 (df d))) We want all this to unravel in one sweep. +Note [Rewrite rules and inlining] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In general we try to arrange that inlining is disabled (via a pragma) if +a rewrite rule should apply, so that the rule has a decent chance to fire +before we inline the function. + +But it turns out that (especially when type-class specialisation or +SpecConstr is involved) it is very helpful for the the rewrite rule to +"win" over inlining when both are active at once: see #21851, #22097. + +The simplifier arranges to do this, as follows. In effect, the ai_rewrite +field of the ArgInfo record is the state of a little state-machine: + +* mkArgInfo sets the ai_rewrite field to TryRules if there are any rewrite + rules avaialable for that function. + +* rebuildCall simplifies arguments until enough are simplified to match the + rule with greatest arity. See Note [RULES apply to simplified arguments] + and the first field of `TryRules`. + + But no more! As soon as we have simplified enough arguments to satisfy the + maximum-arity rules, we try the rules; see Note [Trying rewrite rules]. + +* Once we have tried rules (or immediately if there are no rules) set + ai_rewrite to TryInlining, and the Simplifier will try to inline the + function. We want to try this immediately (before simplifying any (more) + arguments). Why? Consider + f BIG where f = \x{OneOcc}. ...x... + If we inline `f` before simplifying `BIG` well use preInlineUnconditionally, + and we'll simplify BIG once, at x's occurrence, rather than twice. + + Note [Avoid redundant simplification] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because RULES apply to simplified arguments, there's a danger of repeatedly @@ -2327,7 +2372,8 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] - -> Id -> [ArgSpec] + -> Id + -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) @@ -3240,19 +3286,21 @@ zapIdOccInfoAndSetEvald str v = -- see Note [Case alternative occ info] addAltUnfoldings :: SimplEnv -> Maybe OutExpr -> OutId -> OutExpr -> SimplM SimplEnv -addAltUnfoldings env scrut case_bndr con_app +addAltUnfoldings env mb_scrut case_bndr con_app = do { let con_app_unf = mk_simple_unf con_app env1 = addBinderUnfolding env case_bndr con_app_unf -- See Note [Add unfolding for scrutinee] - env2 | Many <- idMult case_bndr = case scrut of - Just (Var v) -> addBinderUnfolding env1 v con_app_unf - Just (Cast (Var v) co) -> addBinderUnfolding env1 v $ - mk_simple_unf (Cast con_app (mkSymCo co)) - _ -> env1 + env2 | Just scrut <- mb_scrut + , Just (v,mco) <- scrutBinderSwap_maybe scrut + = addBinderUnfolding env1 v $ + if isReflMCo mco -- isReflMCo: avoid calling mk_simple_unf + then con_app_unf -- twice in the common case + else mk_simple_unf (mkCastMCo con_app mco) + | otherwise = env1 - ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr scrut, ppr con_app]) + ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr mb_scrut, ppr con_app]) ; return env2 } where -- Force the opts, so that the whole SimplEnv isn't retained @@ -3315,9 +3363,6 @@ 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. -Exactly the same issue arises in GHC.Core.Opt.SpecConstr; -see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr - HOWEVER, given case x of y { Just a -> r1; Nothing -> r2 } we do not want to add the unfolding x -> y to 'x', which might seem cool, @@ -3328,8 +3373,11 @@ piece of information. So instead we add the unfolding x -> Just a, and x -> Nothing in the respective RHSs. -Since this transformation is tantamount to a binder swap, the same caveat as in -Note [Suppressing binder-swaps on linear case] in OccurAnal apply. +Since this transformation is tantamount to a binder swap, we use +GHC.Core.Opt.OccurAnal.scrutBinderSwap_maybe to do the check. + +Exactly the same issue arises in GHC.Core.Opt.SpecConstr; +see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr ************************************************************************ @@ -3668,7 +3716,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty | otherwise = do { join_bndr <- newJoinId [arg_bndr] res_ty ; let arg_info = ArgInfo { ai_fun = join_bndr - , ai_rules = Nothing, ai_args = [] + , ai_rewrite = TryNothing, ai_args = [] , ai_encl = False, ai_dmds = repeat topDmd , ai_discs = repeat 0 } ; return ( addJoinFloats (emptyFloats env) $ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -30,9 +30,10 @@ module GHC.Core.Opt.Simplify.Utils ( interestingCallContext, -- ArgInfo - ArgInfo(..), ArgSpec(..), mkArgInfo, + ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, - argInfoExpr, argInfoAppArgs, pushSimplifiedArgs, + argInfoExpr, argInfoAppArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -52,6 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils +import GHC.Core.Rules( getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make @@ -210,6 +212,7 @@ data SimplCont type StaticEnv = SimplEnv -- Just the static part is relevant +-- See Note [DupFlag invariants] data DupFlag = NoDup -- Unsimplified, might be big | Simplified -- Simplified | OkToDup -- Simplified and small @@ -226,8 +229,9 @@ perhapsSubstTy dup env ty {- Note [StaticEnv invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We pair up an InExpr or InAlts with a StaticEnv, which establishes the -lexical scope for that InExpr. When we simplify that InExpr/InAlts, we -use +lexical scope for that InExpr. + +When we simplify that InExpr/InAlts, we use - Its captured StaticEnv - Overriding its InScopeSet with the larger one at the simplification point. @@ -244,13 +248,14 @@ isn't big enough. Note [DupFlag invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~ -In both (ApplyToVal dup _ env k) - and (Select dup _ _ env k) +In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k} + and Select { se_dup = dup, se_env = env, se_cont = k} the following invariants hold (a) if dup = OkToDup, then continuation k is also ok-to-dup - (b) if dup = OkToDup or Simplified, the subst-env is empty - (and hence no need to re-simplify) + (b) if dup = OkToDup or Simplified, the subst-env is empty, + or at least is always ignored; the payload is + already an OutThing -} instance Outputable DupFlag where @@ -309,7 +314,8 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_rules :: FunRules, -- Rules for this function + ai_rewrite :: RewriteCall, -- What transformation to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration ai_encl :: Bool, -- Flag saying whether this function -- or an enclosing one has rules (recursively) @@ -325,6 +331,12 @@ data ArgInfo -- Always infinite } +data RewriteCall -- What rewriting to try next for this call + -- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration + = TryRules FullArgCount [CoreRule] + | TryInlining + | TryNothing + data ArgSpec = ValArg { as_dmd :: Demand -- Demand placed on this argument , as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal @@ -349,20 +361,20 @@ instance Outputable ArgSpec where addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo addValArgTo ai arg hole_ty - | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rules = rules } <- ai + | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs, ai_rewrite = rew } <- ai -- Pop the top demand and and discounts off , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd } - = ai { ai_args = arg_spec : ai_args ai - , ai_dmds = dmds - , ai_discs = discs - , ai_rules = decRules rules } + = ai { ai_args = arg_spec : ai_args ai + , ai_dmds = dmds + , ai_discs = discs + , ai_rewrite = decArgCount rew } | otherwise = pprPanic "addValArgTo" (ppr ai $$ ppr arg) -- There should always be enough demands and discounts addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo -addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai - , ai_rules = decRules (ai_rules ai) } +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rewrite = decArgCount (ai_rewrite ai) } where arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } @@ -381,19 +393,22 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont -pushSimplifiedArgs _env [] k = k -pushSimplifiedArgs env (arg : args) k - = case arg of - TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } - -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg { as_arg = arg, as_hole_ty = hole_ty } - -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified - , sc_hole_ty = hole_ty, sc_cont = rest } - CastBy c -> CastIt c rest - where - rest = pushSimplifiedArgs env args k - -- The env has an empty SubstEnv +pushSimplifiedArgs, pushSimplifiedRevArgs + :: SimplEnv + -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, + -- in /reverse/ order for pushSimplifiedRevArgs + -> SimplCont -> SimplCont +pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args + +pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushSimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + -- The SubstEnv will be ignored since sc_dup=Simplified + , sc_hole_ty = hole_ty, sc_cont = cont } +pushSimplifiedArg _ (CastBy c) cont = CastIt c cont argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg @@ -406,18 +421,14 @@ argInfoExpr fun rev_args go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co +decArgCount :: RewriteCall -> RewriteCall +decArgCount (TryRules n rules) = TryRules (n-1) rules +decArgCount rew = rew -type FunRules = Maybe (Int, [CoreRule]) -- Remaining rules for this function - -- Nothing => No rules - -- Just (n, rules) => some rules, requiring at least n more type/value args - -decRules :: FunRules -> FunRules -decRules (Just (n, rules)) = Just (n-1, rules) -decRules Nothing = Nothing - -mkFunRules :: [CoreRule] -> FunRules -mkFunRules [] = Nothing -mkFunRules rs = Just (n_required, rs) +mkTryRules :: [CoreRule] -> RewriteCall +-- See Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration +mkTryRules [] = TryInlining +mkTryRules rs = TryRules n_required rs where n_required = maximum (map ruleArity rs) @@ -516,6 +527,7 @@ contHoleScaling (StrictArg { sc_fun_ty = fun_ty, sc_cont = k }) contHoleScaling (ApplyToTy { sc_cont = k }) = contHoleScaling k contHoleScaling (ApplyToVal { sc_cont = k }) = contHoleScaling k contHoleScaling (TickIt _ k) = contHoleScaling k + ------------------- countArgs :: SimplCont -> Int -- Count all arguments, including types, coercions, @@ -525,6 +537,14 @@ countArgs (ApplyToVal { sc_cont = cont }) = 1 + countArgs cont countArgs (CastIt _ cont) = countArgs cont countArgs _ = 0 +countValArgs :: SimplCont -> Int +-- Count value arguments only +countValArgs (ApplyToTy { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (ApplyToVal { sc_cont = cont }) = 1 + countValArgs cont +countValArgs (CastIt _ cont) = countValArgs cont +countValArgs _ = 0 + +------------------- contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont) -- Summarises value args, discards type args and coercions -- The returned continuation of the call is only used to @@ -579,29 +599,26 @@ contEvalContext k = case k of -- and case binder dmds, see addCaseBndrDmd. No priority right now. ------------------- -mkArgInfo :: SimplEnv - -> Id - -> [CoreRule] -- Rules for function - -> Int -- Number of value args - -> SimplCont -- Context of the call - -> ArgInfo - -mkArgInfo env fun rules n_val_args call_cont +mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo + +mkArgInfo env rule_base fun cont | n_val_args < idArity fun -- Note [Unsaturated functions] = ArgInfo { ai_fun = fun, ai_args = [] - , ai_rules = fun_rules + , ai_rewrite = fun_rules , ai_encl = False , ai_dmds = vanilla_dmds , ai_discs = vanilla_discounts } | otherwise = ArgInfo { ai_fun = fun , ai_args = [] - , ai_rules = fun_rules - , ai_encl = interestingArgContext rules call_cont + , ai_rewrite = fun_rules + , ai_encl = notNull rules || contHasRules cont , ai_dmds = add_type_strictness (idType fun) arg_dmds , ai_discs = arg_discounts } where - fun_rules = mkFunRules rules + rules = getRules rule_base fun + fun_rules = mkTryRules rules + n_val_args = countValArgs cont vanilla_discounts, arg_discounts :: [Int] vanilla_discounts = repeat 0 @@ -814,7 +831,7 @@ interestingCallContext env cont -- a build it's *great* to inline it here. So we must ensure that -- the context for (f x) is not totally uninteresting. -interestingArgContext :: [CoreRule] -> SimplCont -> Bool +contHasRules :: SimplCont -> Bool -- If the argument has form (f x y), where x,y are boring, -- and f is marked INLINE, then we don't want to inline f. -- But if the context of the argument is @@ -822,33 +839,29 @@ interestingArgContext :: [CoreRule] -> SimplCont -> Bool -- where g has rules, then we *do* want to inline f, in case it -- exposes a rule that might fire. Similarly, if the context is -- h (g (f x x)) --- where h has rules, then we do want to inline f; hence the --- call_cont argument to interestingArgContext +-- where h has rules, then we do want to inline f. So contHasRules +-- tries to see if the context of the f-call is a call to a function +-- with rules. -- --- The ai-rules flag makes this happen; if it's +-- The ai_encl flag makes this happen; if it's -- set, the inliner gets just enough keener to inline f -- regardless of how boring f's arguments are, if it's marked INLINE -- -- The alternative would be to *always* inline an INLINE function, -- regardless of how boring its context is; but that seems overkill -- For example, it'd mean that wrapper functions were always inlined --- --- The call_cont passed to interestingArgContext is the context of --- the call itself, e.g. g in the example above -interestingArgContext rules call_cont - = notNull rules || enclosing_fn_has_rules +contHasRules cont + = go cont where - enclosing_fn_has_rules = go call_cont - - go (Select {}) = False - go (ApplyToVal {}) = False -- Shouldn't really happen - go (ApplyToTy {}) = False -- Ditto - go (StrictArg { sc_fun = fun }) = ai_encl fun - go (StrictBind {}) = False -- ?? - go (CastIt _ c) = go c - go (Stop _ RuleArgCtxt _) = True - go (Stop _ _ _) = False - go (TickIt _ c) = go c + go (ApplyToVal { sc_cont = cont }) = go cont + go (ApplyToTy { sc_cont = cont }) = go cont + go (CastIt _ cont) = go cont + go (StrictArg { sc_fun = fun }) = ai_encl fun + go (Stop _ RuleArgCtxt _) = True + go (TickIt _ c) = go c + go (Select {}) = False + go (StrictBind {}) = False -- ?? + go (Stop _ _ _) = False {- Note [Interesting arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Core.Unfold import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils +import GHC.Core.Opt.OccurAnal( scrutBinderSwap_maybe ) import GHC.Core.DataCon import GHC.Core.Class( classTyVars ) import GHC.Core.Coercion hiding( substCo ) @@ -1073,8 +1074,8 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs = (env2, alt_bndrs') where live_case_bndr = not (isDeadBinder case_bndr) - env1 | Var v <- stripTicksTopE (const True) scrut - = extendValEnv env v cval + env1 | Just (v, mco) <- scrutBinderSwap_maybe scrut + , isReflMCo mco = extendValEnv env v cval | otherwise = env -- See Note [Add scrutinee to ValueEnv too] env2 | live_case_bndr = extendValEnv env1 case_bndr cval | otherwise = env1 @@ -1164,6 +1165,10 @@ though the simplifier has systematically replaced uses of 'x' with 'y' and 'b' with 'c' in the code. The use of 'b' in the ValueEnv came from outside the case. See #4908 for the live example. +It's very like the binder-swap story, so we use scrutBinderSwap_maybe +to identify suitable scrutinees -- but only if there is no cast +(isReflMCo) because that's all that the ValueEnv allows. + Note [Avoiding exponential blowup] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The sc_count field of the ScEnv says how many times we are prepared to ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -15,9 +15,7 @@ import GHC.Driver.Config import GHC.Driver.Config.Diagnostic import GHC.Driver.Config.Core.Rules ( initRuleOpts ) -import GHC.Tc.Utils.TcType hiding( substTy ) - -import GHC.Core.Type hiding( substTy, extendTvSubstList, zapSubst ) +import GHC.Core.Type hiding( substTy, substCo, extendTvSubstList, zapSubst ) import GHC.Core.Multiplicity import GHC.Core.Predicate import GHC.Core.Coercion( Coercion ) @@ -25,12 +23,15 @@ import GHC.Core.Opt.Monad import qualified GHC.Core.Subst as Core import GHC.Core.Unfold.Make import GHC.Core +import GHC.Core.Make ( mkLitRubbish ) +import GHC.Core.Unify ( tcMatchTy ) import GHC.Core.Rules import GHC.Core.Utils ( exprIsTrivial , mkCast, exprType , stripTicksTop ) import GHC.Core.FVs -import GHC.Core.TyCo.Rep (TyCoBinder (..)) +import GHC.Core.TyCo.Rep ( TyCoBinder (..) ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfTypeList ) import GHC.Core.Opt.Arity( collectBindersPushingCo ) import GHC.Builtin.Types ( unboxedUnitTy ) @@ -531,6 +532,48 @@ like f :: Eq [(a,b)] => ... +Note [Specialisation and overlapping instances] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Here is at tricky case (see a comment in MR !8916): + + module A where + class C a where + meth :: a -> String + instance {-# OVERLAPPABLE #-} C (Maybe a) where + meth _ = "Maybe" + + {-# SPECIALISE f :: Maybe a -> Bool -> String #-} + f :: C a => a -> Bool -> String + f a True = f a False + f a _ = meth a + + module B where + import A + + instance C (Maybe Int) where + meth _ = "Int" + + main = putStrLn $ f (Just 42 :: Maybe Int) True + +Running main without optimisations yields "Int", the correct answer. +Activating optimisations yields "Maybe" due to a rewrite rule in module +A generated by the SPECIALISE pragma: + + RULE "USPEC f" forall a (d :: C a). f @a d = $sf + +In B we get the call (f @(Maybe Int) (d :: C (Maybe Int))), and +that rewrites to $sf, but that isn't really right. + +Overlapping instances mean that `C (Maybe Int)` is not a singleton +type: there two distinct dictionaries that have this type. And that +spells trouble for specialistion, which really asssumes singleton +types. + +For now, we just accept this problem, but it may bite us one day. +One solution would be to decline to expose any specialisation rules +to an importing module -- but that seems a bit drastic. + + ************************************************************************ * * \subsubsection{The new specialiser} @@ -802,8 +845,12 @@ spec_import top_env callers rb dict_binds cis@(CIS fn _) canSpecImport :: DynFlags -> Id -> Maybe CoreExpr canSpecImport dflags fn + | isDataConWrapId fn + = Nothing -- Don't specialise data-con wrappers, even if they + -- have dict args; there is no benefit. + | CoreUnfolding { uf_tmpl = rhs } <- unf - -- See Note [Specialising imported functions] point (1). + -- CoreUnfolding: see Note [Specialising imported functions] point (1). , isAnyInlinePragma (idInlinePragma fn) -- See Note [Specialising imported functions] point (2). = Just rhs @@ -1506,12 +1553,12 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs | otherwise -- No calls or RHS doesn't fit our preconceptions = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me) - "Missed specialisation opportunity" (ppr fn $$ _trace_doc) $ + "Missed specialisation opportunity for" (ppr fn $$ trace_doc) $ -- Note [Specialisation shape] -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] fn_type = idType fn fn_arity = idArity fn @@ -1575,8 +1622,16 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs else 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_bndrs1 ++ leftover_bndrs) rhs_body - ; let spec_fn_ty1 = exprType spec_rhs1 + ; (rhs_body', rhs_uds) <- specExpr rhs_env2 rhs_body + -- Add the { d1' = dx1; d2' = dx2 } usage stuff + -- to the rhs_uds; see Note [Specialising Calls] + ; let rhs_uds_w_dx = foldr consDictBind rhs_uds dx_binds + spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs + (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx + spec_rhs1 = mkLams spec_rhs_bndrs $ + wrapDictBindsE dumped_dbs rhs_body' + + spec_fn_ty1 = exprType spec_rhs1 -- Maybe add a void arg to the specialised function, -- to avoid unlifted bindings @@ -1610,10 +1665,6 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - -- Add the { d1' = dx1; d2' = dx2 } usage stuff - -- See Note [Specialising Calls] - spec_uds = foldr consDictBind rhs_uds dx_binds - simpl_opts = initSimpleOpts dflags -------------------------------------- @@ -1796,11 +1847,23 @@ in the specialisation: {-# 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: +worker/wrapper, anyway, but it’s easy to do. - 1. We don’t specialise on them. - 2. They come before an argument we do specialise on. +Wrinkles + +* Note 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. + +* If the function has a stable unfolding, specHeader has to come up with + arguments to pass to that stable unfolding, when building the stable + unfolding of the specialised function: this is the last field in specHeader's + big result tuple. The right thing to do is to produce a LitRubbish; it should rapidly disappear. Rather like GHC.Core.Opt.WorkWrap.Utils.mk_absent_let. @@ -2251,11 +2314,11 @@ instance Outputable SpecArg where 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 +specArgFreeIds :: SpecArg -> IdSet +specArgFreeIds (SpecType {}) = emptyVarSet +specArgFreeIds (SpecDict dx) = exprFreeIds dx +specArgFreeIds UnspecType = emptyVarSet +specArgFreeIds UnspecArg = emptyVarSet isSpecDict :: SpecArg -> Bool isSpecDict (SpecDict {}) = True @@ -2325,24 +2388,30 @@ specHeader , [OutBndr] -- Binders for $sf , [DictBind] -- Auxiliary dictionary bindings , [OutExpr] -- Specialised arguments for unfolding - -- Same length as "args for LHS of rule" + -- Same length as "Args for LHS of rule" ) -- 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 +specHeader env (bndr : bndrs) (SpecType ty : args) + = do { let in_scope = Core.getSubstInScope (se_subst env) + qvars = scopedSort $ + filterOut (`elemInScopeSet` in_scope) $ + tyCoVarsOfTypeList ty + (env1, qvars') = substBndrs env qvars + ty' = substTy env1 ty + env2 = extendTvSubstList env1 [(bndr, ty')] + ; (useful, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env2 bndrs args ; pure ( useful - , env'' + , env3 , leftover_bndrs - , rule_bs - , Type t : rule_es - , bs' + , qvars' ++ rule_bs + , Type ty' : rule_es + , qvars' ++ bs' , dx - , Type t : spec_args + , Type ty' : spec_args ) } @@ -2369,6 +2438,7 @@ specHeader env (bndr : bndrs) (UnspecType : args) -- 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) + | not (isDeadBinder bndr) = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) @@ -2385,29 +2455,44 @@ specHeader env (bndr : bndrs) (SpecDict d : 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. +-- Finally, we don't want to specialise on this argument 'i': +-- - It's an UnSpecArg, or +-- - It's a dead dictionary +-- 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) +specHeader env (bndr : bndrs) (_ : args) + -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead = 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 + + ; let bndr_ty = idType bndr' + + -- See Note [Drop dead args from specialisations] + -- C.f. GHC.Core.Opt.WorkWrap.Utils.mk_absent_let + (mb_spec_bndr, spec_arg) + | isDeadBinder bndr + , Just lit_expr <- mkLitRubbish bndr_ty + = (Nothing, lit_expr) + | otherwise + = (Just bndr', varToCoreExpr bndr') + ; 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' + , case mb_spec_bndr of + Just b' -> b' : bs' + Nothing -> bs' , dx - , varToCoreExpr bndr' : spec_args + , spec_arg : spec_args ) } @@ -2533,6 +2618,88 @@ successfully specialise 'f'. So the DictBinds in (ud_binds :: OrdList DictBind) may contain non-dictionary bindings too. + +Note [Specialising polymorphic dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + class M a where { foo :: a -> Int } + + instance M (ST s) where ... + -- dMST :: forall s. M (ST s) + + wimwam :: forall a. M a => a -> Int + wimwam = /\a \(d::M a). body + + f :: ST s -> Int + f = /\s \(x::ST s). wimwam @(ST s) (dMST @s) dx + 1 + +We'd like to specialise wimwam at (ST s), thus + $swimwam :: forall s. ST s -> Int + $swimwam = /\s. body[ST s/a, (dMST @s)/d] + + RULE forall s (d :: M (ST s)). + wimwam @(ST s) d = $swimwam @s + +Here are the moving parts: + +* We must /not/ dump the CallInfo + CIS wimwam (CI { ci_key = [@(ST s), dMST @s] + , ci_fvs = {dMST} }) + when we come to the /\s. Instead, we simply let it continue to float + upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that + are free in the call, but not the /TyVars/. Hence using specArgFreeIds + in singleCall. + + NB to be fully kosher we should explicitly quantifying the CallInfo + over 's', but we don't bother. This would matter if there was an + enclosing binding of the same 's', which I don't expect to happen. + +* Whe we come to specialise the call, we must remember to quantify + over 's'. That is done in the SpecType case of specHeader, where + we add 's' (called qvars) to the binders of the RULE and the specialised + function. + +* If we have f :: forall m. Monoid m => blah, and two calls + (f @(Endo b) (d :: Monoid (Endo b)) + (f @(Endo (c->c)) (d :: Monoid (Endo (c->c))) + we want to generate a specialisation only for the first. The second + is just a substitution instance of the first, with no greater specialisation. + Hence the call to `remove_dups` in `filterCalls`. + +All this arose in #13873, in the unexpected form that a SPECIALISE +pragma made the program slower! The reason was that the specialised +function $sinsertWith arising from the pragma looked rather like `f` +above, and failed to specialise a call in its body like wimwam. +Without the pragma, the original call to `insertWith` was completely +monomorpic, and specialised in one go. + +Wrinkles. + +* With -XOverlappingInstances you might worry about this: + class C a where ... + instance C (Maybe Int) where ... -- $df1 :: C (Maybe Int) + instance C (Maybe a) where ... -- $df2 :: forall a. C (Maybe a) + + f :: C a => blah + f = rhs + + g = /\a. ...(f @(Maybe a) ($df2 a))... + h = ...f @(Maybe Int) $df1 + + There are two calls to f, but with different evidence. This patch will + combine them into one. But it's OK: this code will never arise unless you + use -XIncoherentInstances. Even with -XOverlappingInstances, GHC tries hard + to keep dictionaries as singleton types. But that goes out of the window + with -XIncoherentInstances -- and that is true even with ordianry type-class + specialisation (at least if any inlining has taken place). + + GHC makes very few guarantees when you use -XIncoherentInstances, and its + not worth crippling the normal case for the incoherent corner. (The best + thing might be to switch off specialisation altogether if incoherence is + involved... but incoherence is a property of an instance, not a class, so + it's a hard test to make.) + + But see Note [Specialisation and overlapping instances]. -} instance Outputable DictBind where @@ -2571,8 +2738,9 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments , ci_fvs :: IdSet -- Free Ids of the ci_key call - -- _not_ including the main id itself, of course + -- /not/ including the main id itself, of course -- NB: excluding tyvars: + -- See Note [Specialising polymorphic dictionaries] } type DictExpr = CoreExpr @@ -2621,7 +2789,7 @@ singleCall id args unitBag (CI { ci_key = args -- used to be tys , ci_fvs = call_fvs }) } where - call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args + call_fvs = foldr (unionVarSet . specArgFreeIds) 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 @@ -2951,15 +3119,15 @@ callsForMe fn uds at MkUD { ud_binds = orig_dbs, ud_calls = orig_calls } ---------------------- filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo] --- Remove dominated calls +-- Remove dominated calls (Note [Specialising polymorphic dictionaries]) -- and loopy DFuns (Note [Avoiding loops (DFuns)]) filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) | isDFunId fn -- Note [Avoiding loops (DFuns)] applies only to DFuns - = filter ok_call unfiltered_calls + = filter ok_call de_dupd_calls | otherwise -- Do not apply it to non-DFuns - = unfiltered_calls -- See Note [Avoiding loops (non-DFuns)] + = de_dupd_calls -- See Note [Avoiding loops (non-DFuns)] where - unfiltered_calls = bagToList call_bag + de_dupd_calls = remove_dups call_bag dump_set = foldl' go (unitVarSet fn) dbs -- This dump-set could also be computed by splitDictBinds @@ -2973,6 +3141,29 @@ filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set +remove_dups :: Bag CallInfo -> [CallInfo] +remove_dups calls = foldr add [] calls + where + add :: CallInfo -> [CallInfo] -> [CallInfo] + add ci [] = [ci] + add ci1 (ci2:cis) | ci2 `beats_or_same` ci1 = ci2:cis + | ci1 `beats_or_same` ci2 = ci1:cis + | otherwise = ci2 : add ci1 cis + +beats_or_same :: CallInfo -> CallInfo -> Bool +beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 }) + = go args1 args2 + where + go [] _ = True + go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2 + go (_:_) [] = False + + go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2) + go_arg UnspecType UnspecType = True + go_arg (SpecDict {}) (SpecDict {}) = True + go_arg UnspecArg UnspecArg = True + go_arg _ _ = False + ---------------------- splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet) -- splitDictBinds dbs bndrs returns @@ -3003,15 +3194,18 @@ splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set ---------------------- deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails --- Remove calls *mentioning* bs in any way -deleteCallsMentioning bs calls +-- Remove calls mentioning any Id in bndrs +-- NB: The call is allowed to mention TyVars in bndrs +-- Note [Specialising polymorphic dictionaries] +-- ci_fvs are just the free /Ids/ +deleteCallsMentioning bndrs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs deleteCallsFor :: [Id] -> CallDetails -> CallDetails --- Remove calls *for* bs -deleteCallsFor bs calls = delDVarEnvList calls bs +-- Remove calls *for* bndrs +deleteCallsFor bndrs calls = delDVarEnvList calls bndrs {- ************************************************************************ ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -26,7 +26,8 @@ module GHC.Core.Subst ( extendIdSubstWithClone, extendSubst, extendSubstList, extendSubstWithVar, extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, - isInScope, setInScope, extendTvSubst, extendCvSubst, + isInScope, setInScope, getSubstInScope, + extendTvSubst, extendCvSubst, delBndr, delBndrs, zapSubst, -- ** Substituting and cloning binders @@ -41,7 +42,6 @@ import GHC.Core import GHC.Core.FVs import GHC.Core.Seq import GHC.Core.Utils -import GHC.Core.TyCo.Subst ( substCo ) -- We are defining local versions import GHC.Core.Type hiding ( substTy ) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -219,7 +219,7 @@ module GHC.Core.Type ( substTyAddInScope, substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked, substThetaUnchecked, substTyWithUnchecked, - substCoUnchecked, substCoWithUnchecked, + substCo, substCoUnchecked, substCoWithUnchecked, substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars, substVarBndr, substVarBndrs, substTyCoBndr, ===================================== compiler/GHC/Utils/Json.hs ===================================== @@ -14,6 +14,7 @@ data JsonDoc where JSBool :: Bool -> JsonDoc JSInt :: Int -> JsonDoc JSString :: String -> JsonDoc + -- ^ The 'String' is unescaped JSArray :: [JsonDoc] -> JsonDoc JSObject :: [(String, JsonDoc)] -> JsonDoc @@ -57,7 +58,7 @@ class ToJson a where json :: a -> JsonDoc instance ToJson String where - json = JSString . escapeJsonString + json = JSString instance ToJson Int where json = JSInt ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -163,7 +163,10 @@ mapSndM = traverse . traverse -- | Monadic version of concatMap concatMapM :: (Monad m, Traversable f) => (a -> m [b]) -> f a -> m [b] concatMapM f xs = liftM concat (mapM f xs) -{-# SPECIALIZE concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] #-} +{-# INLINE concatMapM #-} +-- It's better to inline to inline this than to specialise +-- concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b] +-- Inlining cuts compiler allocation by around 1% -- | Applicative version of mapMaybe mapMaybeM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] ===================================== testsuite/tests/lib/integer/Makefile ===================================== @@ -11,8 +11,9 @@ CHECK2 = grep -q -- '$1' folding.simpl || \ .PHONY: integerConstantFolding integerConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make integerConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } $(call CHECK,\<200007\>,plusInteger) $(call CHECK,\<683234160\>,timesInteger) @@ -64,8 +65,9 @@ IntegerConversionRules: .PHONY: naturalConstantFolding naturalConstantFolding: - '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl > folding.simpl + '$(TEST_HC)' -Wall -v0 -O --make naturalConstantFolding -fforce-recomp -ddump-simpl -dno-debug-output > folding.simpl # All the 100nnn values should be constant-folded away +# -dno-debug-output suppresses a "Glomming" message ! grep -q '\<100[0-9][0-9][0-9]\>' folding.simpl || { echo "Unfolded values found"; grep '\<100[0-9][0-9][0-9]\>' folding.simpl; } # Bit arithmetic $(call CHECK,\<532\>,andNatural) ===================================== testsuite/tests/linters/notes.stdout ===================================== @@ -2,7 +2,6 @@ ref compiler/GHC/Core/Coercion/Axiom.hs:461:2: Note [RoughMap and rm_empt ref compiler/GHC/Core/Opt/OccurAnal.hs:857:15: Note [Loop breaking] ref compiler/GHC/Core/Opt/SetLevels.hs:1580:30: Note [Top level scope] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:2675:13: Note [Case binder next] -ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3303:0: Note [Suppressing binder-swaps on linear case] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3854:8: Note [Lambda-bound unfoldings] ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1257:37: Note [Gentle mode] ref compiler/GHC/Core/Opt/Specialise.hs:1623:28: Note [Arity decrease] ===================================== testsuite/tests/numeric/should_compile/T19641.stderr ===================================== @@ -3,30 +3,30 @@ Result size of Tidy Core = {terms: 22, types: 20, coercions: 0, joins: 0/0} -integer_to_int +natural_to_word = \ eta -> case eta of { - IS ipv -> Just (I# ipv); - IP x1 -> Nothing; - IN ds -> Nothing + NS x1 -> Just (W# x1); + NB ds -> Nothing } -natural_to_word +integer_to_int = \ eta -> case eta of { - NS x1 -> Just (W# x1); - NB ds -> Nothing + IS ipv -> Just (I# ipv); + IP x1 -> Nothing; + IN ds -> Nothing } ------ Local rules for imported ids -------- -"SPEC/Test toIntegralSized @Natural @Word" - forall $dIntegral $dIntegral1 $dBits $dBits1. - toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 - = natural_to_word "SPEC/Test toIntegralSized @Integer @Int" forall $dIntegral $dIntegral1 $dBits $dBits1. toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 = integer_to_int +"SPEC/Test toIntegralSized @Natural @Word" + forall $dIntegral $dIntegral1 $dBits $dBits1. + toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 + = natural_to_word ===================================== testsuite/tests/simplCore/should_compile/T21851.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl #-} + +module T21851 (g') where +import T21851a + +g :: Num a => a -> a +g x = fst (f x) +{-# NOINLINE[99] g #-} + +g' :: Int -> Int +g' = g + +-- We should see a call to a /specialised/ verion of `f`, +-- something like +-- g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -0,0 +1,19 @@ +[1 of 2] Compiling T21851a ( T21851a.hs, T21851a.o ) +[2 of 2] Compiling T21851 ( T21851.hs, T21851.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 7, types: 10, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} +g' :: Int -> Int +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] +g' + = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } + + + ===================================== testsuite/tests/simplCore/should_compile/T21851a.hs ===================================== @@ -0,0 +1,5 @@ +module T21851a where + +f :: Num b => b -> (b, b) -- note: recursive to prevent inlining +f x = (x + 1, snd (f x)) -- on such a small example +{-# SPECIALIZE f :: Int -> (Int, Int) #-} ===================================== testsuite/tests/simplCore/should_compile/T22097.hs ===================================== @@ -0,0 +1,7 @@ +{-# OPTIONS_GHC -ddump-simpl #-} +{-# LANGUAGE TypeApplications #-} +module T22097 where +import T22097a ( isEven ) + +main :: IO () +main = print $ isEven @Int 10 ===================================== testsuite/tests/simplCore/should_compile/T22097.stderr ===================================== @@ -0,0 +1,46 @@ +[1 of 2] Compiling T22097a ( T22097a.hs, T22097a.o ) +[2 of 2] Compiling T22097 ( T22097.hs, T22097.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 15, types: 14, coercions: 3, joins: 0/0} + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +T22097.main2 :: String +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +T22097.main2 + = case T22097a.$wgoEven 10# of { (# #) -> GHC.Show.$fShowBool4 } + +-- RHS size: {terms: 6, types: 2, coercions: 0, joins: 0/0} +T22097.main1 + :: GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #) +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 40 0}] +T22097.main1 + = \ (eta [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + GHC.IO.Handle.Text.hPutStr2 + GHC.IO.Handle.FD.stdout T22097.main2 GHC.Types.True eta + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +main :: IO () +[GblId, + Arity=1, + Str=, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +main + = T22097.main1 + `cast` (Sym (GHC.Types.N:IO[0] <()>_R) + :: (GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)) + ~R# IO ()) + + + ===================================== testsuite/tests/simplCore/should_compile/T22097a.hs ===================================== @@ -0,0 +1,23 @@ +module T22097a + ( isEven, isOdd ) +where + +{-# SPECIALIZE isEven :: Int -> Bool #-} +isEven :: Integral a => a -> Bool +isEven = fst evenOdd + +{-# SPECIALIZE isOdd :: Int -> Bool #-} +isOdd :: Integral a => a -> Bool +isOdd = snd evenOdd + +evenOdd :: Integral a => (a -> Bool, a -> Bool) +evenOdd = (goEven, goOdd) + where + goEven n + | n < 0 = goEven (- n) + | n > 0 = goOdd (n - 1) + | otherwise = True + + goOdd n + | n < 0 = goOdd n + | otherwise = goEven n ===================================== testsuite/tests/simplCore/should_compile/T6056.stderr ===================================== @@ -1,4 +1,4 @@ Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) -Rule fired: SPEC/T6056 $wsmallerAndRest @Int (T6056) +Rule fired: SPEC/T6056 smallerAndRest @Int (T6056) ===================================== testsuite/tests/simplCore/should_compile/T8331.stderr ===================================== @@ -1,5 +1,60 @@ ==================== Tidy Core rules ==================== +"SPEC $c*> @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$c*> @(ST s) @r $dApplicative + = ($fApplicativeReaderT3 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s b) + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) b)) +"SPEC $c>> @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT1 @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$c>> @s @r +"SPEC $cliftA2 @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cliftA2 @(ST s) @r $dApplicative + = ($fApplicativeReaderT1 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N) (c :: <*>_N). + b -> c>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s c) + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) c)) +"SPEC $cp1Applicative @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cp1Applicative @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $cp1Monad @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT_$cp1Monad @(ST s) @r $dMonad + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $fApplicativeReaderT @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $fFunctorReaderT @(ST s) @_" + forall (@s) (@r) ($dFunctor :: Functor (ST s)). + $fFunctorReaderT @(ST s) @r $dFunctor + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $fMonadReaderT @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$fMonadReaderT @s @r "USPEC useAbstractMonad @(ReaderT Int (ST s))" forall (@s) ($dMonadAbstractIOST :: MonadAbstractIOST (ReaderT Int (ST s))). ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -359,7 +359,6 @@ test('T19586', normal, compile, ['']) test('T19599', normal, compile, ['-O -ddump-rules']) test('T19599a', normal, compile, ['-O -ddump-rules']) -test('T13873', [expect_broken(21229), grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) # Look for a specialisation rule for wimwam test('T19672', normal, compile, ['-O2 -ddump-rules']) @@ -430,3 +429,10 @@ test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# One module, T21851.hs, has OPTIONS_GHC -ddump-simpl +test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) +# One module, T22097.hs, has OPTIONS_GHC -ddump-simpl +test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) + +test('T13873', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/06a937f784301f9522f20cc1a2d3c821e7f3175b...3c4220c96942ff003fe75949af7188ee0438b467 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/06a937f784301f9522f20cc1a2d3c821e7f3175b...3c4220c96942ff003fe75949af7188ee0438b467 You're receiving 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 Oct 11 07:56:17 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Tue, 11 Oct 2022 03:56:17 -0400 Subject: [Git][ghc/ghc][wip/fragile-T7919] 12 commits: chore: extend `.editorconfig` for C files Message-ID: <634521a19dac3_1eea6a6375ad881009978@gitlab.mail> Bryan R pushed to branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 5072e6c3 by Bryan Richter at 2022-10-11T10:56:09+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - libraries/base/tools/ucd2haskell/ucd.sh - rts/include/Stg.h - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - testsuite/tests/lib/integer/Makefile - testsuite/tests/rts/all.T - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/336554c60d35014c9e443a17e491cb6326f57800...5072e6c34af3e526476b17320614193061845b3b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/336554c60d35014c9e443a17e491cb6326f57800...5072e6c34af3e526476b17320614193061845b3b You're receiving 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 Oct 11 08:44:16 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 11 Oct 2022 04:44:16 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/21619 Message-ID: <63452ce0ba0a7_1eea6a5181c224101637b@gitlab.mail> Matthew Pickering pushed new branch wip/21619 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/21619 You're receiving 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 Oct 11 08:48:50 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 11 Oct 2022 04:48:50 -0400 Subject: [Git][ghc/ghc][wip/21619] Alternative solution Message-ID: <63452df26d555_1eea6a514c8101844e@gitlab.mail> Matthew Pickering pushed to branch wip/21619 at Glasgow Haskell Compiler / GHC Commits: 183219f5 by Matthew Pickering at 2022-10-11T09:48:39+01:00 Alternative solution - - - - - 2 changed files: - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Iface/Ext/Ast.hs Changes: ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -133,7 +133,7 @@ hsExprType (HsTypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType (HsUntypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty -- This is ugly but HsSpliced things here are not real, they are inserted -- by GHC.Tc.Gen.Splice as an application of unType applied to the original expression. -hsExprType (HsSpliceE _ (HsSpliced _ _ (HsSplicedExpr (HsApp _ _e1 e2)))) = pprTrace "loc" callStackDoc $ pprTraceIt "ty" $ lhsExprType e2 +--hsExprType (HsSpliceE _ (HsSpliced _ _ (HsSplicedExpr (HsApp _ _e1 e2)))) = pprTrace "loc" callStackDoc $ pprTraceIt "ty" $ lhsExprType e2 hsExprType e@(HsSpliceE{}) = pprPanic "hsExprType: Unexpected HsSpliceE" (ppr e) hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1192,8 +1192,8 @@ instance HiePass p => ToHie (LocatedA (HsExpr (GhcPass p))) where [ toHie b ] HieTc | HsBracketTc _ _ _ p <- xbracket -> - [ toHie b - , toHie p + [ -- toHie b + toHie p ] HsUntypedBracket xbracket b -> case hiePass @p of HieRn -> View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/183219f590910a46edf0b27a64e0e8d05e524dd1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/183219f590910a46edf0b27a64e0e8d05e524dd1 You're receiving 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 Oct 11 09:42:57 2022 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 11 Oct 2022 05:42:57 -0400 Subject: [Git][ghc/ghc][wip/T22218] 12 commits: chore: extend `.editorconfig` for C files Message-ID: <63453aa1cb819_1eea6a5141410349d8@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T22218 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - b4e96b2d by Krzysztof Gogolewski at 2022-10-11T11:16:06+02:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - libraries/base/tools/ucd2haskell/ucd.sh - rts/include/Stg.h - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - testsuite/tests/lib/integer/Makefile - + testsuite/tests/simplCore/should_compile/T21851.hs - + testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851a.hs - + testsuite/tests/simplCore/should_compile/T22097.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6bb944bad600b5fbe378a28d454816ab5da9adb...b4e96b2d129096882a46976f705de5af131778a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6bb944bad600b5fbe378a28d454816ab5da9adb...b4e96b2d129096882a46976f705de5af131778a7 You're receiving 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 Oct 11 09:48:28 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 05:48:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Utils.JSON: do not escapeJsonString in ToJson String instance Message-ID: <63453bec4d689_1eea6a5141410352dc@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 3ab55b59 by Matthew Pickering at 2022-10-11T05:48:12-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - 449ca867 by Matthew Pickering at 2022-10-11T05:48:12-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - d695e730 by Matthew Pickering at 2022-10-11T05:48:12-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - 87aaea11 by Matthew Pickering at 2022-10-11T05:48:15-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - 30 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Unit/Home/ModInfo.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Unit/Module/Status.hs - + compiler/GHC/Unit/Module/WholeCoreBindings.hs - compiler/GHC/Utils/Binary.hs - compiler/GHC/Utils/Json.hs - compiler/ghc.cabal.in - docs/users_guide/phases.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6085913ec38ecead100fbe186ae77291fb8e4db...87aaea11565de48ad6523b99c31a9bb2c73ce269 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f6085913ec38ecead100fbe186ae77291fb8e4db...87aaea11565de48ad6523b99c31a9bb2c73ce269 You're receiving 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 Oct 11 10:10:06 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Oct 2022 06:10:06 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Fix function name from h$shrinkMutableArray to h$shrinkMutableCharArray Message-ID: <634540fee003a_1eea6a529f4f8c104631b@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 6e55c56f by Josh Meredith at 2022-10-11T10:09:07+00:00 Fix function name from h$shrinkMutableArray to h$shrinkMutableCharArray - - - - - 1 changed file: - rts/js/mem.js Changes: ===================================== rts/js/mem.js ===================================== @@ -1007,7 +1007,7 @@ function h$shrinkMutableByteArray(a, n) { } } -function h$shrinkMutableArray(a, n) { +function h$shrinkMutableCharArray(a, n) { a.length = n; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e55c56f36fb8c2ad30314bcddabf3f63fecfc83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e55c56f36fb8c2ad30314bcddabf3f63fecfc83 You're receiving 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 Oct 11 10:22:33 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 06:22:33 -0400 Subject: [Git][ghc/ghc][wip/T21851] 299 commits: driver: Fix implementation of -S Message-ID: <634543e9d91b6_1eea6a5fada5c0106611f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851 at Glasgow Haskell Compiler / GHC Commits: e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - c0829eb5 by Simon Peyton Jones at 2022-10-11T11:24:32+01:00 Fire RULES in the Specialiser A draft patch for #21851 - - - - - 30 changed files: - − .appveyor.sh - .editorconfig - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/CodeGen.Platform.h - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28b335b62f1beb8458a3e2a72174bb75dcd82adf...c0829eb5511b66e135c258300b904c684e64db9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28b335b62f1beb8458a3e2a72174bb75dcd82adf...c0829eb5511b66e135c258300b904c684e64db9a You're receiving 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 Oct 11 10:46:27 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Tue, 11 Oct 2022 06:46:27 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Decode and test underflow frames Message-ID: <63454983620d5_1eea6a514c8108474a@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: a3dacb40 by Sven Tennie at 2022-10-11T10:45:17+00:00 Decode and test underflow frames - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm - libraries/ghc-heap/tests/all.T - testsuite/tests/rts/all.T Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -41,6 +41,9 @@ data StackFrameIter = StackFrameIter StackFrameIter# instance Show StackFrameIter where show (StackFrameIter (# _, i# #)) = "StackFrameIter " ++ "(StackSnapshot _" ++ " " ++ show (W# i#) +instance Show StackSnapshot where + show _ = "StackSnapshot _" + -- | Get an interator starting with the top-most stack frame stackHead :: StackSnapshot -> StackFrameIter stackHead (StackSnapshot s) = StackFrameIter (# s , 0## #) -- GHC stacks are never empty @@ -136,7 +139,10 @@ unpackStackFrameIter sfi@(StackFrameIter (# s#, i# #)) = exceptionsBlocked = W# (getCatchFrameExceptionsBlocked# s# i#) in CatchFrame exceptionsBlocked c - UNDERFLOW_FRAME -> UnderflowFrame + UNDERFLOW_FRAME -> let + nextChunk# = getUnderflowFrameNextChunk# s# i# + in + UnderflowFrame (StackSnapshot nextChunk#) STOP_FRAME -> StopFrame ATOMICALLY_FRAME -> AtomicallyFrame CATCH_RETRY_FRAME -> CatchRetryFrame @@ -179,6 +185,8 @@ foreign import prim "unpackHandlerFromCatchFramezh" unpackHandlerFromCatchFrame# foreign import prim "getCatchFrameExceptionsBlockedzh" getCatchFrameExceptionsBlocked# :: StackSnapshot# -> Word# -> Word# +foreign import prim "getUnderflowFrameNextChunkzh" getUnderflowFrameNextChunk# :: StackSnapshot# -> Word# -> StackSnapshot# + data BitmapPayload = Closure CL.Closure | Primitive Word instance Show BitmapPayload where @@ -222,7 +230,7 @@ data StackFrame = CatchStmFrame | CatchRetryFrame | AtomicallyFrame | - UnderflowFrame | + UnderflowFrame { nextChunk:: StackSnapshot } | StopFrame | RetSmall SpecialRetSmall [BitmapPayload] | RetBig [BitmapPayload] | ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -147,8 +147,12 @@ StgArrBytes* getLargeBitmaps(Capability *cap, StgClosure *c){ } #if defined(DEBUG) -extern void printStack ( StgStack *stack ); +extern void printStack (StgStack *stack); void belchStack(StgStack* stack){ printStack(stack); } #endif + +StgStack* getUnderflowFrameNextChunk(StgUnderflowFrame* frame){ + return frame->next_chunk; +} ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -28,7 +28,7 @@ advanceStackFrameIterzh (P_ stack, W_ index) { stackBottom = stackSizeInBytes + stackArrayPtr; if(nextClosurePtr < stackBottom) (likely: True) { - ccall debugBelch("advanceStackFrameIterzh - ordinary frame \n"); + // ccall debugBelch("advanceStackFrameIterzh - ordinary frame \n"); newStack = stack; newIndex = index + frameSize; hasNext = 1; @@ -36,12 +36,12 @@ advanceStackFrameIterzh (P_ stack, W_ index) { P_ underflowFrameStack; (underflowFrameStack) = ccall getUnderflowFrameStack(stack, index); if (underflowFrameStack == NULL) (likely: True) { - ccall debugBelch("advanceStackFrameIterzh - last frame \n"); + // ccall debugBelch("advanceStackFrameIterzh - last frame \n"); newStack = NULL; newIndex = NULL; hasNext = NULL; } else { - ccall debugBelch("advanceStackFrameIterzh - overflow frame \n"); + // ccall debugBelch("advanceStackFrameIterzh - underflow frame \n"); newStack = underflowFrameStack; newIndex = NULL; hasNext = 1; @@ -49,12 +49,14 @@ advanceStackFrameIterzh (P_ stack, W_ index) { } // TODO: Execute this block only in -DDEBUG +#if DEBUG if(hasNext > 0) { P_ nextClosure; nextClosure = StgStack_sp(stack) + WDS(index); ASSERT(LOOKS_LIKE_CLOSURE_PTR(nextClosure)); ccall checkSTACK(stack); } +#endif // ccall debugBelch("advanceStackFrameIterzh - stack %p, newStack %p, frameSize %ul, newIdex %ul, hasNext %ul, stackBottom %p\n", stack, newStack, frameSize, newIndex, hasNext, stackBottom); return (newStack, newIndex, hasNext); @@ -154,3 +156,14 @@ getCatchFrameExceptionsBlockedzh(P_ stack, W_ index){ exceptions_blocked = StgCatchFrame_exceptions_blocked(closurePtr); return (exceptions_blocked); } + +getUnderflowFrameNextChunkzh(P_ stack, W_ index){ + P_ closurePtr, closurePtrPrime, updateePtr; + closurePtr = (StgStack_sp(stack) + WDS(index)); + ASSERT(LOOKS_LIKE_CLOURE_PTR(closurePtr)); + + P_ next_chunk; + (next_chunk) = ccall getUnderflowFrameNextChunk(closurePtr); + ASSERT(LOOKS_LIKE_CLOURE_PTR(next_chunk)); + return (next_chunk); +} ===================================== libraries/ghc-heap/tests/all.T ===================================== @@ -64,3 +64,13 @@ test('decode_cloned_stack', test('decode_cloned_stack_big_ret', [only_ways(['normal'])], compile_and_run, ['-debug -optc-g -g -DDEBUG']) + +# Options: +# - `-kc512B -kb64B`: Make stack chunk size small to provoke underflow stack frames. +test('stack_underflow', + [ + extra_run_opts('+RTS -kc512B -kb64B -RTS'), + ignore_stdout, + ignore_stderr + ], + compile_and_run, ['-rtsopts']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -508,6 +508,7 @@ test('cloneMyStack2', ignore_stdout, compile_and_run, ['']) test('cloneMyStack_retBigStackFrame', [extra_files(['cloneStackLib.c']), ignore_stdout], compile_and_run, ['cloneStackLib.c']) test('cloneThreadStack', [only_ways(['threaded1']), extra_ways(['threaded1']), extra_files(['cloneStackLib.c'])], compile_and_run, ['cloneStackLib.c -threaded']) test('decodeMyStack', normal, compile_and_run, ['-finfo-table-map']) +# TODO: This comment is wrong! 8K is not the minimum of -kc (though, -kb has to be adjusted)! # Options: # - `-kc8K`: Set stack chunk size to it's minimum to provoke underflow stack frames. test('decodeMyStack_underflowFrames', [extra_run_opts('+RTS -kc8K -RTS')], compile_and_run, ['-finfo-table-map -rtsopts']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3dacb40265d711ae87dfa8e43ebdc252f88d95f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3dacb40265d711ae87dfa8e43ebdc252f88d95f You're receiving 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 Oct 11 10:46:42 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 11 Oct 2022 06:46:42 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mp-9.2.5-backports Message-ID: <63454992ba113_1eea6a5fada5c010849f@gitlab.mail> Matthew Pickering pushed new branch wip/mp-9.2.5-backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mp-9.2.5-backports You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Oct 11 12:00:16 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 08:00:16 -0400 Subject: [Git][ghc/ghc][wip/T21851] Fire RULES in the Specialiser Message-ID: <63455ad03078d_1eea6a5fc830fc1109765@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851 at Glasgow Haskell Compiler / GHC Commits: 91ef98bc by Simon Peyton Jones at 2022-10-11T13:02:07+01:00 Fire RULES in the Specialiser A draft patch for #21851 - - - - - 16 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Unit/External.hs - libraries/base/GHC/Real.hs - testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851c.hs - + testsuite/tests/simplCore/should_compile/T21851d.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -84,9 +84,8 @@ module GHC.Core ( IsOrphan(..), isOrphan, notOrphan, chooseOrphanAnchor, -- * Core rule data types - CoreRule(..), RuleBase, - RuleName, RuleFun, IdUnfoldingFun, InScopeEnv, - RuleEnv(..), RuleOpts, mkRuleEnv, emptyRuleEnv, + CoreRule(..), + RuleName, RuleFun, IdUnfoldingFun, InScopeEnv, RuleOpts, -- ** Operations on 'CoreRule's ruleArity, ruleName, ruleIdName, ruleActivation, @@ -104,7 +103,6 @@ import GHC.Core.Coercion import GHC.Core.Rules.Config ( RuleOpts ) import GHC.Types.Name import GHC.Types.Name.Set -import GHC.Types.Name.Env( NameEnv ) import GHC.Types.Literal import GHC.Types.Tickish import GHC.Core.DataCon @@ -1061,6 +1059,12 @@ has two major consequences M. But it's painful, because it means we need to keep track of all the orphan modules below us. + * The "visible orphan modules" are all the orphan module in the transitive + closure of the imports of this module. + + * During instance lookup, we filter orphan instances depending on + whether or not the instance is in a visible orphan module. + * A non-orphan is not finger-printed separately. Instead, for fingerprinting purposes it is treated as part of the entity it mentions on the LHS. For example @@ -1075,12 +1079,20 @@ has two major consequences Orphan-hood is computed * For class instances: - when we make a ClsInst - (because it is needed during instance lookup) + when we make a ClsInst in GHC.Core.InstEnv.mkLocalInstance + (because it is needed during instance lookup) + See Note [When exactly is an instance decl an orphan?] + in GHC.Core.InstEnv + + * For rules + when we generate a CoreRule (GHC.Core.Rules.mkRule) + + * For family instances: + when we generate an IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst) + +Orphan-hood is persisted into interface files, in ClsInst, FamInst, +and CoreRules. - * For rules and family instances: - when we generate an IfaceRule (GHC.Iface.Make.coreRuleToIfaceRule) - or IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst) -} {- @@ -1095,49 +1107,6 @@ GHC.Core.FVs, GHC.Core.Subst, GHC.Core.Ppr, GHC.Core.Tidy also inspect the representation. -} --- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules -type RuleBase = NameEnv [CoreRule] - -- The rules are unordered; - -- we sort out any overlaps on lookup - --- | A full rule environment which we can apply rules from. Like a 'RuleBase', --- but it also includes the set of visible orphans we use to filter out orphan --- rules which are not visible (even though we can see them...) -data RuleEnv - = RuleEnv { re_base :: [RuleBase] -- See Note [Why re_base is a list] - , re_visible_orphs :: ModuleSet - } - -mkRuleEnv :: RuleBase -> [Module] -> RuleEnv -mkRuleEnv rules vis_orphs = RuleEnv [rules] (mkModuleSet vis_orphs) - -emptyRuleEnv :: RuleEnv -emptyRuleEnv = RuleEnv [] emptyModuleSet - -{- -Note [Why re_base is a list] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Note [Overall plumbing for rules], it is explained that the final -RuleBase which we must consider is combined from 4 different sources. - -During simplifier runs, the fourth source of rules is constantly being updated -as new interfaces are loaded into the EPS. Therefore just before we check to see -if any rules match we get the EPS RuleBase and combine it with the existing RuleBase -and then perform exactly 1 lookup into the new map. - -It is more efficient to avoid combining the environments and store the uncombined -environments as we can instead perform 1 lookup into each environment and then combine -the results. - -Essentially we use the identity: - -> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) -> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 - -The latter being more efficient as we don't construct an intermediate -map. --} -- | A 'CoreRule' is: -- ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -319,7 +319,9 @@ mkImportedInstance cls_nm mb_tcs dfun_name dfun oflag orphan {- Note [When exactly is an instance decl an orphan?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - (see GHC.Iface.Make.instanceToIfaceInst, which implements this) +(See GHC.Iface.Make.instanceToIfaceInst, which implements this.) +See Note [Orphans] in GHC.Core + Roughly speaking, an instance is an orphan if its head (after the =>) mentions nothing defined in this module. ===================================== compiler/GHC/Core/Opt/Monad.hs ===================================== @@ -19,10 +19,10 @@ module GHC.Core.Opt.Monad ( -- ** Reading from the monad getHscEnv, getModule, - getRuleBase, getExternalRuleBase, + initRuleEnv, getExternalRuleBase, getDynFlags, getPackageFamInstEnv, getInteractiveContext, - getVisibleOrphanMods, getUniqMask, + getUniqMask, getPrintUnqualified, getSrcSpanM, -- ** Writing to the monad @@ -45,7 +45,7 @@ import GHC.Prelude hiding ( read ) import GHC.Driver.Session import GHC.Driver.Env -import GHC.Core +import GHC.Core.Rules ( RuleBase, RuleEnv, mkRuleEnv ) import GHC.Core.Opt.Stats ( SimplCount, zeroSimplCount, plusSimplCount ) import GHC.Types.Annotations @@ -113,12 +113,11 @@ pprFloatOutSwitches sw data CoreReader = CoreReader { cr_hsc_env :: HscEnv, - cr_rule_base :: RuleBase, + cr_rule_base :: RuleBase, -- Home package table rules cr_module :: Module, cr_print_unqual :: PrintUnqualified, cr_loc :: SrcSpan, -- Use this for log/error messages so they -- are at least tagged with the right source file - cr_visible_orphan_mods :: !ModuleSet, cr_uniq_mask :: !Char -- Mask for creating unique values } @@ -180,19 +179,17 @@ runCoreM :: HscEnv -> RuleBase -> Char -- ^ Mask -> Module - -> ModuleSet -> PrintUnqualified -> SrcSpan -> CoreM a -> IO (a, SimplCount) -runCoreM hsc_env rule_base mask mod orph_imps print_unqual loc m +runCoreM hsc_env rule_base mask mod print_unqual loc m = liftM extract $ runIOEnv reader $ unCoreM m where reader = CoreReader { cr_hsc_env = hsc_env, cr_rule_base = rule_base, cr_module = mod, - cr_visible_orphan_mods = orph_imps, cr_print_unqual = print_unqual, cr_loc = loc, cr_uniq_mask = mask @@ -244,15 +241,18 @@ liftIOWithCount what = liftIO what >>= (\(count, x) -> addSimplCount count >> re getHscEnv :: CoreM HscEnv getHscEnv = read cr_hsc_env -getRuleBase :: CoreM RuleBase -getRuleBase = read cr_rule_base +getHomeRuleBase :: CoreM RuleBase +getHomeRuleBase = read cr_rule_base + +initRuleEnv :: ModGuts -> CoreM RuleEnv +initRuleEnv guts + = do { hpt_rules <- getHomeRuleBase + ; eps_rules <- getExternalRuleBase + ; return (mkRuleEnv guts eps_rules hpt_rules) } getExternalRuleBase :: CoreM RuleBase getExternalRuleBase = eps_rule_base <$> get_eps -getVisibleOrphanMods :: CoreM ModuleSet -getVisibleOrphanMods = read cr_visible_orphan_mods - getPrintUnqualified :: CoreM PrintUnqualified getPrintUnqualified = read cr_print_unqual ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Platform.Ways ( hasWay, Way(WayProf) ) import GHC.Core import GHC.Core.Opt.CSE ( cseProgram ) -import GHC.Core.Rules ( mkRuleBase, ruleCheckProgram, getRules ) +import GHC.Core.Rules ( RuleBase, mkRuleBase, ruleCheckProgram, getRules ) import GHC.Core.Ppr ( pprCoreBindings ) import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.Lint ( lintAnnots ) @@ -52,9 +52,7 @@ import GHC.Utils.Logger as Logger import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Unit.Module.Env import GHC.Unit.Module.ModGuts -import GHC.Unit.Module.Deps import GHC.Types.Id.Info import GHC.Types.Basic @@ -77,14 +75,12 @@ import GHC.Unit.Module core2core :: HscEnv -> ModGuts -> IO ModGuts core2core hsc_env guts@(ModGuts { mg_module = mod , mg_loc = loc - , mg_deps = deps , mg_rdr_env = rdr_env }) = do { let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars - orph_mods = mkModuleSet (mod : dep_orphs deps) uniq_mask = 's' - ; + ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_mask mod - orph_mods print_unqual loc $ + print_unqual loc $ do { hsc_env' <- getHscEnv ; all_passes <- withPlugins (hsc_plugins hsc_env') installCoreToDos @@ -120,7 +116,8 @@ core2core hsc_env guts@(ModGuts { mg_module = mod -} getCoreToDo :: DynFlags -> RuleBase -> [Var] -> [CoreToDo] -getCoreToDo dflags rule_base extra_vars +-- This function builds the pipeline of optimisations +getCoreToDo dflags hpt_rule_base extra_vars = flatten_todos core_todo where phases = simplPhases dflags @@ -158,7 +155,7 @@ getCoreToDo dflags rule_base extra_vars = CoreDoPasses $ [ maybe_strictness_before phase , CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter - (initSimplMode dflags phase name) rule_base + (initSimplMode dflags phase name) hpt_rule_base , maybe_rule_check phase ] -- Run GHC's internal simplification phase, after all rules have run. @@ -169,7 +166,7 @@ getCoreToDo dflags rule_base extra_vars -- See Note [Inline in InitialPhase] -- See Note [RULEs enabled in InitialPhase] simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter - (initGentleSimplMode dflags) rule_base + (initGentleSimplMode dflags) hpt_rule_base dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] @@ -547,11 +544,9 @@ ruleCheckPass current_phase pat guts = do logger <- getLogger withTiming logger (text "RuleCheck"<+>brackets (ppr $ mg_module guts)) (const ()) $ do - rb <- getRuleBase - vis_orphs <- getVisibleOrphanMods - let rule_fn fn = getRules (RuleEnv [rb] vis_orphs) fn - ++ (mg_rules guts) - let ropts = initRuleOpts dflags + rule_env <- initRuleEnv guts + let rule_fn fn = getRules rule_env fn + ropts = initRuleOpts dflags liftIO $ logDumpMsg logger "Rule check" (ruleCheckProgram ropts current_phase pat rule_fn (mg_binds guts)) ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -10,7 +10,7 @@ import GHC.Prelude import GHC.Driver.Flags import GHC.Core -import GHC.Core.Rules ( extendRuleBaseList, extendRuleEnv, addRuleInfo ) +import GHC.Core.Rules import GHC.Core.Ppr ( pprCoreBindings, pprCoreExpr ) import GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr ) import GHC.Core.Stats ( coreBindsSize, coreBindsStats, exprSize ) @@ -32,7 +32,6 @@ import GHC.Utils.Trace import GHC.Unit.Env ( UnitEnv, ueEPS ) import GHC.Unit.External import GHC.Unit.Module.ModGuts -import GHC.Unit.Module.Deps import GHC.Types.Id import GHC.Types.Id.Info @@ -82,7 +81,7 @@ simplifyExpr logger euc opts expr simpl_env = mkSimplEnv (se_mode opts) fam_envs top_env_cfg = se_top_env_cfg opts read_eps_rules = eps_rule_base <$> eucEPS euc - read_ruleenv = extendRuleEnv emptyRuleEnv <$> read_eps_rules + read_ruleenv = updExternalPackageRules emptyRuleEnv <$> read_eps_rules ; let sz = exprSize expr @@ -133,11 +132,11 @@ simplExprGently env expr = do -- The values of this datatype are /only/ driven by the demands of that function. data SimplifyOpts = SimplifyOpts { so_dump_core_sizes :: !Bool - , so_iterations :: !Int - , so_mode :: !SimplMode + , so_iterations :: !Int + , so_mode :: !SimplMode , so_pass_result_cfg :: !(Maybe LintPassResultConfig) - , so_rule_base :: !RuleBase - , so_top_env_cfg :: !TopEnvConfig + , so_hpt_rules :: !RuleBase + , so_top_env_cfg :: !TopEnvConfig } simplifyPgm :: Logger @@ -149,11 +148,10 @@ simplifyPgm :: Logger simplifyPgm logger unit_env opts guts@(ModGuts { mg_module = this_mod , mg_rdr_env = rdr_env - , mg_deps = deps - , mg_binds = binds, mg_rules = rules + , mg_binds = binds, mg_rules = local_rules , mg_fam_inst_env = fam_inst_env }) = do { (termination_msg, it_count, counts_out, guts') - <- do_iteration 1 [] binds rules + <- do_iteration 1 [] binds local_rules ; when (logHasDumpFlag logger Opt_D_verbose_core2core && logHasDumpFlag logger Opt_D_dump_simpl_stats) $ @@ -170,7 +168,6 @@ simplifyPgm logger unit_env opts dump_core_sizes = so_dump_core_sizes opts mode = so_mode opts max_iterations = so_iterations opts - hpt_rule_base = so_rule_base opts top_env_cfg = so_top_env_cfg opts print_unqual = mkPrintUnqualified unit_env rdr_env active_rule = activeRule mode @@ -179,13 +176,18 @@ simplifyPgm logger unit_env opts -- the old bindings are retained until the end of all simplifier iterations !guts_no_binds = guts { mg_binds = [], mg_rules = [] } + hpt_rule_env :: RuleEnv + hpt_rule_env = mkRuleEnv guts emptyRuleBase (so_hpt_rules opts) + -- emptyRuleBase: no EPS rules yet; we will update + -- them on each iteration to pick up the most up to date set + do_iteration :: Int -- Counts iterations -> [SimplCount] -- Counts from earlier iterations, reversed - -> CoreProgram -- Bindings in - -> [CoreRule] -- and orphan rules + -> CoreProgram -- Bindings + -> [CoreRule] -- Local rules for imported Ids -> IO (String, Int, SimplCount, ModGuts) - do_iteration iteration_no counts_so_far binds rules + do_iteration iteration_no counts_so_far binds local_rules -- iteration_no is the number of the iteration we are -- about to begin, with '1' for the first | iteration_no > max_iterations -- Stop if we've run out of iterations @@ -201,7 +203,7 @@ simplifyPgm logger unit_env opts -- number of iterations we actually completed return ( "Simplifier baled out", iteration_no - 1 , totalise counts_so_far - , guts_no_binds { mg_binds = binds, mg_rules = rules } ) + , guts_no_binds { mg_binds = binds, mg_rules = local_rules } ) -- Try and force thunks off the binds; significantly reduces -- space usage, especially with -O. JRS, 000620. @@ -210,8 +212,8 @@ simplifyPgm logger unit_env opts = do { -- Occurrence analysis let { tagged_binds = {-# SCC "OccAnal" #-} - occurAnalysePgm this_mod active_unf active_rule rules - binds + occurAnalysePgm this_mod active_unf active_rule + local_rules binds } ; Logger.putDumpFileMaybe logger Opt_D_dump_occur_anal "Occurrence analysis" FormatCore @@ -222,24 +224,29 @@ simplifyPgm logger unit_env opts -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings - -- Hence just before attempting to match rules we read on the EPS - -- value and then combine it when the existing rule base. + -- Hence just before attempting to match a rule we read the EPS + -- value (via read_rule_env) and then combine it with the existing rule base. -- See `GHC.Core.Opt.Simplify.Monad.getSimplRules`. - eps <- ueEPS unit_env ; - let { -- Forcing this value to avoid unnessecary allocations. + eps <- ueEPS unit_env ; + let { -- base_rule_env contains + -- (a) home package rules, fixed across all iterations + -- (b) local rules (substituted) from `local_rules` arg to do_iteration + -- Forcing base_rule_env to avoid unnecessary allocations. -- Not doing so results in +25.6% allocations of LargeRecord. - ; !rule_base = extendRuleBaseList hpt_rule_base rules - ; vis_orphs = this_mod : dep_orphs deps - ; base_ruleenv = mkRuleEnv rule_base vis_orphs + ; !base_rule_env = updLocalRules hpt_rule_env local_rules + + ; read_eps_rules :: IO PackageRuleBase ; read_eps_rules = eps_rule_base <$> ueEPS unit_env - ; read_ruleenv = extendRuleEnv base_ruleenv <$> read_eps_rules + + ; read_rule_env :: IO RuleEnv + ; read_rule_env = updExternalPackageRules base_rule_env <$> read_eps_rules ; fam_envs = (eps_fam_inst_env eps, fam_inst_env) ; simpl_env = mkSimplEnv mode fam_envs } ; -- Simplify the program ((binds1, rules1), counts1) <- - initSmpl logger read_ruleenv top_env_cfg sz $ + initSmpl logger read_rule_env top_env_cfg sz $ do { (floats, env1) <- {-# SCC "SimplTopBinds" #-} simplTopBinds simpl_env tagged_binds @@ -247,7 +254,7 @@ simplifyPgm logger unit_env opts -- for imported Ids. Eg RULE map my_f = blah -- If we have a substitution my_f :-> other_f, we'd better -- apply it to the rule to, or it'll never match - ; rules1 <- simplImpRules env1 rules + ; rules1 <- simplImpRules env1 local_rules ; return (getTopFloatBinds floats, rules1) } ; ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -27,8 +27,8 @@ import GHC.Types.Name ( mkSystemVarName ) import GHC.Types.Id ( Id, mkSysLocalOrCoVarM ) import GHC.Types.Id.Info ( IdDetails(..), vanillaIdInfo, setArityInfo ) import GHC.Core.Type ( Type, Mult ) -import GHC.Core ( RuleEnv(..) ) import GHC.Core.Opt.Stats +import GHC.Core.Rules import GHC.Core.Utils ( mkLamTypes ) import GHC.Types.Unique.Supply import GHC.Driver.Flags ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -53,7 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils -import GHC.Core.Rules( getRules ) +import GHC.Core.Rules( RuleEnv, getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -19,6 +19,7 @@ import GHC.Tc.Utils.TcType hiding( substTy ) import GHC.Core.Type hiding( substTy, extendTvSubstList, zapSubst ) import GHC.Core.Multiplicity +import GHC.Core.SimpleOpt( defaultSimpleOpts, simpleOptExprWith ) import GHC.Core.Predicate import GHC.Core.Coercion( Coercion ) import GHC.Core.Opt.Monad @@ -594,9 +595,10 @@ Hence, the invariant is this: -- | Specialise calls to type-class overloaded functions occurring in a program. specProgram :: ModGuts -> CoreM ModGuts specProgram guts@(ModGuts { mg_module = this_mod - , mg_rules = local_rules - , mg_binds = binds }) + , mg_rules = local_rules + , mg_binds = binds }) = do { dflags <- getDynFlags + ; rule_env <- initRuleEnv guts -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -606,6 +608,7 @@ specProgram guts@(ModGuts { mg_module = this_mod ; let top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSetList $ bindersOfBinds binds , se_module = this_mod + , se_rules = rule_env , se_dflags = dflags } go [] = return ([], emptyUDs) @@ -616,7 +619,7 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM (go binds) - ; (spec_rules, spec_binds) <- specImports top_env local_rules uds + ; (spec_rules, spec_binds) <- specImports top_env uds ; return (guts { mg_binds = spec_binds ++ binds' , mg_rules = spec_rules ++ local_rules }) } @@ -681,21 +684,15 @@ specialisation (see canSpecImport): -} specImports :: SpecEnv - -> [CoreRule] -> UsageDetails -> CoreM ([CoreRule], [CoreBind]) -specImports top_env local_rules - (MkUD { ud_binds = dict_binds, ud_calls = calls }) +specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls }) | not $ gopt Opt_CrossModuleSpecialise (se_dflags top_env) -- See Note [Disabling cross-module specialisation] = return ([], wrapDictBinds dict_binds []) | otherwise - = do { hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - - ; (spec_rules, spec_binds) <- spec_imports top_env [] rule_base - dict_binds calls + = do { (_env, spec_rules, spec_binds) <- spec_imports top_env [] dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. @@ -713,89 +710,91 @@ specImports top_env local_rules spec_imports :: 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) -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls -- See Note [Avoiding loops in specImports] -> CallDetails -- Calls for imported things - -> CoreM ( [CoreRule] -- New rules + -> CoreM ( SpecEnv -- Env contains the new rules + , [CoreRule] -- New rules , [CoreBind] ) -- Specialised bindings -spec_imports top_env callers rule_base dict_binds calls +spec_imports env callers 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 + ; (env, rules, spec_binds) <- go env import_calls -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds) } + ; return (env, rules, spec_binds) } where - go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) - go _ [] = return ([], []) - go rb (cis : other_calls) + go :: SpecEnv -> [CallInfoSet] -> CoreM (SpecEnv, [CoreRule], [CoreBind]) + go env [] = return (env, [], []) + go env (cis : other_calls) = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) - ; (rules1, spec_binds1) <- spec_import top_env callers rb dict_binds cis + ; (env, rules1, spec_binds1) <- spec_import env callers dict_binds cis ; -- debugTraceMsg (text "specImport }" <+> ppr cis) - ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls - ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } + ; (env, rules2, spec_binds2) <- go env other_calls + ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) } spec_import :: 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 -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls -- See Note [Avoiding loops in specImports] -> CallInfoSet -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules + -> CoreM ( SpecEnv + , [CoreRule] -- New rules , [CoreBind] ) -- Specialised bindings -spec_import top_env callers rb dict_binds cis@(CIS fn _) +spec_import env callers 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 + = return (env, [], []) -- 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 good_calls - = return ([], []) + = return (env, [], []) | Just rhs <- canSpecImport dflags fn = do { -- Get rules from the external package state -- We keep doing this in case we "page-fault in" -- more rules as we go along - ; external_rule_base <- getExternalRuleBase - ; vis_orphs <- getVisibleOrphanMods - ; let rules_for_fn = getRules (RuleEnv [rb, external_rule_base] vis_orphs) fn + ; eps_rules <- getExternalRuleBase + ; let rule_env = se_rules env `updExternalPackageRules` eps_rules - ; -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) +-- ; debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls +-- , ppr (getRules rule_env fn), ppr rhs]) ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) - <- runSpecM $ specCalls True top_env dict_binds - rules_for_fn good_calls fn rhs + <- runSpecM $ specCalls True env dict_binds + (getRules rule_env 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] + new_subst = se_subst env `Core.extendSubstInScopeList` map fst spec_pairs + new_env = env { se_rules = rule_env `addLocalRules` rules1 + , se_subst = new_subst } + -- Now specialise any cascaded calls - ; -- debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) - ; (rules2, spec_binds2) <- spec_imports top_env - (fn:callers) - (extendRuleBaseList rb rules1) - (dict_binds `thenFDBs` dict_binds1) - new_calls +-- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (env, rules2, spec_binds2) + <- spec_imports new_env (fn:callers) + (dict_binds `thenFDBs` dict_binds1) + new_calls ; let final_binds = wrapDictBinds dict_binds1 $ spec_binds2 ++ spec_binds1 - ; return (rules2 ++ rules1, final_binds) } + ; return (env, rules2 ++ rules1, final_binds) } | otherwise = do { tryWarnMissingSpecs dflags callers fn good_calls - ; return ([], [])} + ; return (env, [], [])} where - dflags = se_dflags top_env + dflags = se_dflags env good_calls = filterCalls cis dict_binds -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn -- See Note [Avoiding loops in specImports] @@ -1086,6 +1085,7 @@ data SpecEnv -- the RHS of specialised bindings (no type-let!) , se_module :: Module + , se_rules :: RuleEnv -- From the home package and this module , se_dflags :: DynFlags } @@ -1124,8 +1124,8 @@ specExpr env expr@(App {}) ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args -- Some dicts may have floated out of args_in; - -- they should be in scope for rewriteClassOps (#21689) - (fun_in', args_out') = rewriteClassOps env_args fun_in args_out + -- they should be in scope for fireRewriteRules (#21689) + (fun_in', args_out') = fireRewriteRules env_args fun_in args_out ; (fun_out', uds_fun) <- specExpr env fun_in' ; let uds_call = mkCallUDs env fun_out' args_out' ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) } @@ -1160,17 +1160,19 @@ specExpr env (Let bind body) ; return (foldr Let body' binds', uds) } -- See Note [Specialisation modulo dictionary selectors] --- and Note [ClassOp/DFun selection] -rewriteClassOps :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr]) -rewriteClassOps env (Var f) args - | isClassOpId f -- If we see `op_sel $fCInt`, we rewrite to `$copInt` - , Just (rule, expr) <- -- pprTrace "rewriteClassOps" (ppr f $$ ppr args $$ ppr (se_subst env)) $ - specLookupRule env f args (idCoreRules f) - , let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target] --- , pprTrace "class op rewritten" (ppr f <+> ppr args $$ ppr expr <+> ppr rest_args) True - , (fun, args) <- collectArgs expr - = rewriteClassOps env fun (args++rest_args) -rewriteClassOps _ fun args = (fun, args) +-- Note [ClassOp/DFun selection] +-- Note [Fire rules in the specialiser] +fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr]) +fireRewriteRules env (Var f) args + | Just (rule, expr) <- specLookupRule env f args InitialPhase (getRules (se_rules env) f) + , let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target] + zapped_subst = Core.zapSubst (se_subst env) + expr' = simpleOptExprWith defaultSimpleOpts zapped_subst expr + -- simplOptExpr needed because lookupRule returns + -- (\x y. rhs) arg1 arg2 + , (fun, args) <- collectArgs expr' + = fireRewriteRules env fun (args++rest_args) +fireRewriteRules _ fun args = (fun, args) -------------- specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails) @@ -1276,7 +1278,56 @@ specCase env scrut case_bndr alts where (env_rhs, args') = substBndrs env_alt args -{- +{- Note [Fire rules in the specialiser] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this (#21851) + + module A where + f :: Num b => b -> (b, b) + f x = (x + 1, snd (f x)) + {-# SPECIALIZE f :: Int -> (Int, Int) #-} + + module B (g') where + import A + + g :: Num a => a -> a + g x = fst (f x) + {-# NOINLINE[99] g #-} + + h :: Int -> Int + h = g + +Note that `f` has the CPR property, and so will worker/wrapper. + +The call to `g` in `h` will make us specialise `g @Int`. And the specialised +version of `g` will contain the call `f @Int`; but in the subsequent run of +the Simplifier, there will be a competition between: +* The user-supplied SPECIALISE rule for `f` +* The inlining of the wrapper for `f` + +Alas, the latter wins. And in any case it's very fragile. So we make the +Specialiser fire the RULE instead. It not hard to to (in fireRewriteRules) +and it's very effective. Moreover consider + + module A + f :: (Ord a, Show b) => a -> b -> blah + {-# RULE forall b. f @Int @b = wombat #-} + + wombat :: Show b => Int -> b -> blah + wombat = blah + + module B + import A + g :: forall a. Ord a => blah + g @a = ...g...f @a @Char.... + + h = ....g @Int.... + +Now, in module B, GHC will specialise g @Int, which will lead to a +call f @Int @Char. If we immediately (in the specialiser) rewrite +that to womabat @Char, we have a chance to specialise `wombat`. + + Note [Floating dictionaries out of cases] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1367,13 +1418,12 @@ specBind top_lvl env (NonRec fn rhs) do_body final_binds :: [DictBind] -- See Note [From non-recursive to recursive] - final_binds - | not (isNilOL dump_dbs) - , not (null spec_defns) - = [recWithDumpedDicts pairs dump_dbs] - | otherwise - = [mkDB $ NonRec b r | (b,r) <- pairs] - ++ fromOL dump_dbs + final_binds | not (isNilOL dump_dbs) + , not (null spec_defns) + = [recWithDumpedDicts pairs dump_dbs] + | otherwise + = [mkDB $ NonRec b r | (b,r) <- pairs] + ++ fromOL dump_dbs ; if float_all then -- Rather than discard the calls mentioning the bound variables @@ -1505,8 +1555,10 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs foldlM spec_call ([], [], emptyUDs) calls_for_me | otherwise -- No calls or RHS doesn't fit our preconceptions - = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me) + = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me && not (isClassOpId fn)) "Missed specialisation opportunity" (ppr fn $$ _trace_doc) $ + -- isClassOpId: class-op Ids never inline; we specialise them + -- through fireRewriteRules. So don't complain about missed opportunities -- Note [Specialisation shape] -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) @@ -1533,9 +1585,13 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs already_covered :: SpecEnv -> [CoreRule] -> [CoreExpr] -> Bool already_covered env new_rules args -- Note [Specialisations already covered] - = isJust (specLookupRule env fn args (new_rules ++ existing_rules)) - -- NB: we look both in the new_rules (generated by this invocation - -- of specCalls), and in existing_rules (passed in to specCalls) + = isJust (specLookupRule env fn args (beginPhase inl_act) + (new_rules ++ existing_rules)) + -- Rules: we look both in the new_rules (generated by this invocation + -- of specCalls), and in existing_rules (passed in to specCalls) + -- inl_act: is the activation we are going to put in the new SPEC + -- rule; so we want to see if it is covered by another rule with + -- that same activation. ---------------------------------------------------------- -- Specialise to one particular call pattern @@ -1653,13 +1709,16 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs -- Convenience function for invoking lookupRule from Specialise -- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr] -specLookupRule :: SpecEnv -> Id -> [CoreExpr] -> [CoreRule] -> Maybe (CoreRule, CoreExpr) -specLookupRule env fn args rules - = lookupRule ropts (in_scope, realIdUnfolding) (const True) fn args rules +specLookupRule :: SpecEnv -> Id -> [CoreExpr] + -> CompilerPhase -- Look up rules as if we were in this phase + -> [CoreRule] -> Maybe (CoreRule, CoreExpr) +specLookupRule env fn args phase rules + = lookupRule ropts (in_scope, realIdUnfolding) is_active fn args rules where - dflags = se_dflags env - in_scope = getSubstInScope (se_subst env) - ropts = initRuleOpts dflags + dflags = se_dflags env + in_scope = getSubstInScope (se_subst env) + ropts = initRuleOpts dflags + is_active = isActive phase {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1846,10 +1905,10 @@ We want to specialise this! How? By doing the method-selection rewrite in the Specialiser. Hence 1. In the App case of 'specExpr', try to apply the ClassOp/DFun rule on the - head of the application, repeatedly, via 'rewriteClassOps'. + head of the application, repeatedly, via 'fireRewriteRules'. 2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and `$dShow` in `bindAuxiliaryDict`, so that we can exploit the unfolding - in 'rewriteClassOps' to do the ClassOp/DFun rewrite. + in 'fireRewriteRules' to do the ClassOp/DFun rewrite. NB: Without (2), (1) would be pointless, because 'lookupRule' wouldn't be able to look into the RHS of `$dC` to see the DFun. ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -12,8 +12,10 @@ module GHC.Core.Rules ( lookupRule, -- ** RuleBase, RuleEnv + RuleBase, RuleEnv(..), mkRuleEnv, emptyRuleEnv, + updExternalPackageRules, addLocalRules, updLocalRules, emptyRuleBase, mkRuleBase, extendRuleBaseList, - pprRuleBase, extendRuleEnv, + pprRuleBase, -- ** Checking rule applications ruleCheckProgram, @@ -22,6 +24,8 @@ module GHC.Core.Rules ( extendRuleInfo, addRuleInfo, addIdSpecialisations, + -- ** RuleBase and RuleEnv + -- * Misc. CoreRule helpers rulesOfBinds, getRules, pprRulesForUser, @@ -34,6 +38,8 @@ import GHC.Prelude import GHC.Unit.Module ( Module ) import GHC.Unit.Module.Env +import GHC.Unit.Module.ModGuts( ModGuts(..) ) +import GHC.Unit.Module.Deps( Dependencies(..) ) import GHC.Driver.Session( DynFlags ) import GHC.Driver.Ppr( showSDoc ) @@ -136,7 +142,7 @@ Note [Overall plumbing for rules] * At the moment (c) is carried in a reader-monad way by the GHC.Core.Opt.Monad. The HomePackageTable doesn't have a single RuleBase because technically we should only be able to "see" rules "below" this module; so we - generate a RuleBase for (c) by combing rules from all the modules + generate a RuleBase for (c) by combining rules from all the modules "below" us. That's why we can't just select the home-package RuleBase from HscEnv. @@ -340,12 +346,100 @@ addIdSpecialisations id rules rulesOfBinds :: [CoreBind] -> [CoreRule] rulesOfBinds binds = concatMap (concatMap idCoreRules . bindersOf) binds + +{- +************************************************************************ +* * + RuleBase +* * +************************************************************************ +-} + +-- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules +type RuleBase = NameEnv [CoreRule] + -- The rules are unordered; + -- we sort out any overlaps on lookup + +emptyRuleBase :: RuleBase +emptyRuleBase = emptyNameEnv + +mkRuleBase :: [CoreRule] -> RuleBase +mkRuleBase rules = extendRuleBaseList emptyRuleBase rules + +extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase +extendRuleBaseList rule_base new_guys + = foldl' extendRuleBase rule_base new_guys + +extendRuleBase :: RuleBase -> CoreRule -> RuleBase +extendRuleBase rule_base rule + = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule + +pprRuleBase :: RuleBase -> SDoc +pprRuleBase rules = pprUFM rules $ \rss -> + vcat [ pprRules (tidyRules emptyTidyEnv rs) + | rs <- rss ] + +-- | A full rule environment which we can apply rules from. Like a 'RuleBase', +-- but it also includes the set of visible orphans we use to filter out orphan +-- rules which are not visible (even though we can see them...) +-- See Note [Orphans] in GHC.Core +data RuleEnv + = RuleEnv { re_local_rules :: !RuleBase -- Rules from this module + , re_home_rules :: !RuleBase -- Rule from the home package + -- (excl this module) + , re_eps_rules :: !RuleBase -- Rules from other packages + -- see Note [External package rules] + , re_visible_orphs :: !ModuleSet + } + +mkRuleEnv :: ModGuts -> RuleBase -> RuleBase -> RuleEnv +mkRuleEnv (ModGuts { mg_module = this_mod + , mg_deps = deps + , mg_rules = local_rules }) + eps_rules hpt_rules + = RuleEnv { re_local_rules = mkRuleBase local_rules + , re_home_rules = hpt_rules + , re_eps_rules = eps_rules + , re_visible_orphs = mkModuleSet vis_orphs } + where + vis_orphs = this_mod : dep_orphs deps + +updExternalPackageRules :: RuleEnv -> RuleBase -> RuleEnv +-- Completely over-ride the external rules in RuleEnv +updExternalPackageRules rule_env eps_rules + = rule_env { re_eps_rules = eps_rules } + +updLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv +-- Completely over-ride the local rules in RuleEnv +updLocalRules rule_env local_rules + = rule_env { re_local_rules = mkRuleBase local_rules } + +addLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv +-- Add new local rules +addLocalRules rule_env rules + = rule_env { re_local_rules = extendRuleBaseList (re_local_rules rule_env) rules } + +emptyRuleEnv :: RuleEnv +emptyRuleEnv = RuleEnv { re_local_rules = emptyNameEnv + , re_home_rules = emptyNameEnv + , re_eps_rules = emptyNameEnv + , re_visible_orphs = emptyModuleSet } + getRules :: RuleEnv -> Id -> [CoreRule] +-- Given a RuleEnv and an Id, find the visible rules for that Id -- See Note [Where rules are found] -getRules (RuleEnv { re_base = rule_base, re_visible_orphs = orphs }) fn - = idCoreRules fn ++ concatMap imp_rules rule_base +getRules (RuleEnv { re_local_rules = local_rules + , re_home_rules = home_rules + , re_eps_rules = eps_rules + , re_visible_orphs = orphs }) fn + = idCoreRules fn ++ + get local_rules ++ + find_visible home_rules ++ + find_visible eps_rules where - imp_rules rb = filter (ruleIsVisible orphs) (lookupNameEnv rb (idName fn) `orElse` []) + fn_name = idName fn + find_visible rb = filter (ruleIsVisible orphs) (get rb) + get rb = lookupNameEnv rb fn_name `orElse` [] ruleIsVisible :: ModuleSet -> CoreRule -> Bool ruleIsVisible _ BuiltinRule{} = True @@ -371,37 +465,28 @@ but that isn't quite right: in the module defining the Id (when it's a LocalId), but the rules are kept in the global RuleBase + Note [External package rules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In Note [Overall plumbing for rules], it is explained that the final +RuleBase which we must consider is combined from 4 different sources. -************************************************************************ -* * - RuleBase -* * -************************************************************************ --} - --- RuleBase itself is defined in GHC.Core, along with CoreRule - -emptyRuleBase :: RuleBase -emptyRuleBase = emptyNameEnv - -mkRuleBase :: [CoreRule] -> RuleBase -mkRuleBase rules = extendRuleBaseList emptyRuleBase rules +During simplifier runs, the fourth source of rules is constantly being updated +as new interfaces are loaded into the EPS. Therefore just before we check to see +if any rules match we get the EPS RuleBase and combine it with the existing RuleBase +and then perform exactly 1 lookup into the new map. -extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase -extendRuleBaseList rule_base new_guys - = foldl' extendRuleBase rule_base new_guys +It is more efficient to avoid combining the environments and store the uncombined +environments as we can instead perform 1 lookup into each environment and then combine +the results. -extendRuleBase :: RuleBase -> CoreRule -> RuleBase -extendRuleBase rule_base rule - = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule +Essentially we use the identity: -extendRuleEnv :: RuleEnv -> RuleBase -> RuleEnv -extendRuleEnv (RuleEnv rules orphs) rb = (RuleEnv (rb:rules) orphs) +> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) +> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 -pprRuleBase :: RuleBase -> SDoc -pprRuleBase rules = pprUFM rules $ \rss -> - vcat [ pprRules (tidyRules emptyTidyEnv rs) - | rs <- rss ] +The latter being more efficient as we don't construct an intermediate +map. +-} {- ************************************************************************ @@ -1576,7 +1661,7 @@ ruleCheckFun env fn args | otherwise = unitBag (ruleAppCheck_help env fn args name_match_rules) where name_match_rules = filter match (rc_rules env fn) - match rule = (rc_pattern env) `isPrefixOf` unpackFS (ruleName rule) + match rule = rc_pattern env `isPrefixOf` unpackFS (ruleName rule) ruleAppCheck_help :: RuleCheckEnv -> Id -> [CoreExpr] -> [CoreRule] -> SDoc ruleAppCheck_help env fn args rules ===================================== compiler/GHC/Driver/Config/Core/Opt/Simplify.hs ===================================== @@ -7,7 +7,7 @@ module GHC.Driver.Config.Core.Opt.Simplify import GHC.Prelude -import GHC.Core ( RuleBase ) +import GHC.Core.Rules ( RuleBase ) import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Core.Opt.Simplify ( SimplifyExprOpts(..), SimplifyOpts(..) ) import GHC.Core.Opt.Simplify.Env ( FloatEnable(..), SimplMode(..) ) @@ -40,20 +40,19 @@ initSimplifyExprOpts dflags ic = SimplifyExprOpts } initSimplifyOpts :: DynFlags -> [Var] -> Int -> SimplMode -> RuleBase -> SimplifyOpts -initSimplifyOpts dflags extra_vars iterations mode rule_base = let +initSimplifyOpts dflags extra_vars iterations mode hpt_rule_base = let -- This is a particularly ugly construction, but we will get rid of it in !8341. opts = SimplifyOpts { so_dump_core_sizes = not $ gopt Opt_SuppressCoreSizes dflags - , so_iterations = iterations - , so_mode = mode + , so_iterations = iterations + , so_mode = mode , so_pass_result_cfg = if gopt Opt_DoCoreLinting dflags - then Just $ initLintPassResultConfig dflags extra_vars (CoreDoSimplify opts) - else Nothing - , so_rule_base = rule_base - , so_top_env_cfg = TopEnvConfig - { te_history_size = historySize dflags - , te_tick_factor = simplTickFactor dflags - } + then Just $ initLintPassResultConfig dflags extra_vars + (CoreDoSimplify opts) + else Nothing + , so_hpt_rules = hpt_rule_base + , so_top_env_cfg = TopEnvConfig { te_history_size = historySize dflags + , te_tick_factor = simplTickFactor dflags } } in opts ===================================== compiler/GHC/Unit/External.hs ===================================== @@ -21,11 +21,10 @@ import GHC.Prelude import GHC.Unit import GHC.Unit.Module.ModIface -import GHC.Core ( RuleBase ) import GHC.Core.FamInstEnv import GHC.Core.InstEnv ( InstEnv, emptyInstEnv ) import GHC.Core.Opt.ConstantFold -import GHC.Core.Rules (mkRuleBase) +import GHC.Core.Rules ( RuleBase, mkRuleBase) import GHC.Types.Annotations ( AnnEnv, emptyAnnEnv ) import GHC.Types.CompleteMatch ===================================== libraries/base/GHC/Real.hs ===================================== @@ -701,11 +701,14 @@ half of y - 1 can be computed as y `quot` 2, optimising subtraction away. Note [Inlining (^) ~~~~~~~~~~~~~~~~~~ -The INLINABLE pragma allows (^) to be specialised at its call sites. +The INLINABLE [1] pragma allows (^) to be specialised at its call sites. If it is called repeatedly at the same type, that can make a huge difference, because of those constants which can be repeatedly calculated. +We don't inline until phase 1, to give a chance for the RULES +"^2/Int" etc to fire first. + Currently the fromInteger calls are not floated because we get \d1 d2 x y -> blah after the gentle round of simplification. ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -15,5 +15,3 @@ g' :: Int -> Int g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } - - ===================================== testsuite/tests/simplCore/should_compile/T21851c.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl -dsuppress-uniques -dno-typeable-binds #-} + +module T21851c where + +import T21851d + +g :: forall a. Num a => a -> (a,String) +g n | n < 10 = (0, f n True) + | otherwise = g (n-2) +-- The specialised version of g leads to a specialised +-- call to (f @Int @Bool). Then we want to fire f's RULE +-- and specialise 'wombat' + +h = g (3::Int) + ===================================== testsuite/tests/simplCore/should_compile/T21851d.hs ===================================== @@ -0,0 +1,11 @@ +module T21851d where + +f :: (Num a, Show b) => a -> b -> String +{-# NOINLINE f #-} +f x y = "no" +{-# RULES "wombat" f = wombat #-} + +wombat :: Show b => Int -> b -> String +{-# INLINEABLE wombat #-} +wombat 0 y = "" +wombat n y = show y ++ wombat (n-1) y ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -434,3 +434,6 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) + +test('T21851', only_ways(['optasm']), multimod_compile, ['T21851', '-v0']) +test('T21851-2', only_ways(['optasm']), multimod_compile, ['T21851c', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/91ef98bc9417a0382d4c4f18679eac33cac58b76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/91ef98bc9417a0382d4c4f18679eac33cac58b76 You're receiving 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 Oct 11 12:13:40 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 11 Oct 2022 08:13:40 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22277 Message-ID: <63455df49b037_1eea6a529f4f8c1122318@gitlab.mail> Sebastian Graf pushed new branch wip/T22277 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22277 You're receiving 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 Oct 11 12:16:17 2022 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Tue, 11 Oct 2022 08:16:17 -0400 Subject: [Git][ghc/ghc][wip/js-staging] allow async exceptions to be thrown from outside a haskell thread Message-ID: <63455e91d26ae_1eea6a5face52c1125675@gitlab.mail> Luite Stegeman pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 1ec975ca by Luite Stegeman at 2022-10-11T14:15:37+02:00 allow async exceptions to be thrown from outside a haskell thread - - - - - 1 changed file: - rts/js/thread.js Changes: ===================================== rts/js/thread.js ===================================== @@ -240,11 +240,15 @@ function h$killThread(t, ex) { return h$stack ? h$stack[h$sp] : null; } else { t.excep.push([h$currentThread,ex]); - h$currentThread.interruptible = true; - h$sp += 2; - h$stack[h$sp-1] = h$r1; - h$stack[h$sp] = h$return; - return h$blockThread(h$currentThread,t,null); + if(h$currentThread) { + h$currentThread.interruptible = true; + h$sp += 2; + h$stack[h$sp-1] = h$r1; + h$stack[h$sp] = h$return; + return h$blockThread(h$currentThread,t,null); + } else { + return null; + } } } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ec975cac75be10ac77b472550d7df4dabdb2da4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ec975cac75be10ac77b472550d7df4dabdb2da4 You're receiving 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 Oct 11 12:48:56 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 08:48:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Tidy implicit binds Message-ID: <6345663847fef_1eea6a514c81149426@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ed861ab4 by Matthew Pickering at 2022-10-11T08:48:31-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - d6018618 by Matthew Pickering at 2022-10-11T08:48:31-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - c610e8c6 by Matthew Pickering at 2022-10-11T08:48:31-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - 54de245f by Simon Peyton Jones at 2022-10-11T08:48:32-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 22e0e202 by Simon Peyton Jones at 2022-10-11T08:48:32-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 98f1d211 by Cheng Shao at 2022-10-11T08:48:34-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 4bc01440 by Matthew Pickering at 2022-10-11T08:48:36-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - 8387bf12 by Cheng Shao at 2022-10-11T08:48:37-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Types/SrcLoc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87aaea11565de48ad6523b99c31a9bb2c73ce269...8387bf129fde37d181cc8344238ea2f045bec330 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87aaea11565de48ad6523b99c31a9bb2c73ce269...8387bf129fde37d181cc8344238ea2f045bec330 You're receiving 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 Oct 11 12:51:56 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 11 Oct 2022 08:51:56 -0400 Subject: [Git][ghc/ghc][wip/T22277] Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <634566ec71bbf_1eea6a514c81163039@gitlab.mail> Sebastian Graf pushed to branch wip/T22277 at Glasgow Haskell Compiler / GHC Commits: f96c8ba9 by Sebastian Graf at 2022-10-11T14:51:38+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 5 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/SpecConstr.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22277.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,13 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind top_lvl env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + , let env' | isTopLevel top_lvl = extendScInScope env (bindersOfBinds binds) + | otherwise = env + -- At top level, scBinds assumes that we've already put all binders into scope; see initScEnv + = scBinds top_lvl env' binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1447,88 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs, body) <- collectBinders rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds`. +It might be interesting to specialise `f` and `g` for call patterns in `rest`, +but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -434,3 +437,5 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f96c8ba907525051bf0d5540bab2c89ee491ac41 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f96c8ba907525051bf0d5540bab2c89ee491ac41 You're receiving 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 Oct 11 12:52:50 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 11 Oct 2022 08:52:50 -0400 Subject: [Git][ghc/ghc][wip/T22277] Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <634567229c6de_1eea6a5181c2241163224@gitlab.mail> Sebastian Graf pushed to branch wip/T22277 at Glasgow Haskell Compiler / GHC Commits: 0beddf90 by Sebastian Graf at 2022-10-11T14:52:43+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 6 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/SpecConstr.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22277.hs - + testsuite/tests/simplCore/should_compile/T22277.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,13 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind top_lvl env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + , let env' | isTopLevel top_lvl = extendScInScope env (bindersOfBinds binds) + | otherwise = env + -- At top level, scBinds assumes that we've already put all binders into scope; see initScEnv + = scBinds top_lvl env' binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1447,88 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs, body) <- collectBinders rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds`. +It might be interesting to specialise `f` and `g` for call patterns in `rest`, +but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/T22277.stderr ===================================== @@ -0,0 +1,132 @@ +[1 of 1] Compiling T22277 ( T22277.hs, T22277.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 110, types: 49, coercions: 0, joins: 3/4} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T22277.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule3 = GHC.Types.TrNameS T22277.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T22277.$trModule2 = "T22277"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule1 = GHC.Types.TrNameS T22277.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule + = GHC.Types.Module T22277.$trModule3 T22277.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry2 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry2 = GHC.Types.I# 13# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry1 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry1 = GHC.Types.I# 24# + +-- RHS size: {terms: 89, types: 40, coercions: 0, joins: 3/4} +entry :: Int -> Int +[GblId, + Arity=1, + Str=<1P(SL)>, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 403 0}] +entry + = \ (n :: Int) -> + case n of wild { GHC.Types.I# ds -> + join { + $w$sexit [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int + [LclId[JoinId(1)(Nothing)], Arity=1, Str=] + $w$sexit (ww [OS=OneShot] :: GHC.Prim.Int#) + = join { + $j [Dmd=1C(1,!P(L))] :: [Int] -> Int + [LclId[JoinId(1)(Just [!])], Arity=1, Str=<1L>, Unf=OtherCon []] + $j (arg [OS=OneShot] :: [Int]) + = case GHC.List.$wlenAcc + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 @Int arg (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + 0# + of ww1 + { __DEFAULT -> + GHC.Types.I# (GHC.Prim.+# ww1 ds) + } } in + case GHC.Prim.># 0# ww of { + __DEFAULT -> + letrec { + go3 [Occ=LoopBreaker, Dmd=SC(S,L)] :: GHC.Prim.Int# -> [Int] + [LclId, Arity=1, Str=, Unf=OtherCon []] + go3 + = \ (x :: GHC.Prim.Int#) -> + GHC.Types.: + @Int + (GHC.Types.I# x) + (case GHC.Prim.==# x ww of { + __DEFAULT -> go3 (GHC.Prim.+# x 1#); + 1# -> GHC.Types.[] @Int + }); } in + jump $j (go3 0#); + 1# -> jump $j (GHC.Types.[] @Int) + } } in + joinrec { + $s$wg [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,!P(L))))] + :: Int -> Int -> GHC.Prim.Int# -> Int + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + $s$wg (sc :: Int) (sc1 :: Int) (sc2 :: GHC.Prim.Int#) + = case GHC.Prim.remInt# sc2 2# of { + __DEFAULT -> + case GHC.Prim.># sc2 43# of { + __DEFAULT -> sc; + 1# -> jump $s$wg sc sc1 (GHC.Prim.-# sc2 1#) + }; + 0# -> jump $w$sexit sc2 + }; } in + case ds of ds1 { + __DEFAULT -> jump $s$wg wild wild ds1; + 0# -> jump $s$wg T22277.entry2 T22277.entry1 0# + } + } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -434,3 +437,5 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0beddf90d6ba63a84e6a00093d164f260c8d50c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0beddf90d6ba63a84e6a00093d164f260c8d50c9 You're receiving 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 Oct 11 13:08:34 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 11 Oct 2022 09:08:34 -0400 Subject: [Git][ghc/ghc][wip/T22227] 15 commits: chore: extend `.editorconfig` for C files Message-ID: <63456ad2bf544_1eea6a5fada5c01171785@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - 271759fb by Sebastian Graf at 2022-10-11T15:08:20+02:00 Loopification in OccurAnal (#22227, #14068) - - - - - f1509ae0 by Sebastian Graf at 2022-10-11T15:08:20+02:00 Do join point loopification only pre-simplification - - - - - b14b8d00 by Sebastian Graf at 2022-10-11T15:08:20+02:00 DmdAnal: Look through DataConWrappers (#22241) - - - - - 6dbf837a by Sebastian Graf at 2022-10-11T15:08:20+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Utils/Json.hs - compiler/GHC/Utils/Monad.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/exts/pattern_synonyms.rst - libraries/base/Data/Array/Byte.hs - libraries/base/GHC/TypeLits.hs - libraries/base/GHC/TypeNats.hs - libraries/base/changelog.md - + libraries/base/tests/T15183.hs - + libraries/base/tests/T15183.stdout - libraries/base/tests/all.T - libraries/base/tools/ucd2haskell/ucd.sh - rts/include/Stg.h - testsuite/tests/dependent/should_compile/RaeJobTalk.hs - testsuite/tests/ghci/scripts/T19667Ghci.hs - testsuite/tests/ghci/scripts/T4175.stdout - testsuite/tests/ghci/scripts/T9181.stdout - testsuite/tests/ghci/scripts/ghci064.stdout - testsuite/tests/lib/integer/Makefile - testsuite/tests/linear/should_compile/LinearLetRec.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28ac7b29f97682e1c08c13c9cfd4ce89c2fd70bc...6dbf837a217705c787c2fdbc9194d3b3c5aefe34 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28ac7b29f97682e1c08c13c9cfd4ce89c2fd70bc...6dbf837a217705c787c2fdbc9194d3b3c5aefe34 You're receiving 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 Oct 11 13:56:54 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 09:56:54 -0400 Subject: [Git][ghc/ghc][wip/T21470] 2 commits: Fix binder-swap bug Message-ID: <63457626ba3c1_1eea6a529f4f6411821f5@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21470 at Glasgow Haskell Compiler / GHC Commits: 44842fb6 by Simon Peyton Jones at 2022-10-11T14:55:42+01:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - f74984fa by Simon Peyton Jones at 2022-10-11T14:58:19+01:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 12 changed files: - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Type.hs - testsuite/tests/linters/notes.stdout - testsuite/tests/numeric/should_compile/T19641.stderr - testsuite/tests/simplCore/should_compile/T8331.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -19,7 +19,7 @@ core expression with (hopefully) improved usage information. module GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr, - zapLambdaBndrs + zapLambdaBndrs, scrutBinderSwap_maybe ) where import GHC.Prelude @@ -27,11 +27,12 @@ import GHC.Prelude import GHC.Core import GHC.Core.FVs import GHC.Core.Utils ( exprIsTrivial, isDefaultAlt, isExpandableApp, - stripTicksTopE, mkTicks ) + mkCastMCo, mkTicks ) import GHC.Core.Opt.Arity ( joinRhsArity, isOneShotBndr ) import GHC.Core.Coercion +import GHC.Core.Predicate ( isDictId ) import GHC.Core.Type -import GHC.Core.TyCo.FVs( tyCoVarsOfMCo ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfMCo ) import GHC.Data.Maybe( isJust, orElse ) import GHC.Data.Graph.Directed ( SCC(..), Node(..) @@ -2462,8 +2463,8 @@ data OccEnv -- See Note [The binder-swap substitution] -- If x :-> (y, co) is in the env, - -- then please replace x by (y |> sym mco) - -- Invariant of course: idType x = exprType (y |> sym mco) + -- then please replace x by (y |> mco) + -- Invariant of course: idType x = exprType (y |> mco) , occ_bs_env :: !(VarEnv (OutId, MCoercion)) , occ_bs_rng :: !VarSet -- Vars free in the range of occ_bs_env -- Domain is Global and Local Ids @@ -2669,7 +2670,7 @@ The binder-swap is implemented by the occ_bs_env field of OccEnv. There are two main pieces: * Given case x |> co of b { alts } - we add [x :-> (b, co)] to the occ_bs_env environment; this is + 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 @@ -2737,30 +2738,8 @@ Some tricky corners: (BS5) We have to apply the occ_bs_env substitution uniformly, including to (local) 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. +(BS6) We must be very careful with dictionaries. + See Note [Care with binder-swap on dictionaries] Note [Case of cast] ~~~~~~~~~~~~~~~~~~~ @@ -2770,6 +2749,54 @@ 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 [Care with binder-swap on dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This Note explains why we need isDictId in scrutBinderSwap_maybe. +Consider this tricky example (#21229, #21470): + + class Sing (b :: Bool) where sing :: Bool + instance Sing 'True where sing = True + instance Sing 'False where sing = False + + f :: forall a. Sing a => blah + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a dSing + +Now do a binder-swap on the case-expression: + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (wild |> sym the_co) + +And now substitute `False` for `wild` (since wild=False in the False branch): + + h = \ @(a :: Bool) ($dSing :: Sing a) + let the_co = Main.N:Sing[0] :: Sing a ~R# Bool + case ($dSing |> the_co) of wild + True -> f @'True (True |> sym the_co) + False -> f @a (False |> sym the_co) + +And now we have a problem. The specialiser will specialise (f @a d)a (for all +vtypes a and dictionaries d!!) with the dictionary (False |> sym the_co), using +Note [Specialising polymorphic dictionaries] in GHC.Core.Opt.Specialise. + +The real problem is the binder-swap. It swaps a dictionary variable $dSing +(of kind Constraint) for a term variable wild (of kind Type). And that is +dangerous: a dictionary is a /singleton/ type whereas a general term variable is +not. In this particular example, Bool is most certainly not a singleton type! + +Conclusion: + for a /dictionary variable/ do not perform + the clever cast version of the binder-swap + +Hence the subtle isDictId in scrutBinderSwap_maybe. + Note [Zap case binders in proxy bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the original @@ -2784,8 +2811,87 @@ binding x = cb. See #5028. NB: the OccInfo on /occurrences/ really doesn't matter much; the simplifier doesn't use it. So this is only to satisfy the perhaps-over-picky Lint. +-} + +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 (scrut_var, mco) <- scrutBinderSwap_maybe scrut + , scrut_var /= case_bndr + -- Consider: case x of x { ... } + -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop + = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) + , occ_bs_rng = rng_vars `extendVarSet` case_bndr' + `unionVarSet` tyCoVarsOfMCo mco } + + | otherwise + = env + where + case_bndr' = zapIdOccInfo case_bndr + -- See Note [Zap case binders in proxy bindings] + +scrutBinderSwap_maybe :: OutExpr -> Maybe (OutVar, MCoercion) +-- If (scrutBinderSwap_maybe e = Just (v, mco), then +-- v = e |> mco +-- See Note [Case of cast] +-- See Note [Care with binder-swap on dictionaries] +-- +-- We use this same function in SpecConstr, and Simplify.Iteration, +-- when something binder-swap-like is happening +scrutBinderSwap_maybe (Var v) = Just (v, MRefl) +scrutBinderSwap_maybe (Cast (Var v) co) + | not (isDictId v) = Just (v, MCo (mkSymCo co)) + -- Cast: see Note [Case of cast] + -- isDictId: see Note [Care with binder-swap on dictionaries] + -- The isDictId rejects a Constraint/Constraint binder-swap, perhaps + -- over-conservatively. But I have never seen one, so I'm leaving + -- the code as simple as possible. Losing the binder-swap in a + -- rare case probably has very low impact. +scrutBinderSwap_maybe (Tick _ e) = scrutBinderSwap_maybe e -- Drop ticks +scrutBinderSwap_maybe _ = Nothing + +lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) +-- See Note [The binder-swap substitution] +-- Returns an expression of the same type as Id +lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr + = case lookupVarEnv bs_env bndr of { + Nothing -> (Var bndr, bndr) ; + Just (bndr1, mco) -> + + -- Why do we iterate here? + -- See (BS2) in Note [The binder-swap substitution] + case lookupBndrSwap env bndr1 of + (fun, fun_id) -> (mkCastMCo fun mco, fun_id) } + + +{- Historical note [Proxy let-bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. + Historical Note [no-case-of-case] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We *used* to suppress the binder-swap in case expressions when -fno-case-of-case is on. Old remarks: "This happens in the first simplifier pass, @@ -2844,53 +2950,8 @@ binder-swap in OccAnal: It's fixed by doing the binder-swap in OccAnal because we can do the binder-swap unconditionally and still get occurrence analysis information right. --} -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 (scrut_var, mco) <- get_scrut_var (stripTicksTopE (const True) scrut) - , scrut_var /= case_bndr - -- Consider: case x of x { ... } - -- Do not add [x :-> x] to occ_bs_env, else lookupBndrSwap will loop - = env { occ_bs_env = extendVarEnv swap_env scrut_var (case_bndr', mco) - , occ_bs_rng = rng_vars `extendVarSet` case_bndr' - `unionVarSet` tyCoVarsOfMCo mco } - - | otherwise - = env - where - get_scrut_var :: OutExpr -> Maybe (OutVar, MCoercion) - get_scrut_var (Var v) = Just (v, MRefl) - get_scrut_var (Cast (Var v) co) = Just (v, MCo co) -- See Note [Case of cast] - get_scrut_var _ = Nothing - - case_bndr' = zapIdOccInfo case_bndr - -- See Note [Zap case binders in proxy bindings] -lookupBndrSwap :: OccEnv -> Id -> (CoreExpr, Id) --- See Note [The binder-swap substitution] --- Returns an expression of the same type as Id -lookupBndrSwap env@(OccEnv { occ_bs_env = bs_env }) bndr - = case lookupVarEnv bs_env bndr of { - Nothing -> (Var bndr, bndr) ; - Just (bndr1, mco) -> - - -- Why do we iterate here? - -- See (BS2) in Note [The binder-swap substitution] - case lookupBndrSwap env bndr1 of - (fun, fun_id) -> (add_cast fun mco, fun_id) } - - where - add_cast fun MRefl = fun - add_cast fun (MCo co) = Cast fun (mkSymCo co) - -- We must switch that 'co' to 'sym co'; - -- see the comment with occ_bs_env - -- No need to test for isReflCo, because 'co' came from - -- a (Cast e co) and hence is unlikely to be Refl - -{- ************************************************************************ * * \subsection[OccurAnal-types]{OccEnv} ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -51,17 +51,6 @@ The simplifier tries to get rid of occurrences of x, in favour of wild, in the hope that there will only be one remaining occurrence of x, namely the scrutinee of the case, and we can inline it. - - This can only work if @wild@ is an unrestricted binder. Indeed, even with the - extended typing rule (in the linter) for case expressions, if - case x of wild % 1 { p -> e} - is well-typed, then - case x of wild % 1 { p -> e[wild\x] } - is only well-typed if @e[wild\x] = e@ (that is, if @wild@ is not used in @e@ - at all). In which case, it is, of course, pointless to do the substitution - anyway. So for a linear binder (and really anything which isn't unrestricted), - doing this substitution would either produce ill-typed terms or be the - identity. -} module GHC.Core.Opt.SetLevels ( @@ -1602,7 +1591,9 @@ extendCaseBndrEnv :: LevelEnv -> LevelEnv extendCaseBndrEnv le@(LE { le_subst = subst, le_env = id_env }) case_bndr (Var scrut_var) - | Many <- varMult case_bndr + -- We could use OccurAnal. scrutBinderSwap_maybe here, and perhaps + -- get a bit more floating. But we didn't in the past and it's + -- an unforced change, so I'm leaving it. = le { le_subst = extendSubstWithVar subst case_bndr scrut_var , le_env = add_id id_env (case_bndr, scrut_var) } extendCaseBndrEnv env _ _ = env ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -71,7 +71,8 @@ import GHC.Core.Make ( mkWildValBinder, mkCoreLet ) import GHC.Builtin.Types import GHC.Core.TyCo.Rep ( TyCoBinder(..) ) import qualified GHC.Core.Type as Type -import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, extendTvSubst, extendCvSubst ) +import GHC.Core.Type hiding ( substTy, substTyVar, substTyVarBndr, substCo + , extendTvSubst, extendCvSubst ) import qualified GHC.Core.Coercion as Coercion import GHC.Core.Coercion hiding ( substCo, substCoVar, substCoVarBndr ) import GHC.Platform ( Platform ) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.Opt.Simplify.Env import GHC.Core.Opt.Simplify.Utils -import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs ) +import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutBinderSwap_maybe ) import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr ) import qualified GHC.Core.Make import GHC.Core.Coercion hiding ( substCo, substCoVar ) @@ -3286,19 +3286,21 @@ zapIdOccInfoAndSetEvald str v = -- see Note [Case alternative occ info] addAltUnfoldings :: SimplEnv -> Maybe OutExpr -> OutId -> OutExpr -> SimplM SimplEnv -addAltUnfoldings env scrut case_bndr con_app +addAltUnfoldings env mb_scrut case_bndr con_app = do { let con_app_unf = mk_simple_unf con_app env1 = addBinderUnfolding env case_bndr con_app_unf -- See Note [Add unfolding for scrutinee] - env2 | Many <- idMult case_bndr = case scrut of - Just (Var v) -> addBinderUnfolding env1 v con_app_unf - Just (Cast (Var v) co) -> addBinderUnfolding env1 v $ - mk_simple_unf (Cast con_app (mkSymCo co)) - _ -> env1 + env2 | Just scrut <- mb_scrut + , Just (v,mco) <- scrutBinderSwap_maybe scrut + = addBinderUnfolding env1 v $ + if isReflMCo mco -- isReflMCo: avoid calling mk_simple_unf + then con_app_unf -- twice in the common case + else mk_simple_unf (mkCastMCo con_app mco) + | otherwise = env1 - ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr scrut, ppr con_app]) + ; traceSmpl "addAltUnf" (vcat [ppr case_bndr <+> ppr mb_scrut, ppr con_app]) ; return env2 } where -- Force the opts, so that the whole SimplEnv isn't retained @@ -3361,9 +3363,6 @@ 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. -Exactly the same issue arises in GHC.Core.Opt.SpecConstr; -see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr - HOWEVER, given case x of y { Just a -> r1; Nothing -> r2 } we do not want to add the unfolding x -> y to 'x', which might seem cool, @@ -3374,8 +3373,11 @@ piece of information. So instead we add the unfolding x -> Just a, and x -> Nothing in the respective RHSs. -Since this transformation is tantamount to a binder swap, the same caveat as in -Note [Suppressing binder-swaps on linear case] in OccurAnal apply. +Since this transformation is tantamount to a binder swap, we use +GHC.Core.Opt.OccurAnal.scrutBinderSwap_maybe to do the check. + +Exactly the same issue arises in GHC.Core.Opt.SpecConstr; +see Note [Add scrutinee to ValueEnv too] in GHC.Core.Opt.SpecConstr ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -35,6 +35,7 @@ import GHC.Core.Unfold import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils +import GHC.Core.Opt.OccurAnal( scrutBinderSwap_maybe ) import GHC.Core.DataCon import GHC.Core.Class( classTyVars ) import GHC.Core.Coercion hiding( substCo ) @@ -1073,8 +1074,8 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs = (env2, alt_bndrs') where live_case_bndr = not (isDeadBinder case_bndr) - env1 | Var v <- stripTicksTopE (const True) scrut - = extendValEnv env v cval + env1 | Just (v, mco) <- scrutBinderSwap_maybe scrut + , isReflMCo mco = extendValEnv env v cval | otherwise = env -- See Note [Add scrutinee to ValueEnv too] env2 | live_case_bndr = extendValEnv env1 case_bndr cval | otherwise = env1 @@ -1164,6 +1165,10 @@ though the simplifier has systematically replaced uses of 'x' with 'y' and 'b' with 'c' in the code. The use of 'b' in the ValueEnv came from outside the case. See #4908 for the live example. +It's very like the binder-swap story, so we use scrutBinderSwap_maybe +to identify suitable scrutinees -- but only if there is no cast +(isReflMCo) because that's all that the ValueEnv allows. + Note [Avoiding exponential blowup] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The sc_count field of the ScEnv says how many times we are prepared to ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -15,9 +15,7 @@ import GHC.Driver.Config import GHC.Driver.Config.Diagnostic import GHC.Driver.Config.Core.Rules ( initRuleOpts ) -import GHC.Tc.Utils.TcType hiding( substTy ) - -import GHC.Core.Type hiding( substTy, extendTvSubstList, zapSubst ) +import GHC.Core.Type hiding( substTy, substCo, extendTvSubstList, zapSubst ) import GHC.Core.Multiplicity import GHC.Core.Predicate import GHC.Core.Coercion( Coercion ) @@ -25,12 +23,15 @@ import GHC.Core.Opt.Monad import qualified GHC.Core.Subst as Core import GHC.Core.Unfold.Make import GHC.Core +import GHC.Core.Make ( mkLitRubbish ) +import GHC.Core.Unify ( tcMatchTy ) import GHC.Core.Rules import GHC.Core.Utils ( exprIsTrivial , mkCast, exprType , stripTicksTop ) import GHC.Core.FVs -import GHC.Core.TyCo.Rep (TyCoBinder (..)) +import GHC.Core.TyCo.Rep ( TyCoBinder (..) ) +import GHC.Core.TyCo.FVs ( tyCoVarsOfTypeList ) import GHC.Core.Opt.Arity( collectBindersPushingCo ) import GHC.Builtin.Types ( unboxedUnitTy ) @@ -531,6 +532,48 @@ like f :: Eq [(a,b)] => ... +Note [Specialisation and overlapping instances] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Here is at tricky case (see a comment in MR !8916): + + module A where + class C a where + meth :: a -> String + instance {-# OVERLAPPABLE #-} C (Maybe a) where + meth _ = "Maybe" + + {-# SPECIALISE f :: Maybe a -> Bool -> String #-} + f :: C a => a -> Bool -> String + f a True = f a False + f a _ = meth a + + module B where + import A + + instance C (Maybe Int) where + meth _ = "Int" + + main = putStrLn $ f (Just 42 :: Maybe Int) True + +Running main without optimisations yields "Int", the correct answer. +Activating optimisations yields "Maybe" due to a rewrite rule in module +A generated by the SPECIALISE pragma: + + RULE "USPEC f" forall a (d :: C a). f @a d = $sf + +In B we get the call (f @(Maybe Int) (d :: C (Maybe Int))), and +that rewrites to $sf, but that isn't really right. + +Overlapping instances mean that `C (Maybe Int)` is not a singleton +type: there two distinct dictionaries that have this type. And that +spells trouble for specialistion, which really asssumes singleton +types. + +For now, we just accept this problem, but it may bite us one day. +One solution would be to decline to expose any specialisation rules +to an importing module -- but that seems a bit drastic. + + ************************************************************************ * * \subsubsection{The new specialiser} @@ -802,8 +845,12 @@ spec_import top_env callers rb dict_binds cis@(CIS fn _) canSpecImport :: DynFlags -> Id -> Maybe CoreExpr canSpecImport dflags fn + | isDataConWrapId fn + = Nothing -- Don't specialise data-con wrappers, even if they + -- have dict args; there is no benefit. + | CoreUnfolding { uf_tmpl = rhs } <- unf - -- See Note [Specialising imported functions] point (1). + -- CoreUnfolding: see Note [Specialising imported functions] point (1). , isAnyInlinePragma (idInlinePragma fn) -- See Note [Specialising imported functions] point (2). = Just rhs @@ -1506,12 +1553,12 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs | otherwise -- No calls or RHS doesn't fit our preconceptions = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me) - "Missed specialisation opportunity" (ppr fn $$ _trace_doc) $ + "Missed specialisation opportunity for" (ppr fn $$ trace_doc) $ -- Note [Specialisation shape] -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] fn_type = idType fn fn_arity = idArity fn @@ -1575,8 +1622,16 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs else 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_bndrs1 ++ leftover_bndrs) rhs_body - ; let spec_fn_ty1 = exprType spec_rhs1 + ; (rhs_body', rhs_uds) <- specExpr rhs_env2 rhs_body + -- Add the { d1' = dx1; d2' = dx2 } usage stuff + -- to the rhs_uds; see Note [Specialising Calls] + ; let rhs_uds_w_dx = foldr consDictBind rhs_uds dx_binds + spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs + (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx + spec_rhs1 = mkLams spec_rhs_bndrs $ + wrapDictBindsE dumped_dbs rhs_body' + + spec_fn_ty1 = exprType spec_rhs1 -- Maybe add a void arg to the specialised function, -- to avoid unlifted bindings @@ -1610,10 +1665,6 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - -- Add the { d1' = dx1; d2' = dx2 } usage stuff - -- See Note [Specialising Calls] - spec_uds = foldr consDictBind rhs_uds dx_binds - simpl_opts = initSimpleOpts dflags -------------------------------------- @@ -1796,11 +1847,23 @@ in the specialisation: {-# 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: +worker/wrapper, anyway, but it’s easy to do. - 1. We don’t specialise on them. - 2. They come before an argument we do specialise on. +Wrinkles + +* Note 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. + +* If the function has a stable unfolding, specHeader has to come up with + arguments to pass to that stable unfolding, when building the stable + unfolding of the specialised function: this is the last field in specHeader's + big result tuple. The right thing to do is to produce a LitRubbish; it should rapidly disappear. Rather like GHC.Core.Opt.WorkWrap.Utils.mk_absent_let. @@ -2251,11 +2314,11 @@ instance Outputable SpecArg where 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 +specArgFreeIds :: SpecArg -> IdSet +specArgFreeIds (SpecType {}) = emptyVarSet +specArgFreeIds (SpecDict dx) = exprFreeIds dx +specArgFreeIds UnspecType = emptyVarSet +specArgFreeIds UnspecArg = emptyVarSet isSpecDict :: SpecArg -> Bool isSpecDict (SpecDict {}) = True @@ -2325,24 +2388,30 @@ specHeader , [OutBndr] -- Binders for $sf , [DictBind] -- Auxiliary dictionary bindings , [OutExpr] -- Specialised arguments for unfolding - -- Same length as "args for LHS of rule" + -- Same length as "Args for LHS of rule" ) -- 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 +specHeader env (bndr : bndrs) (SpecType ty : args) + = do { let in_scope = Core.getSubstInScope (se_subst env) + qvars = scopedSort $ + filterOut (`elemInScopeSet` in_scope) $ + tyCoVarsOfTypeList ty + (env1, qvars') = substBndrs env qvars + ty' = substTy env1 ty + env2 = extendTvSubstList env1 [(bndr, ty')] + ; (useful, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env2 bndrs args ; pure ( useful - , env'' + , env3 , leftover_bndrs - , rule_bs - , Type t : rule_es - , bs' + , qvars' ++ rule_bs + , Type ty' : rule_es + , qvars' ++ bs' , dx - , Type t : spec_args + , Type ty' : spec_args ) } @@ -2369,6 +2438,7 @@ specHeader env (bndr : bndrs) (UnspecType : args) -- 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) + | not (isDeadBinder bndr) = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) @@ -2385,29 +2455,44 @@ specHeader env (bndr : bndrs) (SpecDict d : 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. +-- Finally, we don't want to specialise on this argument 'i': +-- - It's an UnSpecArg, or +-- - It's a dead dictionary +-- 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) +specHeader env (bndr : bndrs) (_ : args) + -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead = 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 + + ; let bndr_ty = idType bndr' + + -- See Note [Drop dead args from specialisations] + -- C.f. GHC.Core.Opt.WorkWrap.Utils.mk_absent_let + (mb_spec_bndr, spec_arg) + | isDeadBinder bndr + , Just lit_expr <- mkLitRubbish bndr_ty + = (Nothing, lit_expr) + | otherwise + = (Just bndr', varToCoreExpr bndr') + ; 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' + , case mb_spec_bndr of + Just b' -> b' : bs' + Nothing -> bs' , dx - , varToCoreExpr bndr' : spec_args + , spec_arg : spec_args ) } @@ -2533,6 +2618,88 @@ successfully specialise 'f'. So the DictBinds in (ud_binds :: OrdList DictBind) may contain non-dictionary bindings too. + +Note [Specialising polymorphic dictionaries] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + class M a where { foo :: a -> Int } + + instance M (ST s) where ... + -- dMST :: forall s. M (ST s) + + wimwam :: forall a. M a => a -> Int + wimwam = /\a \(d::M a). body + + f :: ST s -> Int + f = /\s \(x::ST s). wimwam @(ST s) (dMST @s) dx + 1 + +We'd like to specialise wimwam at (ST s), thus + $swimwam :: forall s. ST s -> Int + $swimwam = /\s. body[ST s/a, (dMST @s)/d] + + RULE forall s (d :: M (ST s)). + wimwam @(ST s) d = $swimwam @s + +Here are the moving parts: + +* We must /not/ dump the CallInfo + CIS wimwam (CI { ci_key = [@(ST s), dMST @s] + , ci_fvs = {dMST} }) + when we come to the /\s. Instead, we simply let it continue to float + upwards. Hence ci_fvs is an IdSet, listing the /Ids/ that + are free in the call, but not the /TyVars/. Hence using specArgFreeIds + in singleCall. + + NB to be fully kosher we should explicitly quantifying the CallInfo + over 's', but we don't bother. This would matter if there was an + enclosing binding of the same 's', which I don't expect to happen. + +* Whe we come to specialise the call, we must remember to quantify + over 's'. That is done in the SpecType case of specHeader, where + we add 's' (called qvars) to the binders of the RULE and the specialised + function. + +* If we have f :: forall m. Monoid m => blah, and two calls + (f @(Endo b) (d :: Monoid (Endo b)) + (f @(Endo (c->c)) (d :: Monoid (Endo (c->c))) + we want to generate a specialisation only for the first. The second + is just a substitution instance of the first, with no greater specialisation. + Hence the call to `remove_dups` in `filterCalls`. + +All this arose in #13873, in the unexpected form that a SPECIALISE +pragma made the program slower! The reason was that the specialised +function $sinsertWith arising from the pragma looked rather like `f` +above, and failed to specialise a call in its body like wimwam. +Without the pragma, the original call to `insertWith` was completely +monomorpic, and specialised in one go. + +Wrinkles. + +* With -XOverlappingInstances you might worry about this: + class C a where ... + instance C (Maybe Int) where ... -- $df1 :: C (Maybe Int) + instance C (Maybe a) where ... -- $df2 :: forall a. C (Maybe a) + + f :: C a => blah + f = rhs + + g = /\a. ...(f @(Maybe a) ($df2 a))... + h = ...f @(Maybe Int) $df1 + + There are two calls to f, but with different evidence. This patch will + combine them into one. But it's OK: this code will never arise unless you + use -XIncoherentInstances. Even with -XOverlappingInstances, GHC tries hard + to keep dictionaries as singleton types. But that goes out of the window + with -XIncoherentInstances -- and that is true even with ordianry type-class + specialisation (at least if any inlining has taken place). + + GHC makes very few guarantees when you use -XIncoherentInstances, and its + not worth crippling the normal case for the incoherent corner. (The best + thing might be to switch off specialisation altogether if incoherence is + involved... but incoherence is a property of an instance, not a class, so + it's a hard test to make.) + + But see Note [Specialisation and overlapping instances]. -} instance Outputable DictBind where @@ -2571,8 +2738,9 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments , ci_fvs :: IdSet -- Free Ids of the ci_key call - -- _not_ including the main id itself, of course + -- /not/ including the main id itself, of course -- NB: excluding tyvars: + -- See Note [Specialising polymorphic dictionaries] } type DictExpr = CoreExpr @@ -2621,7 +2789,7 @@ singleCall id args unitBag (CI { ci_key = args -- used to be tys , ci_fvs = call_fvs }) } where - call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args + call_fvs = foldr (unionVarSet . specArgFreeIds) 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 @@ -2951,15 +3119,15 @@ callsForMe fn uds at MkUD { ud_binds = orig_dbs, ud_calls = orig_calls } ---------------------- filterCalls :: CallInfoSet -> FloatedDictBinds -> [CallInfo] --- Remove dominated calls +-- Remove dominated calls (Note [Specialising polymorphic dictionaries]) -- and loopy DFuns (Note [Avoiding loops (DFuns)]) filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) | isDFunId fn -- Note [Avoiding loops (DFuns)] applies only to DFuns - = filter ok_call unfiltered_calls + = filter ok_call de_dupd_calls | otherwise -- Do not apply it to non-DFuns - = unfiltered_calls -- See Note [Avoiding loops (non-DFuns)] + = de_dupd_calls -- See Note [Avoiding loops (non-DFuns)] where - unfiltered_calls = bagToList call_bag + de_dupd_calls = remove_dups call_bag dump_set = foldl' go (unitVarSet fn) dbs -- This dump-set could also be computed by splitDictBinds @@ -2973,6 +3141,29 @@ filterCalls (CIS fn call_bag) (FDB { fdb_binds = dbs }) ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set +remove_dups :: Bag CallInfo -> [CallInfo] +remove_dups calls = foldr add [] calls + where + add :: CallInfo -> [CallInfo] -> [CallInfo] + add ci [] = [ci] + add ci1 (ci2:cis) | ci2 `beats_or_same` ci1 = ci2:cis + | ci1 `beats_or_same` ci2 = ci1:cis + | otherwise = ci2 : add ci1 cis + +beats_or_same :: CallInfo -> CallInfo -> Bool +beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 }) + = go args1 args2 + where + go [] _ = True + go (arg1:args1) (arg2:args2) = go_arg arg1 arg2 && go args1 args2 + go (_:_) [] = False + + go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2) + go_arg UnspecType UnspecType = True + go_arg (SpecDict {}) (SpecDict {}) = True + go_arg UnspecArg UnspecArg = True + go_arg _ _ = False + ---------------------- splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet) -- splitDictBinds dbs bndrs returns @@ -3003,15 +3194,18 @@ splitDictBinds (FDB { fdb_binds = dbs, fdb_bndrs = bs }) bndr_set ---------------------- deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails --- Remove calls *mentioning* bs in any way -deleteCallsMentioning bs calls +-- Remove calls mentioning any Id in bndrs +-- NB: The call is allowed to mention TyVars in bndrs +-- Note [Specialising polymorphic dictionaries] +-- ci_fvs are just the free /Ids/ +deleteCallsMentioning bndrs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bndrs deleteCallsFor :: [Id] -> CallDetails -> CallDetails --- Remove calls *for* bs -deleteCallsFor bs calls = delDVarEnvList calls bs +-- Remove calls *for* bndrs +deleteCallsFor bndrs calls = delDVarEnvList calls bndrs {- ************************************************************************ ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -26,7 +26,8 @@ module GHC.Core.Subst ( extendIdSubstWithClone, extendSubst, extendSubstList, extendSubstWithVar, extendSubstInScope, extendSubstInScopeList, extendSubstInScopeSet, - isInScope, setInScope, extendTvSubst, extendCvSubst, + isInScope, setInScope, getSubstInScope, + extendTvSubst, extendCvSubst, delBndr, delBndrs, zapSubst, -- ** Substituting and cloning binders @@ -41,7 +42,6 @@ import GHC.Core import GHC.Core.FVs import GHC.Core.Seq import GHC.Core.Utils -import GHC.Core.TyCo.Subst ( substCo ) -- We are defining local versions import GHC.Core.Type hiding ( substTy ) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -219,7 +219,7 @@ module GHC.Core.Type ( substTyAddInScope, substTyUnchecked, substTysUnchecked, substScaledTyUnchecked, substScaledTysUnchecked, substThetaUnchecked, substTyWithUnchecked, - substCoUnchecked, substCoWithUnchecked, + substCo, substCoUnchecked, substCoWithUnchecked, substTyVarBndr, substTyVarBndrs, substTyVar, substTyVars, substVarBndr, substVarBndrs, substTyCoBndr, ===================================== testsuite/tests/linters/notes.stdout ===================================== @@ -2,7 +2,6 @@ ref compiler/GHC/Core/Coercion/Axiom.hs:461:2: Note [RoughMap and rm_empt ref compiler/GHC/Core/Opt/OccurAnal.hs:857:15: Note [Loop breaking] ref compiler/GHC/Core/Opt/SetLevels.hs:1580:30: Note [Top level scope] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:2675:13: Note [Case binder next] -ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3303:0: Note [Suppressing binder-swaps on linear case] ref compiler/GHC/Core/Opt/Simplify/Iteration.hs:3854:8: Note [Lambda-bound unfoldings] ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1257:37: Note [Gentle mode] ref compiler/GHC/Core/Opt/Specialise.hs:1623:28: Note [Arity decrease] ===================================== testsuite/tests/numeric/should_compile/T19641.stderr ===================================== @@ -3,30 +3,30 @@ Result size of Tidy Core = {terms: 22, types: 20, coercions: 0, joins: 0/0} -integer_to_int +natural_to_word = \ eta -> case eta of { - IS ipv -> Just (I# ipv); - IP x1 -> Nothing; - IN ds -> Nothing + NS x1 -> Just (W# x1); + NB ds -> Nothing } -natural_to_word +integer_to_int = \ eta -> case eta of { - NS x1 -> Just (W# x1); - NB ds -> Nothing + IS ipv -> Just (I# ipv); + IP x1 -> Nothing; + IN ds -> Nothing } ------ Local rules for imported ids -------- -"SPEC/Test toIntegralSized @Natural @Word" - forall $dIntegral $dIntegral1 $dBits $dBits1. - toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 - = natural_to_word "SPEC/Test toIntegralSized @Integer @Int" forall $dIntegral $dIntegral1 $dBits $dBits1. toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 = integer_to_int +"SPEC/Test toIntegralSized @Natural @Word" + forall $dIntegral $dIntegral1 $dBits $dBits1. + toIntegralSized $dIntegral $dIntegral1 $dBits $dBits1 + = natural_to_word ===================================== testsuite/tests/simplCore/should_compile/T8331.stderr ===================================== @@ -1,5 +1,149 @@ ==================== Tidy Core rules ==================== +"SPEC $c*> @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$c*> @(ST s) @r $dApplicative + = ($fApplicativeReaderT2 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s b) + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) b)) +"SPEC $c<$ @(ST s) @_" + forall (@s) (@r) ($dFunctor :: Functor (ST s)). + $fFunctorReaderT_$c<$ @(ST s) @r $dFunctor + = ($fApplicativeReaderT6 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. a -> ReaderT r (ST s) b -> r -> STRep s a) + (forall {a} {b}. a -> ReaderT r (ST s) b -> ReaderT r (ST s) a)) +"SPEC $c<* @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$c<* @(ST s) @r $dApplicative + = ($fApplicativeReaderT1 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s a) + (forall {a} {b}. + ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) a)) +"SPEC $c<*> @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT9 @(ST s) @r $dApplicative + = ($fApplicativeReaderT4 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + b)>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R Sym (N:ST[0] _N _R) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) (a -> b) -> ReaderT r (ST s) a -> r -> STRep s b) + (forall {a} {b}. + ReaderT r (ST s) (a -> b) -> ReaderT r (ST s) a -> r -> ST s b)) +"SPEC $c>> @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT1 @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$c>> @s @r +"SPEC $c>>= @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT2 @(ST s) @r $dMonad + = ($fMonadAbstractIOSTReaderT2 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + _R + %<'Many>_N ->_R ReaderT r (ST s) b>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R Sym (N:ST[0] _N _R) + :: Coercible + (forall {a} {b}. + ReaderT r (ST s) a -> (a -> ReaderT r (ST s) b) -> r -> STRep s b) + (forall {a} {b}. + ReaderT r (ST s) a -> (a -> ReaderT r (ST s) b) -> r -> ST s b)) +"SPEC $cfmap @(ST s) @_" + forall (@s) (@r) ($dFunctor :: Functor (ST s)). + $fFunctorReaderT_$cfmap @(ST s) @r $dFunctor + = ($fApplicativeReaderT7 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N). + b>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b}. (a -> b) -> ReaderT r (ST s) a -> r -> STRep s b) + (forall {a} {b}. + (a -> b) -> ReaderT r (ST s) a -> ReaderT r (ST s) b)) +"SPEC $cliftA2 @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cliftA2 @(ST s) @r $dApplicative + = ($fApplicativeReaderT3 @s @r) + `cast` (forall (a :: <*>_N) (b :: <*>_N) (c :: <*>_N). + b -> c>_R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> r -> STRep s c) + (forall {a} {b} {c}. + (a -> b -> c) + -> ReaderT r (ST s) a -> ReaderT r (ST s) b -> ReaderT r (ST s) c)) +"SPEC $cp1Applicative @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cp1Applicative @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $cp1Monad @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT_$cp1Monad @(ST s) @r $dMonad + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $cpure @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT_$cpure @(ST s) @r $dApplicative + = ($fApplicativeReaderT5 @s @r) + `cast` (forall (a :: <*>_N). + _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a}. a -> r -> STRep s a) + (forall {a}. a -> ReaderT r (ST s) a)) +"SPEC $creturn @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT_$creturn @(ST s) @r $dMonad + = ($fApplicativeReaderT5 @s @r) + `cast` (forall (a :: <*>_N). + _R + %<'Many>_N ->_R _R %<'Many>_N ->_R Sym (N:ST[0] _N _R) + ; Sym (N:ReaderT[0] <*>_N _R _R _N) + :: Coercible + (forall {a}. a -> r -> STRep s a) + (forall {a}. a -> ReaderT r (ST s) a)) +"SPEC $fApplicativeReaderT @(ST s) @_" + forall (@s) (@r) ($dApplicative :: Applicative (ST s)). + $fApplicativeReaderT @(ST s) @r $dApplicative + = $fApplicativeReaderT_$s$fApplicativeReaderT @s @r +"SPEC $fFunctorReaderT @(ST s) @_" + forall (@s) (@r) ($dFunctor :: Functor (ST s)). + $fFunctorReaderT @(ST s) @r $dFunctor + = $fApplicativeReaderT_$s$fFunctorReaderT @s @r +"SPEC $fMonadReaderT @(ST s) @_" + forall (@s) (@r) ($dMonad :: Monad (ST s)). + $fMonadReaderT @(ST s) @r $dMonad + = $fMonadAbstractIOSTReaderT_$s$fMonadReaderT @s @r "USPEC useAbstractMonad @(ReaderT Int (ST s))" forall (@s) ($dMonadAbstractIOST :: MonadAbstractIOST (ReaderT Int (ST s))). ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -359,7 +359,6 @@ test('T19586', normal, compile, ['']) test('T19599', normal, compile, ['-O -ddump-rules']) test('T19599a', normal, compile, ['-O -ddump-rules']) -test('T13873', [expect_broken(21229), grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) # Look for a specialisation rule for wimwam test('T19672', normal, compile, ['-O2 -ddump-rules']) @@ -434,3 +433,6 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) + +test('T13873', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-rules']) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3c4220c96942ff003fe75949af7188ee0438b467...f74984fa4d46793e3d5d03a5266e25aaf5b1cf2b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3c4220c96942ff003fe75949af7188ee0438b467...f74984fa4d46793e3d5d03a5266e25aaf5b1cf2b You're receiving 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 Oct 11 14:13:54 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 10:13:54 -0400 Subject: [Git][ghc/ghc][wip/T21851] Fire RULES in the Specialiser Message-ID: <63457a22d5f2e_1eea6a514c81193552@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851 at Glasgow Haskell Compiler / GHC Commits: b3b1ddd8 by Simon Peyton Jones at 2022-10-11T15:14:19+01:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. - - - - - 17 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Unit/External.hs - libraries/base/GHC/Real.hs - testsuite/tests/simplCore/should_compile/T21851.stderr - + testsuite/tests/simplCore/should_compile/T21851_2.hs - + testsuite/tests/simplCore/should_compile/T21851_2.stderr - + testsuite/tests/simplCore/should_compile/T21851_2a.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -84,9 +84,8 @@ module GHC.Core ( IsOrphan(..), isOrphan, notOrphan, chooseOrphanAnchor, -- * Core rule data types - CoreRule(..), RuleBase, - RuleName, RuleFun, IdUnfoldingFun, InScopeEnv, - RuleEnv(..), RuleOpts, mkRuleEnv, emptyRuleEnv, + CoreRule(..), + RuleName, RuleFun, IdUnfoldingFun, InScopeEnv, RuleOpts, -- ** Operations on 'CoreRule's ruleArity, ruleName, ruleIdName, ruleActivation, @@ -104,7 +103,6 @@ import GHC.Core.Coercion import GHC.Core.Rules.Config ( RuleOpts ) import GHC.Types.Name import GHC.Types.Name.Set -import GHC.Types.Name.Env( NameEnv ) import GHC.Types.Literal import GHC.Types.Tickish import GHC.Core.DataCon @@ -1061,6 +1059,12 @@ has two major consequences M. But it's painful, because it means we need to keep track of all the orphan modules below us. + * The "visible orphan modules" are all the orphan module in the transitive + closure of the imports of this module. + + * During instance lookup, we filter orphan instances depending on + whether or not the instance is in a visible orphan module. + * A non-orphan is not finger-printed separately. Instead, for fingerprinting purposes it is treated as part of the entity it mentions on the LHS. For example @@ -1075,12 +1079,20 @@ has two major consequences Orphan-hood is computed * For class instances: - when we make a ClsInst - (because it is needed during instance lookup) + when we make a ClsInst in GHC.Core.InstEnv.mkLocalInstance + (because it is needed during instance lookup) + See Note [When exactly is an instance decl an orphan?] + in GHC.Core.InstEnv + + * For rules + when we generate a CoreRule (GHC.Core.Rules.mkRule) + + * For family instances: + when we generate an IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst) + +Orphan-hood is persisted into interface files, in ClsInst, FamInst, +and CoreRules. - * For rules and family instances: - when we generate an IfaceRule (GHC.Iface.Make.coreRuleToIfaceRule) - or IfaceFamInst (GHC.Iface.Make.instanceToIfaceInst) -} {- @@ -1095,49 +1107,6 @@ GHC.Core.FVs, GHC.Core.Subst, GHC.Core.Ppr, GHC.Core.Tidy also inspect the representation. -} --- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules -type RuleBase = NameEnv [CoreRule] - -- The rules are unordered; - -- we sort out any overlaps on lookup - --- | A full rule environment which we can apply rules from. Like a 'RuleBase', --- but it also includes the set of visible orphans we use to filter out orphan --- rules which are not visible (even though we can see them...) -data RuleEnv - = RuleEnv { re_base :: [RuleBase] -- See Note [Why re_base is a list] - , re_visible_orphs :: ModuleSet - } - -mkRuleEnv :: RuleBase -> [Module] -> RuleEnv -mkRuleEnv rules vis_orphs = RuleEnv [rules] (mkModuleSet vis_orphs) - -emptyRuleEnv :: RuleEnv -emptyRuleEnv = RuleEnv [] emptyModuleSet - -{- -Note [Why re_base is a list] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In Note [Overall plumbing for rules], it is explained that the final -RuleBase which we must consider is combined from 4 different sources. - -During simplifier runs, the fourth source of rules is constantly being updated -as new interfaces are loaded into the EPS. Therefore just before we check to see -if any rules match we get the EPS RuleBase and combine it with the existing RuleBase -and then perform exactly 1 lookup into the new map. - -It is more efficient to avoid combining the environments and store the uncombined -environments as we can instead perform 1 lookup into each environment and then combine -the results. - -Essentially we use the identity: - -> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) -> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 - -The latter being more efficient as we don't construct an intermediate -map. --} -- | A 'CoreRule' is: -- ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -319,7 +319,9 @@ mkImportedInstance cls_nm mb_tcs dfun_name dfun oflag orphan {- Note [When exactly is an instance decl an orphan?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - (see GHC.Iface.Make.instanceToIfaceInst, which implements this) +(See GHC.Iface.Make.instanceToIfaceInst, which implements this.) +See Note [Orphans] in GHC.Core + Roughly speaking, an instance is an orphan if its head (after the =>) mentions nothing defined in this module. ===================================== compiler/GHC/Core/Opt/Monad.hs ===================================== @@ -19,10 +19,10 @@ module GHC.Core.Opt.Monad ( -- ** Reading from the monad getHscEnv, getModule, - getRuleBase, getExternalRuleBase, + initRuleEnv, getExternalRuleBase, getDynFlags, getPackageFamInstEnv, getInteractiveContext, - getVisibleOrphanMods, getUniqMask, + getUniqMask, getPrintUnqualified, getSrcSpanM, -- ** Writing to the monad @@ -45,7 +45,7 @@ import GHC.Prelude hiding ( read ) import GHC.Driver.Session import GHC.Driver.Env -import GHC.Core +import GHC.Core.Rules ( RuleBase, RuleEnv, mkRuleEnv ) import GHC.Core.Opt.Stats ( SimplCount, zeroSimplCount, plusSimplCount ) import GHC.Types.Annotations @@ -113,12 +113,11 @@ pprFloatOutSwitches sw data CoreReader = CoreReader { cr_hsc_env :: HscEnv, - cr_rule_base :: RuleBase, + cr_rule_base :: RuleBase, -- Home package table rules cr_module :: Module, cr_print_unqual :: PrintUnqualified, cr_loc :: SrcSpan, -- Use this for log/error messages so they -- are at least tagged with the right source file - cr_visible_orphan_mods :: !ModuleSet, cr_uniq_mask :: !Char -- Mask for creating unique values } @@ -180,19 +179,17 @@ runCoreM :: HscEnv -> RuleBase -> Char -- ^ Mask -> Module - -> ModuleSet -> PrintUnqualified -> SrcSpan -> CoreM a -> IO (a, SimplCount) -runCoreM hsc_env rule_base mask mod orph_imps print_unqual loc m +runCoreM hsc_env rule_base mask mod print_unqual loc m = liftM extract $ runIOEnv reader $ unCoreM m where reader = CoreReader { cr_hsc_env = hsc_env, cr_rule_base = rule_base, cr_module = mod, - cr_visible_orphan_mods = orph_imps, cr_print_unqual = print_unqual, cr_loc = loc, cr_uniq_mask = mask @@ -244,15 +241,18 @@ liftIOWithCount what = liftIO what >>= (\(count, x) -> addSimplCount count >> re getHscEnv :: CoreM HscEnv getHscEnv = read cr_hsc_env -getRuleBase :: CoreM RuleBase -getRuleBase = read cr_rule_base +getHomeRuleBase :: CoreM RuleBase +getHomeRuleBase = read cr_rule_base + +initRuleEnv :: ModGuts -> CoreM RuleEnv +initRuleEnv guts + = do { hpt_rules <- getHomeRuleBase + ; eps_rules <- getExternalRuleBase + ; return (mkRuleEnv guts eps_rules hpt_rules) } getExternalRuleBase :: CoreM RuleBase getExternalRuleBase = eps_rule_base <$> get_eps -getVisibleOrphanMods :: CoreM ModuleSet -getVisibleOrphanMods = read cr_visible_orphan_mods - getPrintUnqualified :: CoreM PrintUnqualified getPrintUnqualified = read cr_print_unqual ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -22,7 +22,7 @@ import GHC.Platform.Ways ( hasWay, Way(WayProf) ) import GHC.Core import GHC.Core.Opt.CSE ( cseProgram ) -import GHC.Core.Rules ( mkRuleBase, ruleCheckProgram, getRules ) +import GHC.Core.Rules ( RuleBase, mkRuleBase, ruleCheckProgram, getRules ) import GHC.Core.Ppr ( pprCoreBindings ) import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.Lint ( lintAnnots ) @@ -52,9 +52,7 @@ import GHC.Utils.Logger as Logger import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Unit.Module.Env import GHC.Unit.Module.ModGuts -import GHC.Unit.Module.Deps import GHC.Types.Id.Info import GHC.Types.Basic @@ -77,14 +75,12 @@ import GHC.Unit.Module core2core :: HscEnv -> ModGuts -> IO ModGuts core2core hsc_env guts@(ModGuts { mg_module = mod , mg_loc = loc - , mg_deps = deps , mg_rdr_env = rdr_env }) = do { let builtin_passes = getCoreToDo dflags hpt_rule_base extra_vars - orph_mods = mkModuleSet (mod : dep_orphs deps) uniq_mask = 's' - ; + ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_mask mod - orph_mods print_unqual loc $ + print_unqual loc $ do { hsc_env' <- getHscEnv ; all_passes <- withPlugins (hsc_plugins hsc_env') installCoreToDos @@ -120,7 +116,8 @@ core2core hsc_env guts@(ModGuts { mg_module = mod -} getCoreToDo :: DynFlags -> RuleBase -> [Var] -> [CoreToDo] -getCoreToDo dflags rule_base extra_vars +-- This function builds the pipeline of optimisations +getCoreToDo dflags hpt_rule_base extra_vars = flatten_todos core_todo where phases = simplPhases dflags @@ -158,7 +155,7 @@ getCoreToDo dflags rule_base extra_vars = CoreDoPasses $ [ maybe_strictness_before phase , CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter - (initSimplMode dflags phase name) rule_base + (initSimplMode dflags phase name) hpt_rule_base , maybe_rule_check phase ] -- Run GHC's internal simplification phase, after all rules have run. @@ -169,7 +166,7 @@ getCoreToDo dflags rule_base extra_vars -- See Note [Inline in InitialPhase] -- See Note [RULEs enabled in InitialPhase] simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter - (initGentleSimplMode dflags) rule_base + (initGentleSimplMode dflags) hpt_rule_base dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] @@ -547,11 +544,9 @@ ruleCheckPass current_phase pat guts = do logger <- getLogger withTiming logger (text "RuleCheck"<+>brackets (ppr $ mg_module guts)) (const ()) $ do - rb <- getRuleBase - vis_orphs <- getVisibleOrphanMods - let rule_fn fn = getRules (RuleEnv [rb] vis_orphs) fn - ++ (mg_rules guts) - let ropts = initRuleOpts dflags + rule_env <- initRuleEnv guts + let rule_fn fn = getRules rule_env fn + ropts = initRuleOpts dflags liftIO $ logDumpMsg logger "Rule check" (ruleCheckProgram ropts current_phase pat rule_fn (mg_binds guts)) ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -10,7 +10,7 @@ import GHC.Prelude import GHC.Driver.Flags import GHC.Core -import GHC.Core.Rules ( extendRuleBaseList, extendRuleEnv, addRuleInfo ) +import GHC.Core.Rules import GHC.Core.Ppr ( pprCoreBindings, pprCoreExpr ) import GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr ) import GHC.Core.Stats ( coreBindsSize, coreBindsStats, exprSize ) @@ -32,7 +32,6 @@ import GHC.Utils.Trace import GHC.Unit.Env ( UnitEnv, ueEPS ) import GHC.Unit.External import GHC.Unit.Module.ModGuts -import GHC.Unit.Module.Deps import GHC.Types.Id import GHC.Types.Id.Info @@ -82,7 +81,7 @@ simplifyExpr logger euc opts expr simpl_env = mkSimplEnv (se_mode opts) fam_envs top_env_cfg = se_top_env_cfg opts read_eps_rules = eps_rule_base <$> eucEPS euc - read_ruleenv = extendRuleEnv emptyRuleEnv <$> read_eps_rules + read_ruleenv = updExternalPackageRules emptyRuleEnv <$> read_eps_rules ; let sz = exprSize expr @@ -133,11 +132,11 @@ simplExprGently env expr = do -- The values of this datatype are /only/ driven by the demands of that function. data SimplifyOpts = SimplifyOpts { so_dump_core_sizes :: !Bool - , so_iterations :: !Int - , so_mode :: !SimplMode + , so_iterations :: !Int + , so_mode :: !SimplMode , so_pass_result_cfg :: !(Maybe LintPassResultConfig) - , so_rule_base :: !RuleBase - , so_top_env_cfg :: !TopEnvConfig + , so_hpt_rules :: !RuleBase + , so_top_env_cfg :: !TopEnvConfig } simplifyPgm :: Logger @@ -149,11 +148,10 @@ simplifyPgm :: Logger simplifyPgm logger unit_env opts guts@(ModGuts { mg_module = this_mod , mg_rdr_env = rdr_env - , mg_deps = deps - , mg_binds = binds, mg_rules = rules + , mg_binds = binds, mg_rules = local_rules , mg_fam_inst_env = fam_inst_env }) = do { (termination_msg, it_count, counts_out, guts') - <- do_iteration 1 [] binds rules + <- do_iteration 1 [] binds local_rules ; when (logHasDumpFlag logger Opt_D_verbose_core2core && logHasDumpFlag logger Opt_D_dump_simpl_stats) $ @@ -170,7 +168,6 @@ simplifyPgm logger unit_env opts dump_core_sizes = so_dump_core_sizes opts mode = so_mode opts max_iterations = so_iterations opts - hpt_rule_base = so_rule_base opts top_env_cfg = so_top_env_cfg opts print_unqual = mkPrintUnqualified unit_env rdr_env active_rule = activeRule mode @@ -179,13 +176,18 @@ simplifyPgm logger unit_env opts -- the old bindings are retained until the end of all simplifier iterations !guts_no_binds = guts { mg_binds = [], mg_rules = [] } + hpt_rule_env :: RuleEnv + hpt_rule_env = mkRuleEnv guts emptyRuleBase (so_hpt_rules opts) + -- emptyRuleBase: no EPS rules yet; we will update + -- them on each iteration to pick up the most up to date set + do_iteration :: Int -- Counts iterations -> [SimplCount] -- Counts from earlier iterations, reversed - -> CoreProgram -- Bindings in - -> [CoreRule] -- and orphan rules + -> CoreProgram -- Bindings + -> [CoreRule] -- Local rules for imported Ids -> IO (String, Int, SimplCount, ModGuts) - do_iteration iteration_no counts_so_far binds rules + do_iteration iteration_no counts_so_far binds local_rules -- iteration_no is the number of the iteration we are -- about to begin, with '1' for the first | iteration_no > max_iterations -- Stop if we've run out of iterations @@ -201,7 +203,7 @@ simplifyPgm logger unit_env opts -- number of iterations we actually completed return ( "Simplifier baled out", iteration_no - 1 , totalise counts_so_far - , guts_no_binds { mg_binds = binds, mg_rules = rules } ) + , guts_no_binds { mg_binds = binds, mg_rules = local_rules } ) -- Try and force thunks off the binds; significantly reduces -- space usage, especially with -O. JRS, 000620. @@ -210,8 +212,8 @@ simplifyPgm logger unit_env opts = do { -- Occurrence analysis let { tagged_binds = {-# SCC "OccAnal" #-} - occurAnalysePgm this_mod active_unf active_rule rules - binds + occurAnalysePgm this_mod active_unf active_rule + local_rules binds } ; Logger.putDumpFileMaybe logger Opt_D_dump_occur_anal "Occurrence analysis" FormatCore @@ -222,24 +224,29 @@ simplifyPgm logger unit_env opts -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings - -- Hence just before attempting to match rules we read on the EPS - -- value and then combine it when the existing rule base. + -- Hence just before attempting to match a rule we read the EPS + -- value (via read_rule_env) and then combine it with the existing rule base. -- See `GHC.Core.Opt.Simplify.Monad.getSimplRules`. - eps <- ueEPS unit_env ; - let { -- Forcing this value to avoid unnessecary allocations. + eps <- ueEPS unit_env ; + let { -- base_rule_env contains + -- (a) home package rules, fixed across all iterations + -- (b) local rules (substituted) from `local_rules` arg to do_iteration + -- Forcing base_rule_env to avoid unnecessary allocations. -- Not doing so results in +25.6% allocations of LargeRecord. - ; !rule_base = extendRuleBaseList hpt_rule_base rules - ; vis_orphs = this_mod : dep_orphs deps - ; base_ruleenv = mkRuleEnv rule_base vis_orphs + ; !base_rule_env = updLocalRules hpt_rule_env local_rules + + ; read_eps_rules :: IO PackageRuleBase ; read_eps_rules = eps_rule_base <$> ueEPS unit_env - ; read_ruleenv = extendRuleEnv base_ruleenv <$> read_eps_rules + + ; read_rule_env :: IO RuleEnv + ; read_rule_env = updExternalPackageRules base_rule_env <$> read_eps_rules ; fam_envs = (eps_fam_inst_env eps, fam_inst_env) ; simpl_env = mkSimplEnv mode fam_envs } ; -- Simplify the program ((binds1, rules1), counts1) <- - initSmpl logger read_ruleenv top_env_cfg sz $ + initSmpl logger read_rule_env top_env_cfg sz $ do { (floats, env1) <- {-# SCC "SimplTopBinds" #-} simplTopBinds simpl_env tagged_binds @@ -247,7 +254,7 @@ simplifyPgm logger unit_env opts -- for imported Ids. Eg RULE map my_f = blah -- If we have a substitution my_f :-> other_f, we'd better -- apply it to the rule to, or it'll never match - ; rules1 <- simplImpRules env1 rules + ; rules1 <- simplImpRules env1 local_rules ; return (getTopFloatBinds floats, rules1) } ; ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -27,8 +27,8 @@ import GHC.Types.Name ( mkSystemVarName ) import GHC.Types.Id ( Id, mkSysLocalOrCoVarM ) import GHC.Types.Id.Info ( IdDetails(..), vanillaIdInfo, setArityInfo ) import GHC.Core.Type ( Type, Mult ) -import GHC.Core ( RuleEnv(..) ) import GHC.Core.Opt.Stats +import GHC.Core.Rules import GHC.Core.Utils ( mkLamTypes ) import GHC.Types.Unique.Supply import GHC.Driver.Flags ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -53,7 +53,7 @@ import GHC.Core.Ppr import GHC.Core.TyCo.Ppr ( pprParendType ) import GHC.Core.FVs import GHC.Core.Utils -import GHC.Core.Rules( getRules ) +import GHC.Core.Rules( RuleEnv, getRules ) import GHC.Core.Opt.Arity import GHC.Core.Unfold import GHC.Core.Unfold.Make ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -19,6 +19,7 @@ import GHC.Tc.Utils.TcType hiding( substTy ) import GHC.Core.Type hiding( substTy, extendTvSubstList, zapSubst ) import GHC.Core.Multiplicity +import GHC.Core.SimpleOpt( defaultSimpleOpts, simpleOptExprWith ) import GHC.Core.Predicate import GHC.Core.Coercion( Coercion ) import GHC.Core.Opt.Monad @@ -594,9 +595,11 @@ Hence, the invariant is this: -- | Specialise calls to type-class overloaded functions occurring in a program. specProgram :: ModGuts -> CoreM ModGuts specProgram guts@(ModGuts { mg_module = this_mod - , mg_rules = local_rules - , mg_binds = binds }) - = do { dflags <- getDynFlags + , mg_rules = local_rules + , mg_binds = binds }) + = do { dflags <- getDynFlags + ; rule_env <- initRuleEnv guts + -- See Note [Fire rules in the specialiser] -- We need to start with a Subst that knows all the things -- that are in scope, so that the substitution engine doesn't @@ -606,6 +609,7 @@ specProgram guts@(ModGuts { mg_module = this_mod ; let top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSetList $ bindersOfBinds binds , se_module = this_mod + , se_rules = rule_env , se_dflags = dflags } go [] = return ([], emptyUDs) @@ -616,7 +620,7 @@ specProgram guts@(ModGuts { mg_module = this_mod -- Specialise the bindings of this module ; (binds', uds) <- runSpecM (go binds) - ; (spec_rules, spec_binds) <- specImports top_env local_rules uds + ; (spec_rules, spec_binds) <- specImports top_env uds ; return (guts { mg_binds = spec_binds ++ binds' , mg_rules = spec_rules ++ local_rules }) } @@ -681,21 +685,15 @@ specialisation (see canSpecImport): -} specImports :: SpecEnv - -> [CoreRule] -> UsageDetails -> CoreM ([CoreRule], [CoreBind]) -specImports top_env local_rules - (MkUD { ud_binds = dict_binds, ud_calls = calls }) +specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls }) | not $ gopt Opt_CrossModuleSpecialise (se_dflags top_env) -- See Note [Disabling cross-module specialisation] = return ([], wrapDictBinds dict_binds []) | otherwise - = do { hpt_rules <- getRuleBase - ; let rule_base = extendRuleBaseList hpt_rules local_rules - - ; (spec_rules, spec_binds) <- spec_imports top_env [] rule_base - dict_binds calls + = do { (_env, spec_rules, spec_binds) <- spec_imports top_env [] dict_binds calls -- Don't forget to wrap the specialized bindings with -- bindings for the needed dictionaries. @@ -713,89 +711,91 @@ specImports top_env local_rules spec_imports :: 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) -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls -- See Note [Avoiding loops in specImports] -> CallDetails -- Calls for imported things - -> CoreM ( [CoreRule] -- New rules + -> CoreM ( SpecEnv -- Env contains the new rules + , [CoreRule] -- New rules , [CoreBind] ) -- Specialised bindings -spec_imports top_env callers rule_base dict_binds calls +spec_imports env callers 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 + ; (env, rules, spec_binds) <- go env import_calls -- ; debugTraceMsg (text "End specImports }" <+> ppr import_calls) - ; return (rules, spec_binds) } + ; return (env, rules, spec_binds) } where - go :: RuleBase -> [CallInfoSet] -> CoreM ([CoreRule], [CoreBind]) - go _ [] = return ([], []) - go rb (cis : other_calls) + go :: SpecEnv -> [CallInfoSet] -> CoreM (SpecEnv, [CoreRule], [CoreBind]) + go env [] = return (env, [], []) + go env (cis : other_calls) = do { -- debugTraceMsg (text "specImport {" <+> ppr cis) - ; (rules1, spec_binds1) <- spec_import top_env callers rb dict_binds cis + ; (env, rules1, spec_binds1) <- spec_import env callers dict_binds cis ; -- debugTraceMsg (text "specImport }" <+> ppr cis) - ; (rules2, spec_binds2) <- go (extendRuleBaseList rb rules1) other_calls - ; return (rules1 ++ rules2, spec_binds1 ++ spec_binds2) } + ; (env, rules2, spec_binds2) <- go env other_calls + ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) } spec_import :: 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 -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls -- See Note [Avoiding loops in specImports] -> CallInfoSet -- Imported function and calls for it - -> CoreM ( [CoreRule] -- New rules + -> CoreM ( SpecEnv + , [CoreRule] -- New rules , [CoreBind] ) -- Specialised bindings -spec_import top_env callers rb dict_binds cis@(CIS fn _) +spec_import env callers 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 + = return (env, [], []) -- 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 good_calls - = return ([], []) + = return (env, [], []) | Just rhs <- canSpecImport dflags fn = do { -- Get rules from the external package state -- We keep doing this in case we "page-fault in" -- more rules as we go along - ; external_rule_base <- getExternalRuleBase - ; vis_orphs <- getVisibleOrphanMods - ; let rules_for_fn = getRules (RuleEnv [rb, external_rule_base] vis_orphs) fn + ; eps_rules <- getExternalRuleBase + ; let rule_env = se_rules env `updExternalPackageRules` eps_rules - ; -- debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls, ppr rhs]) +-- ; debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls +-- , ppr (getRules rule_env fn), ppr rhs]) ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls }) - <- runSpecM $ specCalls True top_env dict_binds - rules_for_fn good_calls fn rhs + <- runSpecM $ specCalls True env dict_binds + (getRules rule_env 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] + new_subst = se_subst env `Core.extendSubstInScopeList` map fst spec_pairs + new_env = env { se_rules = rule_env `addLocalRules` rules1 + , se_subst = new_subst } + -- Now specialise any cascaded calls - ; -- debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) - ; (rules2, spec_binds2) <- spec_imports top_env - (fn:callers) - (extendRuleBaseList rb rules1) - (dict_binds `thenFDBs` dict_binds1) - new_calls +-- ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1)) + ; (env, rules2, spec_binds2) + <- spec_imports new_env (fn:callers) + (dict_binds `thenFDBs` dict_binds1) + new_calls ; let final_binds = wrapDictBinds dict_binds1 $ spec_binds2 ++ spec_binds1 - ; return (rules2 ++ rules1, final_binds) } + ; return (env, rules2 ++ rules1, final_binds) } | otherwise = do { tryWarnMissingSpecs dflags callers fn good_calls - ; return ([], [])} + ; return (env, [], [])} where - dflags = se_dflags top_env + dflags = se_dflags env good_calls = filterCalls cis dict_binds -- SUPER IMPORTANT! Drop calls that (directly or indirectly) refer to fn -- See Note [Avoiding loops in specImports] @@ -1086,6 +1086,7 @@ data SpecEnv -- the RHS of specialised bindings (no type-let!) , se_module :: Module + , se_rules :: RuleEnv -- From the home package and this module , se_dflags :: DynFlags } @@ -1124,8 +1125,8 @@ specExpr env expr@(App {}) ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args -- Some dicts may have floated out of args_in; - -- they should be in scope for rewriteClassOps (#21689) - (fun_in', args_out') = rewriteClassOps env_args fun_in args_out + -- they should be in scope for fireRewriteRules (#21689) + (fun_in', args_out') = fireRewriteRules env_args fun_in args_out ; (fun_out', uds_fun) <- specExpr env fun_in' ; let uds_call = mkCallUDs env fun_out' args_out' ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) } @@ -1160,17 +1161,19 @@ specExpr env (Let bind body) ; return (foldr Let body' binds', uds) } -- See Note [Specialisation modulo dictionary selectors] --- and Note [ClassOp/DFun selection] -rewriteClassOps :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr]) -rewriteClassOps env (Var f) args - | isClassOpId f -- If we see `op_sel $fCInt`, we rewrite to `$copInt` - , Just (rule, expr) <- -- pprTrace "rewriteClassOps" (ppr f $$ ppr args $$ ppr (se_subst env)) $ - specLookupRule env f args (idCoreRules f) - , let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target] --- , pprTrace "class op rewritten" (ppr f <+> ppr args $$ ppr expr <+> ppr rest_args) True - , (fun, args) <- collectArgs expr - = rewriteClassOps env fun (args++rest_args) -rewriteClassOps _ fun args = (fun, args) +-- Note [ClassOp/DFun selection] +-- Note [Fire rules in the specialiser] +fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr]) +fireRewriteRules env (Var f) args + | Just (rule, expr) <- specLookupRule env f args InitialPhase (getRules (se_rules env) f) + , let rest_args = drop (ruleArity rule) args -- See Note [Extra args in the target] + zapped_subst = Core.zapSubst (se_subst env) + expr' = simpleOptExprWith defaultSimpleOpts zapped_subst expr + -- simplOptExpr needed because lookupRule returns + -- (\x y. rhs) arg1 arg2 + , (fun, args) <- collectArgs expr' + = fireRewriteRules env fun (args++rest_args) +fireRewriteRules _ fun args = (fun, args) -------------- specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails) @@ -1276,7 +1279,61 @@ specCase env scrut case_bndr alts where (env_rhs, args') = substBndrs env_alt args -{- +{- Note [Fire rules in the specialiser] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this (#21851) + + module A where + f :: Num b => b -> (b, b) + f x = (x + 1, snd (f x)) + {-# SPECIALIZE f :: Int -> (Int, Int) #-} + + module B (g') where + import A + + g :: Num a => a -> a + g x = fst (f x) + {-# NOINLINE[99] g #-} + + h :: Int -> Int + h = g + +Note that `f` has the CPR property, and so will worker/wrapper. + +The call to `g` in `h` will make us specialise `g @Int`. And the specialised +version of `g` will contain the call `f @Int`; but in the subsequent run of +the Simplifier, there will be a competition between: +* The user-supplied SPECIALISE rule for `f` +* The inlining of the wrapper for `f` +In fact, the latter wins -- see Note [Rewrite rules and inlining] in +GHC.Core.Opt.Simplify.Iteration. However, it a bit fragile. + +Moreover consider (test T21851_2): + + module A + f :: (Ord a, Show b) => a -> b -> blah + {-# RULE forall b. f @Int @b = wombat #-} + + wombat :: Show b => Int -> b -> blah + wombat = blah + + module B + import A + g :: forall a. Ord a => blah + g @a = ...g...f @a @Char.... + + h = ....g @Int.... + +Now, in module B, GHC will specialise `g @Int`, which will lead to a +call `f @Int @Char`. If we immediately (in the specialiser) rewrite +that to `womabat @Char`, we have a chance to specialise `wombat`. + +Conclusion: it's treat if the Specialiser fires RULEs itself. +It's not hard to achieve: see `fireRewriteRules`. The only tricky bit is +making sure that we have a reasonably up to date EPS rule base. Currently +we load it up just once, in `initRuleEnv`, called at the beginning of +`specProgram`. + Note [Floating dictionaries out of cases] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1367,13 +1424,12 @@ specBind top_lvl env (NonRec fn rhs) do_body final_binds :: [DictBind] -- See Note [From non-recursive to recursive] - final_binds - | not (isNilOL dump_dbs) - , not (null spec_defns) - = [recWithDumpedDicts pairs dump_dbs] - | otherwise - = [mkDB $ NonRec b r | (b,r) <- pairs] - ++ fromOL dump_dbs + final_binds | not (isNilOL dump_dbs) + , not (null spec_defns) + = [recWithDumpedDicts pairs dump_dbs] + | otherwise + = [mkDB $ NonRec b r | (b,r) <- pairs] + ++ fromOL dump_dbs ; if float_all then -- Rather than discard the calls mentioning the bound variables @@ -1505,8 +1561,10 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs foldlM spec_call ([], [], emptyUDs) calls_for_me | otherwise -- No calls or RHS doesn't fit our preconceptions - = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me) + = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me && not (isClassOpId fn)) "Missed specialisation opportunity" (ppr fn $$ _trace_doc) $ + -- isClassOpId: class-op Ids never inline; we specialise them + -- through fireRewriteRules. So don't complain about missed opportunities -- Note [Specialisation shape] -- pprTrace "specCalls: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) @@ -1533,9 +1591,13 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs already_covered :: SpecEnv -> [CoreRule] -> [CoreExpr] -> Bool already_covered env new_rules args -- Note [Specialisations already covered] - = isJust (specLookupRule env fn args (new_rules ++ existing_rules)) - -- NB: we look both in the new_rules (generated by this invocation - -- of specCalls), and in existing_rules (passed in to specCalls) + = isJust (specLookupRule env fn args (beginPhase inl_act) + (new_rules ++ existing_rules)) + -- Rules: we look both in the new_rules (generated by this invocation + -- of specCalls), and in existing_rules (passed in to specCalls) + -- inl_act: is the activation we are going to put in the new SPEC + -- rule; so we want to see if it is covered by another rule with + -- that same activation. ---------------------------------------------------------- -- Specialise to one particular call pattern @@ -1653,13 +1715,16 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs -- Convenience function for invoking lookupRule from Specialise -- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr] -specLookupRule :: SpecEnv -> Id -> [CoreExpr] -> [CoreRule] -> Maybe (CoreRule, CoreExpr) -specLookupRule env fn args rules - = lookupRule ropts (in_scope, realIdUnfolding) (const True) fn args rules +specLookupRule :: SpecEnv -> Id -> [CoreExpr] + -> CompilerPhase -- Look up rules as if we were in this phase + -> [CoreRule] -> Maybe (CoreRule, CoreExpr) +specLookupRule env fn args phase rules + = lookupRule ropts (in_scope, realIdUnfolding) is_active fn args rules where - dflags = se_dflags env - in_scope = getSubstInScope (se_subst env) - ropts = initRuleOpts dflags + dflags = se_dflags env + in_scope = getSubstInScope (se_subst env) + ropts = initRuleOpts dflags + is_active = isActive phase {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1846,10 +1911,10 @@ We want to specialise this! How? By doing the method-selection rewrite in the Specialiser. Hence 1. In the App case of 'specExpr', try to apply the ClassOp/DFun rule on the - head of the application, repeatedly, via 'rewriteClassOps'. + head of the application, repeatedly, via 'fireRewriteRules'. 2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and `$dShow` in `bindAuxiliaryDict`, so that we can exploit the unfolding - in 'rewriteClassOps' to do the ClassOp/DFun rewrite. + in 'fireRewriteRules' to do the ClassOp/DFun rewrite. NB: Without (2), (1) would be pointless, because 'lookupRule' wouldn't be able to look into the RHS of `$dC` to see the DFun. ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -12,8 +12,10 @@ module GHC.Core.Rules ( lookupRule, -- ** RuleBase, RuleEnv + RuleBase, RuleEnv(..), mkRuleEnv, emptyRuleEnv, + updExternalPackageRules, addLocalRules, updLocalRules, emptyRuleBase, mkRuleBase, extendRuleBaseList, - pprRuleBase, extendRuleEnv, + pprRuleBase, -- ** Checking rule applications ruleCheckProgram, @@ -22,6 +24,8 @@ module GHC.Core.Rules ( extendRuleInfo, addRuleInfo, addIdSpecialisations, + -- ** RuleBase and RuleEnv + -- * Misc. CoreRule helpers rulesOfBinds, getRules, pprRulesForUser, @@ -34,6 +38,8 @@ import GHC.Prelude import GHC.Unit.Module ( Module ) import GHC.Unit.Module.Env +import GHC.Unit.Module.ModGuts( ModGuts(..) ) +import GHC.Unit.Module.Deps( Dependencies(..) ) import GHC.Driver.Session( DynFlags ) import GHC.Driver.Ppr( showSDoc ) @@ -136,7 +142,7 @@ Note [Overall plumbing for rules] * At the moment (c) is carried in a reader-monad way by the GHC.Core.Opt.Monad. The HomePackageTable doesn't have a single RuleBase because technically we should only be able to "see" rules "below" this module; so we - generate a RuleBase for (c) by combing rules from all the modules + generate a RuleBase for (c) by combining rules from all the modules "below" us. That's why we can't just select the home-package RuleBase from HscEnv. @@ -340,12 +346,100 @@ addIdSpecialisations id rules rulesOfBinds :: [CoreBind] -> [CoreRule] rulesOfBinds binds = concatMap (concatMap idCoreRules . bindersOf) binds + +{- +************************************************************************ +* * + RuleBase +* * +************************************************************************ +-} + +-- | Gathers a collection of 'CoreRule's. Maps (the name of) an 'Id' to its rules +type RuleBase = NameEnv [CoreRule] + -- The rules are unordered; + -- we sort out any overlaps on lookup + +emptyRuleBase :: RuleBase +emptyRuleBase = emptyNameEnv + +mkRuleBase :: [CoreRule] -> RuleBase +mkRuleBase rules = extendRuleBaseList emptyRuleBase rules + +extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase +extendRuleBaseList rule_base new_guys + = foldl' extendRuleBase rule_base new_guys + +extendRuleBase :: RuleBase -> CoreRule -> RuleBase +extendRuleBase rule_base rule + = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule + +pprRuleBase :: RuleBase -> SDoc +pprRuleBase rules = pprUFM rules $ \rss -> + vcat [ pprRules (tidyRules emptyTidyEnv rs) + | rs <- rss ] + +-- | A full rule environment which we can apply rules from. Like a 'RuleBase', +-- but it also includes the set of visible orphans we use to filter out orphan +-- rules which are not visible (even though we can see them...) +-- See Note [Orphans] in GHC.Core +data RuleEnv + = RuleEnv { re_local_rules :: !RuleBase -- Rules from this module + , re_home_rules :: !RuleBase -- Rule from the home package + -- (excl this module) + , re_eps_rules :: !RuleBase -- Rules from other packages + -- see Note [External package rules] + , re_visible_orphs :: !ModuleSet + } + +mkRuleEnv :: ModGuts -> RuleBase -> RuleBase -> RuleEnv +mkRuleEnv (ModGuts { mg_module = this_mod + , mg_deps = deps + , mg_rules = local_rules }) + eps_rules hpt_rules + = RuleEnv { re_local_rules = mkRuleBase local_rules + , re_home_rules = hpt_rules + , re_eps_rules = eps_rules + , re_visible_orphs = mkModuleSet vis_orphs } + where + vis_orphs = this_mod : dep_orphs deps + +updExternalPackageRules :: RuleEnv -> RuleBase -> RuleEnv +-- Completely over-ride the external rules in RuleEnv +updExternalPackageRules rule_env eps_rules + = rule_env { re_eps_rules = eps_rules } + +updLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv +-- Completely over-ride the local rules in RuleEnv +updLocalRules rule_env local_rules + = rule_env { re_local_rules = mkRuleBase local_rules } + +addLocalRules :: RuleEnv -> [CoreRule] -> RuleEnv +-- Add new local rules +addLocalRules rule_env rules + = rule_env { re_local_rules = extendRuleBaseList (re_local_rules rule_env) rules } + +emptyRuleEnv :: RuleEnv +emptyRuleEnv = RuleEnv { re_local_rules = emptyNameEnv + , re_home_rules = emptyNameEnv + , re_eps_rules = emptyNameEnv + , re_visible_orphs = emptyModuleSet } + getRules :: RuleEnv -> Id -> [CoreRule] +-- Given a RuleEnv and an Id, find the visible rules for that Id -- See Note [Where rules are found] -getRules (RuleEnv { re_base = rule_base, re_visible_orphs = orphs }) fn - = idCoreRules fn ++ concatMap imp_rules rule_base +getRules (RuleEnv { re_local_rules = local_rules + , re_home_rules = home_rules + , re_eps_rules = eps_rules + , re_visible_orphs = orphs }) fn + = idCoreRules fn ++ + get local_rules ++ + find_visible home_rules ++ + find_visible eps_rules where - imp_rules rb = filter (ruleIsVisible orphs) (lookupNameEnv rb (idName fn) `orElse` []) + fn_name = idName fn + find_visible rb = filter (ruleIsVisible orphs) (get rb) + get rb = lookupNameEnv rb fn_name `orElse` [] ruleIsVisible :: ModuleSet -> CoreRule -> Bool ruleIsVisible _ BuiltinRule{} = True @@ -371,37 +465,28 @@ but that isn't quite right: in the module defining the Id (when it's a LocalId), but the rules are kept in the global RuleBase + Note [External package rules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In Note [Overall plumbing for rules], it is explained that the final +RuleBase which we must consider is combined from 4 different sources. -************************************************************************ -* * - RuleBase -* * -************************************************************************ --} - --- RuleBase itself is defined in GHC.Core, along with CoreRule - -emptyRuleBase :: RuleBase -emptyRuleBase = emptyNameEnv - -mkRuleBase :: [CoreRule] -> RuleBase -mkRuleBase rules = extendRuleBaseList emptyRuleBase rules +During simplifier runs, the fourth source of rules is constantly being updated +as new interfaces are loaded into the EPS. Therefore just before we check to see +if any rules match we get the EPS RuleBase and combine it with the existing RuleBase +and then perform exactly 1 lookup into the new map. -extendRuleBaseList :: RuleBase -> [CoreRule] -> RuleBase -extendRuleBaseList rule_base new_guys - = foldl' extendRuleBase rule_base new_guys +It is more efficient to avoid combining the environments and store the uncombined +environments as we can instead perform 1 lookup into each environment and then combine +the results. -extendRuleBase :: RuleBase -> CoreRule -> RuleBase -extendRuleBase rule_base rule - = extendNameEnv_Acc (:) Utils.singleton rule_base (ruleIdName rule) rule +Essentially we use the identity: -extendRuleEnv :: RuleEnv -> RuleBase -> RuleEnv -extendRuleEnv (RuleEnv rules orphs) rb = (RuleEnv (rb:rules) orphs) +> lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) +> = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 -pprRuleBase :: RuleBase -> SDoc -pprRuleBase rules = pprUFM rules $ \rss -> - vcat [ pprRules (tidyRules emptyTidyEnv rs) - | rs <- rss ] +The latter being more efficient as we don't construct an intermediate +map. +-} {- ************************************************************************ @@ -1576,7 +1661,7 @@ ruleCheckFun env fn args | otherwise = unitBag (ruleAppCheck_help env fn args name_match_rules) where name_match_rules = filter match (rc_rules env fn) - match rule = (rc_pattern env) `isPrefixOf` unpackFS (ruleName rule) + match rule = rc_pattern env `isPrefixOf` unpackFS (ruleName rule) ruleAppCheck_help :: RuleCheckEnv -> Id -> [CoreExpr] -> [CoreRule] -> SDoc ruleAppCheck_help env fn args rules ===================================== compiler/GHC/Driver/Config/Core/Opt/Simplify.hs ===================================== @@ -7,7 +7,7 @@ module GHC.Driver.Config.Core.Opt.Simplify import GHC.Prelude -import GHC.Core ( RuleBase ) +import GHC.Core.Rules ( RuleBase ) import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Core.Opt.Simplify ( SimplifyExprOpts(..), SimplifyOpts(..) ) import GHC.Core.Opt.Simplify.Env ( FloatEnable(..), SimplMode(..) ) @@ -40,20 +40,19 @@ initSimplifyExprOpts dflags ic = SimplifyExprOpts } initSimplifyOpts :: DynFlags -> [Var] -> Int -> SimplMode -> RuleBase -> SimplifyOpts -initSimplifyOpts dflags extra_vars iterations mode rule_base = let +initSimplifyOpts dflags extra_vars iterations mode hpt_rule_base = let -- This is a particularly ugly construction, but we will get rid of it in !8341. opts = SimplifyOpts { so_dump_core_sizes = not $ gopt Opt_SuppressCoreSizes dflags - , so_iterations = iterations - , so_mode = mode + , so_iterations = iterations + , so_mode = mode , so_pass_result_cfg = if gopt Opt_DoCoreLinting dflags - then Just $ initLintPassResultConfig dflags extra_vars (CoreDoSimplify opts) - else Nothing - , so_rule_base = rule_base - , so_top_env_cfg = TopEnvConfig - { te_history_size = historySize dflags - , te_tick_factor = simplTickFactor dflags - } + then Just $ initLintPassResultConfig dflags extra_vars + (CoreDoSimplify opts) + else Nothing + , so_hpt_rules = hpt_rule_base + , so_top_env_cfg = TopEnvConfig { te_history_size = historySize dflags + , te_tick_factor = simplTickFactor dflags } } in opts ===================================== compiler/GHC/Unit/External.hs ===================================== @@ -21,11 +21,10 @@ import GHC.Prelude import GHC.Unit import GHC.Unit.Module.ModIface -import GHC.Core ( RuleBase ) import GHC.Core.FamInstEnv import GHC.Core.InstEnv ( InstEnv, emptyInstEnv ) import GHC.Core.Opt.ConstantFold -import GHC.Core.Rules (mkRuleBase) +import GHC.Core.Rules ( RuleBase, mkRuleBase) import GHC.Types.Annotations ( AnnEnv, emptyAnnEnv ) import GHC.Types.CompleteMatch ===================================== libraries/base/GHC/Real.hs ===================================== @@ -701,11 +701,14 @@ half of y - 1 can be computed as y `quot` 2, optimising subtraction away. Note [Inlining (^) ~~~~~~~~~~~~~~~~~~ -The INLINABLE pragma allows (^) to be specialised at its call sites. +The INLINABLE [1] pragma allows (^) to be specialised at its call sites. If it is called repeatedly at the same type, that can make a huge difference, because of those constants which can be repeatedly calculated. +We don't inline until phase 1, to give a chance for the RULES +"^2/Int" etc to fire first. + Currently the fromInteger calls are not floated because we get \d1 d2 x y -> blah after the gentle round of simplification. ===================================== testsuite/tests/simplCore/should_compile/T21851.stderr ===================================== @@ -15,5 +15,3 @@ g' :: Int -> Int g' = \ (x :: Int) -> case T21851a.$w$sf x of { (# ww, ww1 #) -> ww } - - ===================================== testsuite/tests/simplCore/should_compile/T21851_2.hs ===================================== @@ -0,0 +1,15 @@ +{-# OPTIONS_GHC -ddump-simpl -dsuppress-uniques -dno-typeable-binds #-} + +module T21851_2 where + +import T21851_2a + +g :: forall a. (Ord a, Num a) => a -> (a,String) +g n | n < 10 = (0, f n True) + | otherwise = g (n-2) +-- The specialised version of g leads to a specialised +-- call to (f @Int @Bool). Then we want to fire f's RULE +-- and specialise 'wombat' + +h = g (3::Int) + ===================================== testsuite/tests/simplCore/should_compile/T21851_2.stderr ===================================== @@ -0,0 +1,120 @@ +[1 of 2] Compiling T21851_2a ( T21851_2a.hs, T21851_2a.o ) +[2 of 2] Compiling T21851_2 ( T21851_2.hs, T21851_2.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 107, types: 96, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Integer +[GblId, Unf=OtherCon []] +lvl = GHC.Num.Integer.IS 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl1 :: Integer +[GblId, Unf=OtherCon []] +lvl1 = GHC.Num.Integer.IS 0# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl2 :: Integer +[GblId, Unf=OtherCon []] +lvl2 = GHC.Num.Integer.IS 10# + +Rec { +-- RHS size: {terms: 25, types: 5, coercions: 0, joins: 0/0} +T21851_2.$s$wwombat [InlPrag=[~], Occ=LoopBreaker] + :: GHC.Prim.Int# -> Bool -> [Char] +[GblId, Arity=2, Str=<1L>, Unf=OtherCon []] +T21851_2.$s$wwombat + = \ (ww :: GHC.Prim.Int#) (y :: Bool) -> + case ww of ds { + __DEFAULT -> + case y of { + False -> + GHC.CString.unpackAppendCString# + GHC.Show.$fShowBool3 + (T21851_2.$s$wwombat (GHC.Prim.-# ds 1#) GHC.Types.False); + True -> + GHC.CString.unpackAppendCString# + GHC.Show.$fShowBool2 + (T21851_2.$s$wwombat (GHC.Prim.-# ds 1#) GHC.Types.True) + }; + 0# -> GHC.Types.[] @Char + } +end Rec } + +Rec { +-- RHS size: {terms: 16, types: 6, coercions: 0, joins: 0/0} +T21851_2.$w$sg [InlPrag=[2], Occ=LoopBreaker] + :: GHC.Prim.Int# -> (# GHC.Prim.Int#, String #) +[GblId, Arity=1, Str=, Unf=OtherCon []] +T21851_2.$w$sg + = \ (ww :: GHC.Prim.Int#) -> + case GHC.Prim.<# ww 10# of { + __DEFAULT -> T21851_2.$w$sg (GHC.Prim.-# ww 2#); + 1# -> (# 0#, T21851_2.$s$wwombat ww GHC.Types.True #) + } +end Rec } + +-- RHS size: {terms: 3, types: 3, coercions: 0, joins: 0/0} +lvl3 :: forall {a}. [Char] +[GblId] +lvl3 = \ (@a) -> T21851_2a.$wf GHC.Prim.(##) @a @Bool + +Rec { +-- RHS size: {terms: 27, types: 18, coercions: 0, joins: 0/0} +T21851_2.$wg [InlPrag=[2], Occ=LoopBreaker] + :: forall {a}. (Ord a, Num a) => a -> (# a, String #) +[GblId[StrictWorker([!])], + Arity=3, + Str=, + Unf=OtherCon []] +T21851_2.$wg + = \ (@a) ($dOrd :: Ord a) ($dNum :: Num a) (n :: a) -> + case < @a $dOrd n (fromInteger @a $dNum lvl2) of { + False -> + T21851_2.$wg + @a $dOrd $dNum (- @a $dNum n (fromInteger @a $dNum lvl)); + True -> (# fromInteger @a $dNum lvl1, lvl3 @a #) + } +end Rec } + +-- RHS size: {terms: 13, types: 16, coercions: 0, joins: 0/0} +g [InlPrag=[2]] :: forall a. (Ord a, Num a) => a -> (a, String) +[GblId, + Arity=3, + Str=, + Cpr=1, + Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) + Tmpl= \ (@a) + ($dOrd [Occ=Once1] :: Ord a) + ($dNum [Occ=Once1] :: Num a) + (n [Occ=Once1] :: a) -> + case T21851_2.$wg @a $dOrd $dNum n of + { (# ww [Occ=Once1], ww1 [Occ=Once1] #) -> + (ww, ww1) + }}] +g = \ (@a) ($dOrd :: Ord a) ($dNum :: Num a) (n :: a) -> + case T21851_2.$wg @a $dOrd $dNum n of { (# ww, ww1 #) -> + (ww, ww1) + } + +-- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} +h :: (Int, String) +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] +h = case T21851_2.$w$sg 3# of { (# ww, ww1 #) -> + (GHC.Types.I# ww, ww1) + } + + +------ Local rules for imported ids -------- +"SPEC/T21851_2 $wwombat @Bool" [2] + forall ($dShow :: Show Bool). + T21851_2a.$wwombat @Bool $dShow + = T21851_2.$s$wwombat + + ===================================== testsuite/tests/simplCore/should_compile/T21851_2a.hs ===================================== @@ -0,0 +1,11 @@ +module T21851_2a where + +f :: (Num a, Show b) => a -> b -> String +{-# NOINLINE f #-} +f x y = "no" +{-# RULES "wombat" f = wombat #-} + +wombat :: Show b => Int -> b -> String +{-# INLINEABLE wombat #-} +wombat 0 y = "" +wombat n y = show y ++ wombat (n-1) y ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -434,3 +434,7 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) + +# One module, T21851_2.hs, has OPTIONS_GHC -ddump-simpl +# Expecting to see $s$wwombat +test('T21851_2', [grep_errmsg(r'wwombat') ], multimod_compile, ['T21851_2', '-O -dno-typeable-binds -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3b1ddd8784556ba6c9a69cca1c80d665b5e991b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3b1ddd8784556ba6c9a69cca1c80d665b5e991b You're receiving 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 Oct 11 16:49:04 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 12:49:04 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Tidy implicit binds Message-ID: <63459e80b8e07_1eea6a514c812961ca@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - 30 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Unit/Home/ModInfo.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/ModIface.hs - compiler/GHC/Unit/Module/Status.hs - + compiler/GHC/Unit/Module/WholeCoreBindings.hs - compiler/ghc.cabal.in - docs/users_guide/phases.rst - ghc/GHCi/Leak.hs - ghc/Main.hs - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ed4b5885bdac7b986655bb40f8c9ece2f8735c98...9789ea8e9f35d5c0674e10730c3435c4d3293f2b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ed4b5885bdac7b986655bb40f8c9ece2f8735c98...9789ea8e9f35d5c0674e10730c3435c4d3293f2b You're receiving 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 Oct 11 16:49:42 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 12:49:42 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Don't keep exit join points so much Message-ID: <63459ea6df58c_1eea6a5face52c13003f5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 11 changed files: - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - + testsuite/tests/simplCore/should_compile/T21148.hs - + testsuite/tests/simplCore/should_compile/T21148.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/T21128.hs - testsuite/tests/stranal/should_compile/T21128.stderr Changes: ===================================== compiler/GHC/Core/Opt/Exitify.hs ===================================== @@ -433,6 +433,7 @@ inlining. Exit join points, recognizable using `isExitJoinId` are join points with an occurrence in a recursive group, and can be recognized (after the occurrence analyzer ran!) using `isExitJoinId`. + This function detects joinpoints with `occ_in_lam (idOccinfo id) == True`, because the lambdas of a non-recursive join point are not considered for `occ_in_lam`. For example, in the following code, `j1` is /not/ marked @@ -446,6 +447,29 @@ To prevent inlining, we check for isExitJoinId * In `simplLetUnfolding` we simply give exit join points no unfolding, which prevents inlining in `postInlineUnconditionally` and call sites. +But see Note [Be selective about not-inlining exit join points] + +Note [Be selective about not-inlining exit join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If we follow "do not inline exit join points" mantra throughout, +some bad things happen. + +* We can lose CPR information: see #21148 + +* We get useless clutter (#22084) that + - makes the program bigger (including duplicated code #20739), and + - adds extra jumps (and maybe stack saves) at runtime + +So instead we follow "do not inline exit join points" for a /single run/ +of the simplifier, right after Exitification. That should give a +sufficient chance for used-once things to inline, but subsequent runs +will inline them back in. (Annoyingly, as things stand, only with -O2 +is there a subsequent run, but that might change, and it's not a huge +deal anyway.) + +This is controlled by the Simplifier's sm_keep_exits flag; see +GHC.Core.Opt.Pipeline. + Note [Placement of the exitification pass] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I (Joachim) experimented with multiple positions for the Exitification pass in ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Driver.Plugins ( withPlugins, installCoreToDos ) import GHC.Driver.Env import GHC.Driver.Config.Core.Lint ( endPass ) import GHC.Driver.Config.Core.Opt.LiberateCase ( initLiberateCaseOpts ) -import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode, initGentleSimplMode ) +import GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyOpts, initSimplMode ) import GHC.Driver.Config.Core.Opt.WorkWrap ( initWorkWrapOpts ) import GHC.Driver.Config.Core.Rules ( initRuleOpts ) import GHC.Platform.Ways ( hasWay, Way(WayProf) ) @@ -28,6 +28,7 @@ import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.Lint ( lintAnnots ) import GHC.Core.Lint.Interactive ( interactiveInScope ) import GHC.Core.Opt.Simplify ( simplifyExpr, simplifyPgm ) +import GHC.Core.Opt.Simplify.Env( SimplMode(..) ) import GHC.Core.Opt.Simplify.Monad import GHC.Core.Opt.Monad import GHC.Core.Opt.Pipeline.Types @@ -154,32 +155,45 @@ getCoreToDo dflags rule_base extra_vars maybe_strictness_before _ = CoreDoNothing - simpl_phase phase name iter - = CoreDoPasses - $ [ maybe_strictness_before phase - , CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter - (initSimplMode dflags phase name) rule_base - , maybe_rule_check phase ] + ---------------------------- + base_simpl_mode :: SimplMode + base_simpl_mode = initSimplMode dflags - -- Run GHC's internal simplification phase, after all rules have run. - -- See Note [Compiler phases] in GHC.Types.Basic - simplify name = simpl_phase FinalPhase name max_iter - - -- initial simplify: mk specialiser happy: minimum effort please + -- gentle_mode: make specialiser happy: minimum effort please -- See Note [Inline in InitialPhase] -- See Note [RULEs enabled in InitialPhase] - simpl_gently = CoreDoSimplify $ initSimplifyOpts dflags extra_vars max_iter - (initGentleSimplMode dflags) rule_base + gentle_mode = base_simpl_mode { sm_names = ["Gentle"] + , sm_phase = InitialPhase + , sm_case_case = False } + + simpl_mode phase name + = base_simpl_mode { sm_names = [name], sm_phase = phase } + + keep_exits :: SimplMode -> SimplMode + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + keep_exits mode = mode { sm_keep_exits = True } + + ---------------------------- + run_simplifier mode iter + = CoreDoSimplify $ initSimplifyOpts dflags extra_vars iter mode rule_base + simpl_phase phase name iter = CoreDoPasses $ + [ maybe_strictness_before phase + , run_simplifier (simpl_mode phase name) iter + , maybe_rule_check phase ] + + -- Run GHC's internal simplification phase, after all rules have run. + -- See Note [Compiler phases] in GHC.Types.Basic + simpl_gently = run_simplifier gentle_mode max_iter + simplify_final name = run_simplifier ( simpl_mode FinalPhase name) max_iter + simpl_keep_exits name = run_simplifier (keep_exits $ simpl_mode FinalPhase name) max_iter + + ---------------------------- dmd_cpr_ww = if ww_on then [CoreDoDemand True,CoreDoCpr,CoreDoWorkerWrapper] else [CoreDoDemand False] -- NB: No CPR! See Note [Don't change boxity without worker/wrapper] - demand_analyser = (CoreDoPasses ( - dmd_cpr_ww ++ - [simplify "post-worker-wrapper"] - )) - -- Static forms are moved to the top level with the FloatOut pass. -- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable. static_ptrs_float_outwards = @@ -269,14 +283,16 @@ getCoreToDo dflags rule_base extra_vars runWhen call_arity $ CoreDoPasses [ CoreDoCallArity - , simplify "post-call-arity" + , simplify_final "post-call-arity" ], -- Strictness analysis - runWhen strictness demand_analyser, + runWhen strictness $ CoreDoPasses + (dmd_cpr_ww ++ [simplify_final "post-worker-wrapper"]), runWhen exitification CoreDoExitify, -- See Note [Placement of the exitification pass] + -- in GHC.Core.Opt.Exitify runWhen full_laziness $ CoreDoFloatOutwards FloatOutSwitches { @@ -298,7 +314,17 @@ getCoreToDo dflags rule_base extra_vars runWhen do_float_in CoreDoFloatInwards, - simplify "final", -- Final tidy-up + -- Final tidy-up run of the simplifier + simpl_keep_exits "final tidy up", + -- Keep exit join point because this is the first + -- Simplifier run after Exitify. Subsequent runs will + -- re-inline those exit join points; their work is done. + -- See Note [Be selective about not-inlining exit join points] + -- in GHC.Core.Opt.Exitify + -- + -- Annoyingly, we only /have/ a subsequent run with -O2. With + -- plain -O we'll still have those exit join points hanging around. + -- Oh well. maybe_rule_check FinalPhase, @@ -308,31 +334,31 @@ getCoreToDo dflags rule_base extra_vars -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. runWhen liberate_case $ CoreDoPasses - [ CoreLiberateCase, simplify "post-liberate-case" ], + [ CoreLiberateCase, simplify_final "post-liberate-case" ], -- Run the simplifier after LiberateCase to vastly -- reduce the possibility of shadowing -- Reason: see Note [Shadowing] in GHC.Core.Opt.SpecConstr runWhen spec_constr $ CoreDoPasses - [ CoreDoSpecConstr, simplify "post-spec-constr"], + [ CoreDoSpecConstr, simplify_final "post-spec-constr"], -- See Note [Simplify after SpecConstr] maybe_rule_check FinalPhase, runWhen late_specialise $ CoreDoPasses - [ CoreDoSpecialising, simplify "post-late-spec"], + [ CoreDoSpecialising, simplify_final "post-late-spec"], -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this -- in wheel-sieve1), and I'm guessing that SpecConstr can too -- And CSE is a very cheap pass. So it seems worth doing here. runWhen ((liberate_case || spec_constr) && cse) $ CoreDoPasses - [ CoreCSE, simplify "post-final-cse" ], + [ CoreCSE, simplify_final "post-final-cse" ], --------- End of -O2 passes -------------- runWhen late_dmd_anal $ CoreDoPasses ( - dmd_cpr_ww ++ [simplify "post-late-ww"] + dmd_cpr_ww ++ [simplify_final "post-late-ww"] ), -- Final run of the demand_analyser, ensures that one-shot thunks are ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -248,13 +248,16 @@ data SimplMode = SimplMode -- See comments in GHC.Core.Opt.Simplify.Monad , sm_uf_opts :: !UnfoldingOpts -- ^ Unfolding options , sm_case_case :: !Bool -- ^ Whether case-of-case is enabled , sm_pre_inline :: !Bool -- ^ Whether pre-inlining is enabled - , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out + , sm_keep_exits :: !Bool -- ^ True <=> keep ExitJoinIds + -- See Note [Do not inline exit join points] + -- in GHC.Core.Opt.Exitify + , sm_float_enable :: !FloatEnable -- ^ Whether to enable floating out , sm_do_eta_reduction :: !Bool - , sm_arity_opts :: !ArityOpts - , sm_rule_opts :: !RuleOpts - , sm_case_folding :: !Bool - , sm_case_merge :: !Bool - , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options + , sm_arity_opts :: !ArityOpts + , sm_rule_opts :: !RuleOpts + , sm_case_folding :: !Bool + , sm_case_merge :: !Bool + , sm_co_opt_opts :: !OptCoercionOpts -- ^ Coercion optimiser options } instance Outputable SimplMode where ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1333,11 +1333,11 @@ preInlineUnconditionally -- Reason: we don't want to inline single uses, or discard dead bindings, -- for unlifted, side-effect-ful bindings preInlineUnconditionally env top_lvl bndr rhs rhs_env - | not pre_inline_unconditionally = Nothing + | not pre_inline = Nothing | not active = Nothing | isTopLevel top_lvl && isDeadEndId bndr = Nothing -- Note [Top-level bottoming Ids] | isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally] - | isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] + | keep_exits, isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] -- in module Exitify | not (one_occ (idOccInfo bndr)) = Nothing | not (isStableUnfolding unf) = Just $! (extend_subst_with rhs) @@ -1347,19 +1347,36 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env , Just inl <- maybeUnfoldingTemplate unf = Just $! (extend_subst_with inl) | otherwise = Nothing where + mode = seMode env + phase = sm_phase mode + keep_exits = sm_keep_exits mode + pre_inline = sm_pre_inline mode + unf = idUnfolding bndr extend_subst_with inl_rhs = extendIdSubst env bndr $! (mkContEx rhs_env inl_rhs) one_occ IAmDead = True -- Happens in ((\x.1) v) + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = NotInsideLam } = isNotTopLevel top_lvl || early_phase + one_occ OneOcc{ occ_n_br = 1 , occ_in_lam = IsInsideLam , occ_int_cxt = IsInteresting } = canInlineInLam rhs - one_occ _ = False - pre_inline_unconditionally = sePreInline env - active = isActive (sePhase env) (inlinePragmaActivation inline_prag) + one_occ OneOcc{ occ_n_br = 1 } -- Inline join point that are used once, even inside + | isJoinId bndr = True -- lambdas (which are presumably other join points) + -- E.g. join j x = rhs in + -- joinrec k y = ....j x.... + -- Here j must be an exit for k, and we can safely inline it under the lambda + -- This includes the case where j is nullary: a nullary join point is just the + -- same as an arity-1 one. So we don't look at occ_int_cxt. + -- All of this only applies if keep_exits is False, otherwise the + -- earlier guard on preInlineUnconditionally would have fired + + one_occ _ = False + + active = isActive phase (inlinePragmaActivation inline_prag) -- See Note [pre/postInlineUnconditionally in gentle mode] inline_prag = idInlinePragma bndr @@ -1391,7 +1408,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = sePhase env /= FinalPhase + early_phase = phase /= FinalPhase -- If we don't have this early_phase test, consider -- x = length [1,2,3] -- The full laziness pass carefully floats all the cons cells to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -881,7 +881,7 @@ data SpecConstrOpts = SpecConstrOpts , sc_count :: !(Maybe Int) -- ^ Max # of specialisations for any one function. Nothing => no limit. - -- See Note [Avoiding exponential blowup]. + -- See Note [Avoiding exponential blowup] and decreaseSpecCount , sc_recursive :: !Int -- ^ Max # of specialisations over recursive type. Stops @@ -1098,16 +1098,20 @@ extendCaseBndrs env scrut case_bndr con alt_bndrs decreaseSpecCount :: ScEnv -> Int -> ScEnv -- See Note [Avoiding exponential blowup] -decreaseSpecCount env n_specs +decreaseSpecCount env _n_specs = env { sc_force = False -- See Note [Forcing specialisation] - , sc_opts = (sc_opts env) - { sc_count = case sc_count $ sc_opts env of - Nothing -> Nothing - Just n -> Just $! (n `div` (n_specs + 1)) + , sc_opts = opts { sc_count = case sc_count opts of + Nothing -> Nothing + Just n -> Just $! dec n } } - -- The "+1" takes account of the original function; - -- See Note [Avoiding exponential blowup] + where + opts = sc_opts env + dec n = n `div` 2 -- See Note [Avoiding exponential blowup] + + -- Or: n `div` (n_specs + 1) + -- See the historical note part of Note [Avoiding exponential blowup] + -- The "+1" takes account of the original function; --------------------------------------------------- -- See Note [Forcing specialisation] @@ -1183,9 +1187,20 @@ we can specialise $j2, and similarly $j3. Even if we make just *one* specialisation of each, because we also have the original we'll get 2^n copies of $j3, which is not good. -So when recursively specialising we divide the sc_count by the number of -copies we are making at this level, including the original. - +So when recursively specialising we divide the sc_count (the maximum +number of specialisations, in the ScEnv) by two. You might think that +gives us n*(n/2)*(n/4)... copies of the innnermost thing, which is +still exponential the depth. But we use integer division, rounding +down, so if the starting sc_count is 3, we'll get 3 -> 1 -> 0, and +stop. In fact, simply subtracting 1 would be good enough, for the same +reason. + +Historical note: in the past we divided by (n_specs+1), where n_specs +is the number of specialisations at this level; but that gets us down +to zero jolly quickly, which I found led to some regressions. (An +example is nofib/spectral/fibheaps, the getMin' function inside the +outer function $sfibToList, which has several interesting call +patterns.) ************************************************************************ * * @@ -1512,8 +1527,10 @@ scExpr' env (Case scrut b ty alts) scrut_occ = case con of DataAlt dc -- See Note [Do not specialise evals] | not (single_alt && all deadArgOcc arg_occs) - -> ScrutOcc (unitUFM dc arg_occs) - _ -> UnkOcc + -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + ScrutOcc (unitUFM dc arg_occs) + _ -> -- pprTrace "sc_alt1" (ppr b' $$ ppr con $$ ppr bs $$ ppr arg_occs) $ + UnkOcc ; return (usg', b_occ `combineOcc` scrut_occ, Alt con bs2 rhs') } @@ -1792,16 +1809,19 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs , not (null arg_bndrs) -- Only specialise functions , Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it = -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $ - do { (boring_call, new_pats) <- callsToNewPats env fn spec_info arg_occs all_calls + do { (boring_call, pats_discarded, new_pats) + <- callsToNewPats env fn spec_info arg_occs all_calls ; let n_pats = length new_pats --- ; if (not (null new_pats) || isJust mb_unspec) then --- pprTrace "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" --- , text "mb_unspec" <+> ppr (isJust mb_unspec) --- , text "arg_occs" <+> ppr arg_occs --- , text "good pats" <+> ppr new_pats]) $ --- return () --- else return () +-- ; when (not (null new_pats) || isJust mb_unspec) $ +-- pprTraceM "specialise" (vcat [ ppr fn <+> text "with" <+> int n_pats <+> text "good patterns" +-- , text "boring_call:" <+> ppr boring_call +-- , text "pats_discarded:" <+> ppr pats_discarded +-- , text "old spec_count" <+> ppr spec_count +-- , text "spec count limit" <+> ppr (sc_count (sc_opts env)) +-- , text "mb_unspec" <+> ppr (isJust mb_unspec) +-- , text "arg_occs" <+> ppr arg_occs +-- , text "new_pats" <+> ppr new_pats]) ; let spec_env = decreaseSpecCount env n_pats ; (spec_usgs, new_specs) <- mapAndUnzipM (spec_one spec_env fn arg_bndrs body) @@ -1810,7 +1830,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ; let spec_usg = combineUsages spec_usgs - unspec_rhs_needed = boring_call || isExportedId fn + unspec_rhs_needed = pats_discarded || boring_call || isExportedId fn -- If there were any boring calls among the seeds (= all_calls), then those -- calls will call the un-specialised function. So we should use the seeds @@ -1821,15 +1841,14 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs -> (spec_usg `combineUsage` rhs_usg, Nothing) _ -> (spec_usg, mb_unspec) --- ; pprTrace "specialise return }" --- (vcat [ ppr fn --- , text "boring_call:" <+> ppr boring_call --- , text "new calls:" <+> ppr (scu_calls new_usg)]) $ --- return () +-- ; pprTraceM "specialise return }" $ +-- vcat [ ppr fn +-- , text "unspec_rhs_needed:" <+> ppr unspec_rhs_needed +-- , text "new calls:" <+> ppr (scu_calls new_usg)] - ; return (new_usg, SI { si_specs = new_specs ++ specs - , si_n_specs = spec_count + n_pats - , si_mb_unspec = mb_unspec' }) } + ; return (new_usg, SI { si_specs = new_specs ++ specs + , si_n_specs = spec_count + n_pats + , si_mb_unspec = mb_unspec' }) } | otherwise -- No calls, inactive, or not a function -- Behave as if there was a single, boring call @@ -1872,7 +1891,9 @@ spec_one :: ScEnv spec_one env fn arg_bndrs body (call_pat, rule_number) | CP { cp_qvars = qvars, cp_args = pats, cp_strict_args = cbv_args } <- call_pat - = do { spec_uniq <- getUniqueM + = do { -- pprTraceM "spec_one {" (ppr fn <+> ppr pats) + + ; spec_uniq <- getUniqueM ; let env1 = extendScSubstList (extendScInScope env qvars) (arg_bndrs `zip` pats) (body_env, extra_bndrs) = extendBndrs env1 (dropList pats arg_bndrs) @@ -1898,9 +1919,6 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) -- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env) ; (spec_usg, spec_body) <- scExpr body_env body --- ; pprTrace "done spec_one }" (ppr fn $$ ppr (scu_calls spec_usg)) $ --- return () - -- And build the results ; (qvars', pats') <- generaliseDictPats qvars pats ; let spec_body_ty = exprType spec_body @@ -1944,21 +1962,22 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) fn_name qvars' pats' rule_rhs -- See Note [Transfer activation] - -- ; pprTraceM "spec_one {" (vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) - -- , text "sc_count:" <+> ppr (sc_count env) - -- , text "pats:" <+> ppr pats - -- , text "call_pat:" <+> ppr call_pat - -- , text "-->" <+> ppr spec_name - -- , text "bndrs" <+> ppr arg_bndrs - -- , text "extra_bndrs" <+> ppr extra_bndrs - -- , text "cbv_args" <+> ppr cbv_args - -- , text "spec_lam_args" <+> ppr spec_lam_args - -- , text "spec_call_args" <+> ppr spec_call_args - -- , text "rule_rhs" <+> ppr rule_rhs - -- , text "adds_void_worker_arg" <+> ppr add_void_arg - -- , text "body" <+> ppr body - -- , text "spec_rhs" <+> ppr spec_rhs - -- , text "how_bound" <+> ppr (sc_how_bound env) ]) +-- ; pprTraceM "spec_one end }" $ +-- vcat [ text "function:" <+> ppr fn <+> braces (ppr (idUnique fn)) +-- , text "pats:" <+> ppr pats +-- , text "call_pat:" <+> ppr call_pat +-- , text "-->" <+> ppr spec_name +-- , text "bndrs" <+> ppr arg_bndrs +-- , text "extra_bndrs" <+> ppr extra_bndrs +-- , text "cbv_args" <+> ppr cbv_args +-- , text "spec_lam_args" <+> ppr spec_lam_args +-- , text "spec_call_args" <+> ppr spec_call_args +-- , text "rule_rhs" <+> ppr rule_rhs +-- , text "adds_void_worker_arg" <+> ppr add_void_arg +---- , text "body" <+> ppr body +---- , text "spec_rhs" <+> ppr spec_rhs +---- , text "how_bound" <+> ppr (sc_how_bound env) ] +-- ] ; return (spec_usg, OS { os_pat = call_pat, os_rule = rule , os_id = spec_id , os_rhs = spec_rhs }) } @@ -2328,7 +2347,9 @@ instance Outputable CallPat where callsToNewPats :: ScEnv -> Id -> SpecInfo -> [ArgOcc] -> [Call] - -> UniqSM (Bool, [CallPat]) + -> UniqSM ( Bool -- At least one boring call + , Bool -- Patterns were discarded + , [CallPat] ) -- Patterns to specialise -- Result has no duplicate patterns, -- nor ones mentioned in si_specs (hence "new" patterns) -- Bool indicates that there was at least one boring pattern @@ -2360,12 +2381,11 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Discard specialisations if there are too many of them (pats_were_discarded, trimmed_pats) = trim_pats env fn spec_info small_pats --- ; pprTrace "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls --- , text "done_specs:" <+> ppr (map os_pat done_specs) --- , text "good_pats:" <+> ppr good_pats ]) $ --- return () +-- ; pprTraceM "callsToPats" (vcat [ text "calls to" <+> ppr fn <> colon <+> ppr calls +-- , text "done_specs:" <+> ppr (map os_pat done_specs) +-- , text "trimmed_pats:" <+> ppr trimmed_pats ]) - ; return (have_boring_call || pats_were_discarded, trimmed_pats) } + ; return (have_boring_call, pats_were_discarded, trimmed_pats) } -- If any of the calls does not give rise to a specialisation, either -- because it is boring, or because there are too many specialisations, -- return a flag to say so, so that we know to keep the original function. @@ -2474,29 +2494,29 @@ callToPats env bndr_occs call@(Call fn args con_env) sanitise id = updateIdTypeAndMult expandTypeSynonyms id -- See Note [Free type variables of the qvar types] - -- Bad coercion variables: see Note [SpecConstr and casts] - bad_covars :: CoVarSet + + -- Check for bad coercion variables: see Note [SpecConstr and casts] + ; let bad_covars :: CoVarSet bad_covars = mapUnionVarSet get_bad_covars pats get_bad_covars :: CoreArg -> CoVarSet get_bad_covars (Type ty) = filterVarSet bad_covar (tyCoVarsOfType ty) get_bad_covars _ = emptyVarSet bad_covar v = isId v && not (is_in_scope v) - ; -- pprTrace "callToPats" (ppr args $$ ppr bndr_occs) $ - warnPprTrace (not (isEmptyVarSet bad_covars)) + ; warnPprTrace (not (isEmptyVarSet bad_covars)) "SpecConstr: bad covars" (ppr bad_covars $$ ppr call) $ + if interesting && isEmptyVarSet bad_covars - then do - -- pprTraceM "callToPatsOut" ( - -- text "fn:" <+> ppr fn $$ - -- text "args:" <+> ppr args $$ - -- text "in_scope:" <+> ppr in_scope $$ - -- -- text "in_scope:" <+> ppr in_scope $$ - -- text "pat_fvs:" <+> ppr pat_fvs - -- ) - -- ppr (CP { cp_qvars = qvars', cp_args = pats })) >> - return (Just (CP { cp_qvars = qvars', cp_args = pats, cp_strict_args = concat cbv_ids })) + then do { let cp_res = CP { cp_qvars = qvars', cp_args = pats + , cp_strict_args = concat cbv_ids } +-- ; pprTraceM "callToPatsOut" $ +-- vcat [ text "fn:" <+> ppr fn +-- , text "args:" <+> ppr args +-- , text "bndr_occs:" <+> ppr bndr_occs +-- , text "pat_fvs:" <+> ppr pat_fvs +-- , text "cp_res:" <+> ppr cp_res ] + ; return (Just cp_res) } else return Nothing } -- argToPat takes an actual argument, and returns an abstracted ===================================== compiler/GHC/Driver/Config/Core/Opt/Simplify.hs ===================================== @@ -2,7 +2,6 @@ module GHC.Driver.Config.Core.Opt.Simplify ( initSimplifyExprOpts , initSimplifyOpts , initSimplMode - , initGentleSimplMode ) where import GHC.Prelude @@ -27,12 +26,13 @@ import GHC.Types.Var ( Var ) initSimplifyExprOpts :: DynFlags -> InteractiveContext -> SimplifyExprOpts initSimplifyExprOpts dflags ic = SimplifyExprOpts { se_fam_inst = snd $ ic_instances ic - , se_mode = (initSimplMode dflags InitialPhase "GHCi") - { sm_inline = False - -- Do not do any inlining, in case we expose some - -- unboxed tuple stuff that confuses the bytecode + + , se_mode = (initSimplMode dflags) { sm_names = ["GHCi"] + , sm_inline = False } + -- sm_inline: do not do any inlining, in case we expose + -- some unboxed tuple stuff that confuses the bytecode -- interpreter - } + , se_top_env_cfg = TopEnvConfig { te_history_size = historySize dflags , te_tick_factor = simplTickFactor dflags @@ -57,31 +57,25 @@ initSimplifyOpts dflags extra_vars iterations mode rule_base = let } in opts -initSimplMode :: DynFlags -> CompilerPhase -> String -> SimplMode -initSimplMode dflags phase name = SimplMode - { sm_names = [name] - , sm_phase = phase - , sm_rules = gopt Opt_EnableRewriteRules dflags - , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags - , sm_cast_swizzle = True - , sm_inline = True - , sm_uf_opts = unfoldingOpts dflags - , sm_case_case = True - , sm_pre_inline = gopt Opt_SimplPreInlining dflags - , sm_float_enable = floatEnable dflags +initSimplMode :: DynFlags -> SimplMode +initSimplMode dflags = SimplMode + { sm_names = ["Unknown simplifier run"] -- Always overriden + , sm_phase = InitialPhase + , sm_rules = gopt Opt_EnableRewriteRules dflags + , sm_eta_expand = gopt Opt_DoLambdaEtaExpansion dflags + , sm_pre_inline = gopt Opt_SimplPreInlining dflags , sm_do_eta_reduction = gopt Opt_DoEtaReduction dflags - , sm_arity_opts = initArityOpts dflags - , sm_rule_opts = initRuleOpts dflags - , sm_case_folding = gopt Opt_CaseFolding dflags - , sm_case_merge = gopt Opt_CaseMerge dflags - , sm_co_opt_opts = initOptCoercionOpts dflags - } - -initGentleSimplMode :: DynFlags -> SimplMode -initGentleSimplMode dflags = (initSimplMode dflags InitialPhase "Gentle") - { -- Don't do case-of-case transformations. - -- This makes full laziness work better - sm_case_case = False + , sm_uf_opts = unfoldingOpts dflags + , sm_float_enable = floatEnable dflags + , sm_arity_opts = initArityOpts dflags + , sm_rule_opts = initRuleOpts dflags + , sm_case_folding = gopt Opt_CaseFolding dflags + , sm_case_merge = gopt Opt_CaseMerge dflags + , sm_co_opt_opts = initOptCoercionOpts dflags + , sm_cast_swizzle = True + , sm_inline = True + , sm_case_case = True + , sm_keep_exits = False } floatEnable :: DynFlags -> FloatEnable ===================================== testsuite/tests/simplCore/should_compile/T21148.hs ===================================== @@ -0,0 +1,12 @@ +module T211148 where + +-- The point of this test is that f should get a (nested) +-- CPR property, with a worker of type +-- $wf :: Int# -> State# RealWorld -> (# State# RealWorld, Int# #) + +{-# NOINLINE f #-} +-- The NOINLINE makes GHC do a worker/wrapper split +-- even though f is small +f :: Int -> IO Int +f x = return $! sum [0..x] + ===================================== testsuite/tests/simplCore/should_compile/T21148.stderr ===================================== @@ -0,0 +1,126 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 73, types: 80, coercions: 6, joins: 2/2} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T211148.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule3 = GHC.Types.TrNameS T211148.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T211148.$trModule2 = "T211148"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule1 = GHC.Types.TrNameS T211148.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T211148.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T211148.$trModule + = GHC.Types.Module T211148.$trModule3 T211148.$trModule1 + +-- RHS size: {terms: 41, types: 35, coercions: 0, joins: 2/2} +T211148.$wf [InlPrag=NOINLINE] + :: GHC.Prim.Int# + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) +[GblId, Arity=2, Str=, Unf=OtherCon []] +T211148.$wf + = \ (ww_s179 :: GHC.Prim.Int#) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case GHC.Prim.># 0# ww_s179 of { + __DEFAULT -> + join { + exit_X0 [Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit_X0 (x_s16Z [OS=OneShot] :: GHC.Prim.Int#) + (ww1_s172 [OS=OneShot] :: GHC.Prim.Int#) + = (# eta_s17b, GHC.Prim.+# ww1_s172 x_s16Z #) } in + joinrec { + $wgo3_s175 [InlPrag=[2], Occ=LoopBreaker, Dmd=SC(S,C(1,!P(L,L)))] + :: GHC.Prim.Int# + -> GHC.Prim.Int# + -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=, Unf=OtherCon []] + $wgo3_s175 (x_s16Z :: GHC.Prim.Int#) (ww1_s172 :: GHC.Prim.Int#) + = case GHC.Prim.==# x_s16Z ww_s179 of { + __DEFAULT -> + jump $wgo3_s175 + (GHC.Prim.+# x_s16Z 1#) (GHC.Prim.+# ww1_s172 x_s16Z); + 1# -> jump exit_X0 x_s16Z ww1_s172 + }; } in + jump $wgo3_s175 0# 0#; + 1# -> (# eta_s17b, 0# #) + } + +-- RHS size: {terms: 14, types: 19, coercions: 0, joins: 0/0} +T211148.f1 [InlPrag=NOINLINE[final]] + :: Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (x_s177 [Occ=Once1!] :: Int) + (eta_s17b [Occ=Once1, OS=OneShot] + :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 [Occ=Once1] -> + case T211148.$wf ww_s179 eta_s17b of + { (# ww1_s17e [Occ=Once1], ww2_s17j [Occ=Once1] #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + }}] +T211148.f1 + = \ (x_s177 :: Int) + (eta_s17b [OS=OneShot] :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case x_s177 of { GHC.Types.I# ww_s179 -> + case T211148.$wf ww_s179 eta_s17b of { (# ww1_s17e, ww2_s17j #) -> + (# ww1_s17e, GHC.Types.I# ww2_s17j #) + } + } + +-- RHS size: {terms: 1, types: 0, coercions: 6, joins: 0/0} +f [InlPrag=NOINLINE[final]] :: Int -> IO Int +[GblId, + Arity=2, + Str=<1!P(L)>, + Cpr=1(, 1), + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] +f = T211148.f1 + `cast` (_R %<'Many>_N ->_R Sym (GHC.Types.N:IO[0] _R) + :: (Int + -> GHC.Prim.State# GHC.Prim.RealWorld + -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) + ~R# (Int -> IO Int)) + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -429,6 +429,7 @@ test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21148', [grep_errmsg(r'Cpr=') ], compile, ['-O -ddump-simpl']) # One module, T21851.hs, has OPTIONS_GHC -ddump-simpl test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/stranal/should_compile/T21128.hs ===================================== @@ -2,6 +2,10 @@ module T21128 where import T21128a +{- This test originally had some unnecessary reboxing of y +in the hot path of $wtheresCrud. That reboxing should +not happen. -} + theresCrud :: Int -> Int -> Int theresCrud x y = go x where @@ -9,3 +13,4 @@ theresCrud x y = go x go 1 = index x y 1 go n = go (n-1) {-# NOINLINE theresCrud #-} + ===================================== testsuite/tests/stranal/should_compile/T21128.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 137, types: 92, coercions: 4, joins: 0/0} + = {terms: 125, types: 68, coercions: 4, joins: 0/0} lvl = "error"# @@ -29,17 +29,11 @@ lvl9 = SrcLoc lvl2 lvl3 lvl5 lvl6 lvl7 lvl6 lvl8 lvl10 = PushCallStack lvl1 lvl9 EmptyCallStack -$windexError - = \ @a @b ww eta eta1 eta2 -> - error - (lvl10 `cast` :: CallStack ~R# (?callStack::CallStack)) - (++ (ww eta) (++ (ww eta1) (ww eta2))) - indexError = \ @a @b $dShow eta eta1 eta2 -> - case $dShow of { C:Show ww ww1 ww2 -> - $windexError ww1 eta eta1 eta2 - } + error + (lvl10 `cast` :: ...) + (++ (show $dShow eta) (++ (show $dShow eta1) (show $dShow eta2))) $trModule3 = TrNameS $trModule4 @@ -48,8 +42,7 @@ $trModule1 = TrNameS $trModule2 $trModule = Module $trModule3 $trModule1 $wlvl - = \ ww ww1 ww2 -> - $windexError $fShowInt_$cshow (I# ww2) (I# ww1) (I# ww) + = \ ww ww1 ww2 -> indexError $fShowInt (I# ww2) (I# ww1) (I# ww) index = \ l u i -> @@ -73,7 +66,7 @@ index ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 108, types: 47, coercions: 0, joins: 3/4} + = {terms: 108, types: 46, coercions: 0, joins: 3/3} $trModule4 = "main"# @@ -89,35 +82,34 @@ i = I# 1# l = I# 0# -lvl = \ y -> $windexError $fShowInt_$cshow l y l +lvl = \ x ww -> indexError $fShowInt x (I# ww) i -lvl1 = \ ww y -> $windexError $fShowInt_$cshow (I# ww) y i +lvl1 = \ ww -> indexError $fShowInt l (I# ww) l $wtheresCrud = \ ww ww1 -> - let { y = I# ww1 } in join { - lvl2 + exit + = case <# 0# ww1 of { + __DEFAULT -> case lvl1 ww1 of wild { }; + 1# -> 0# + } } in + join { + exit1 = case <=# ww 1# of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> case <# 1# ww1 of { - __DEFAULT -> case lvl1 ww y of wild { }; + __DEFAULT -> case lvl (I# ww) ww1 of wild { }; 1# -> -# 1# ww } } } in - join { - lvl3 - = case <# 0# ww1 of { - __DEFAULT -> case lvl y of wild { }; - 1# -> 0# - } } in joinrec { $wgo ww2 = case ww2 of wild { __DEFAULT -> jump $wgo (-# wild 1#); - 0# -> jump lvl3; - 1# -> jump lvl2 + 0# -> jump exit; + 1# -> jump exit1 }; } in jump $wgo ww View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9789ea8e9f35d5c0674e10730c3435c4d3293f2b...284cf387537110ce9139bf6ed0841c8f4f41db2a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9789ea8e9f35d5c0674e10730c3435c4d3293f2b...284cf387537110ce9139bf6ed0841c8f4f41db2a You're receiving 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 Oct 11 16:50:15 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 12:50:15 -0400 Subject: [Git][ghc/ghc][master] CmmToC: emit explicit tail calls when the C compiler supports it Message-ID: <63459ec79926_1eea6a6375ad881303128@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 3 changed files: - configure.ac - + m4/fp_musttail.m4 - rts/include/Stg.h Changes: ===================================== configure.ac ===================================== @@ -996,6 +996,8 @@ fi FP_VISIBILITY_HIDDEN +FP_MUSTTAIL + dnl ** check for librt AC_CHECK_LIB([rt], [clock_gettime]) AC_CHECK_LIB([rt], [clock_gettime], [AC_SUBST([CabalHaveLibrt], [True])], [AC_SUBST([CabalHaveLibrt], [False])]) ===================================== m4/fp_musttail.m4 ===================================== @@ -0,0 +1,16 @@ +# FP_MUSTTAIL +# ---------------------------------- +# Is the musttail attribute supported? +AC_DEFUN([FP_MUSTTAIL], +[ + AC_MSG_CHECKING([whether __attribute__((musttail)) is supported]) + echo 'extern int foo(void); int bar(void) { __attribute__((musttail)) return foo(); }' > conftest.c + if $CC -c conftest.c -o conftest.o + then + AC_MSG_RESULT([yes]) + AC_DEFINE(HAS_MUSTTAIL, 1, [Has musttail]) + else + AC_MSG_RESULT([no]) + fi + rm -f conftest.c conftest.o +]) ===================================== rts/include/Stg.h ===================================== @@ -325,7 +325,11 @@ external prototype return neither of these types to workaround #11395. Tail calls -------------------------------------------------------------------------- */ -#define JMP_(cont) return((StgFunPtr)(cont)) +#if defined(HAS_MUSTTAIL) +#define JMP_(cont) { StgFunPtr (*_f)(void) = (StgFunPtr (*)(void))(cont); __attribute__((musttail)) return _f(); } +#else +#define JMP_(cont) return (StgFunPtr)(cont) +#endif /* ----------------------------------------------------------------------------- Other Stg stuff... @@ -591,4 +595,3 @@ typedef union { c; \ }) #endif - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66af1399963a1872e520d1dbd1c94fd43e65082d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66af1399963a1872e520d1dbd1c94fd43e65082d You're receiving 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 Oct 11 16:51:11 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 12:51:11 -0400 Subject: [Git][ghc/ghc][master] Don't include BufPos in interface files Message-ID: <63459eff9cb78_1eea6a529f4f8c13102fa@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - 3 changed files: - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -781,5 +781,5 @@ toHieName name | isKnownKeyName name = KnownKeyName (nameUnique name) | isExternalName name = ExternalName (nameModule name) (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) + (removeBufSpan $ nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (removeBufSpan $ nameSrcSpan name) ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -68,6 +68,7 @@ module GHC.Types.SrcLoc ( getBufPos, BufSpan(..), getBufSpan, + removeBufSpan, -- * Located Located, @@ -392,6 +393,10 @@ data UnhelpfulSpanReason | UnhelpfulOther !FastString deriving (Eq, Show) +removeBufSpan :: SrcSpan -> SrcSpan +removeBufSpan (RealSrcSpan s _) = RealSrcSpan s Strict.Nothing +removeBufSpan s = s + {- Note [Why Maybe BufPos] ~~~~~~~~~~~~~~~~~~~~~~~~~~ In SrcLoc we store (Maybe BufPos); in SrcSpan we store (Maybe BufSpan). ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -1312,19 +1312,6 @@ instance Binary RealSrcSpan where return (mkRealSrcSpan (mkRealSrcLoc f sl sc) (mkRealSrcLoc f el ec)) -instance Binary BufPos where - put_ bh (BufPos i) = put_ bh i - get bh = BufPos <$> get bh - -instance Binary BufSpan where - put_ bh (BufSpan start end) = do - put_ bh start - put_ bh end - get bh = do - start <- get bh - end <- get bh - return (BufSpan start end) - instance Binary UnhelpfulSpanReason where put_ bh r = case r of UnhelpfulNoLocationInfo -> putByte bh 0 @@ -1343,10 +1330,11 @@ instance Binary UnhelpfulSpanReason where _ -> UnhelpfulOther <$> get bh instance Binary SrcSpan where - put_ bh (RealSrcSpan ss sb) = do + put_ bh (RealSrcSpan ss _sb) = do putByte bh 0 + -- BufSpan doesn't ever get serialised because the positions depend + -- on build location. put_ bh ss - put_ bh sb put_ bh (UnhelpfulSpan s) = do putByte bh 1 @@ -1356,8 +1344,7 @@ instance Binary SrcSpan where h <- getByte bh case h of 0 -> do ss <- get bh - sb <- get bh - return (RealSrcSpan ss sb) + return (RealSrcSpan ss Strict.Nothing) _ -> do s <- get bh return (UnhelpfulSpan s) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f0decd5063a853fc8f38a8944b2c91995cd5e48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f0decd5063a853fc8f38a8944b2c91995cd5e48 You're receiving 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 Oct 11 16:51:40 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 12:51:40 -0400 Subject: [Git][ghc/ghc][master] CLabel: fix isInfoTableLabel Message-ID: <63459f1cd0afd_1eea6a514c8131386f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 3 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -108,6 +108,7 @@ module GHC.Cmm.CLabel ( isLocalCLabel, mayRedirectTo, isInfoTableLabel, + isCmmInfoTableLabel, isConInfoTableLabel, isIdLabel, isTickyLabel, @@ -794,8 +795,14 @@ isInfoTableLabel (IdLabel _ _ InfoTable) = True isInfoTableLabel (IdLabel _ _ LocalInfoTable) = True isInfoTableLabel (IdLabel _ _ ConInfoTable {}) = True isInfoTableLabel (IdLabel _ _ BlockInfoTable) = True +isInfoTableLabel (CmmLabel _ _ _ CmmInfo) = True isInfoTableLabel _ = False +-- | Whether label points to an info table defined in Cmm +isCmmInfoTableLabel :: CLabel -> Bool +isCmmInfoTableLabel (CmmLabel _ _ _ CmmInfo) = True +isCmmInfoTableLabel _ = False + -- | Whether label is points to constructor info table isConInfoTableLabel :: CLabel -> Bool isConInfoTableLabel (IdLabel _ _ ConInfoTable {}) = True ===================================== compiler/GHC/CmmToAsm/AArch64/Ppr.hs ===================================== @@ -195,7 +195,7 @@ pprLabelType' platform lbl = text "@object" where functionOkInfoTable = platformTablesNextToCode platform && - isInfoTableLabel lbl && not (isConInfoTableLabel lbl) + isInfoTableLabel lbl && not (isCmmInfoTableLabel lbl) && not (isConInfoTableLabel lbl) -- this is called pprTypeAndSizeDecl in PPC.Ppr pprTypeDecl :: Platform -> CLabel -> SDoc ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -254,7 +254,7 @@ pprLabelType' platform lbl = but mess up with the relocation. https://phabricator.haskell.org/D4730 -} functionOkInfoTable = platformTablesNextToCode platform && - isInfoTableLabel lbl && not (isConInfoTableLabel lbl) + isInfoTableLabel lbl && not (isCmmInfoTableLabel lbl) && not (isConInfoTableLabel lbl) pprTypeDecl :: Platform -> CLabel -> SDoc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dce9f320ce7275fa97f49abef604abbc3b0f9a9c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dce9f320ce7275fa97f49abef604abbc3b0f9a9c You're receiving 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 Oct 11 18:07:12 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Oct 2022 14:07:12 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/drop-inlines Message-ID: <6345b0d010d2c_1eea6a5fada5c0133954c@gitlab.mail> Ben Gamari pushed new branch wip/drop-inlines at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/drop-inlines You're receiving 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 Oct 11 18:13:09 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Oct 2022 14:13:09 -0400 Subject: [Git][ghc/ghc][wip/drop-inlines] rts: Don't hint inlining of appendToRunQueue Message-ID: <6345b23517d03_1eea6a514c813454a1@gitlab.mail> Ben Gamari pushed to branch wip/drop-inlines at Glasgow Haskell Compiler / GHC Commits: 3bc1e289 by Ben Gamari at 2022-10-11T14:13:02-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 2 changed files: - rts/Schedule.c - rts/Schedule.h Changes: ===================================== rts/Schedule.c ===================================== @@ -2915,6 +2915,61 @@ deleteThread_(StgTSO *tso) } #endif +/* + * Run queue manipulation + */ + +void +appendToRunQueue (Capability *cap, StgTSO *tso) +{ + ASSERT(tso->_link == END_TSO_QUEUE); + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_hd = tso; + tso->block_info.prev = END_TSO_QUEUE; + } else { + setTSOLink(cap, cap->run_queue_tl, tso); + setTSOPrev(cap, tso, cap->run_queue_tl); + } + cap->run_queue_tl = tso; + cap->n_run_queue++; +} + +void +pushOnRunQueue (Capability *cap, StgTSO *tso) +{ + setTSOLink(cap, tso, cap->run_queue_hd); + tso->block_info.prev = END_TSO_QUEUE; + if (cap->run_queue_hd != END_TSO_QUEUE) { + setTSOPrev(cap, cap->run_queue_hd, tso); + } + cap->run_queue_hd = tso; + if (cap->run_queue_tl == END_TSO_QUEUE) { + cap->run_queue_tl = tso; + } + cap->n_run_queue++; +} + +StgTSO *popRunQueue (Capability *cap) +{ + ASSERT(cap->n_run_queue > 0); + StgTSO *t = cap->run_queue_hd; + ASSERT(t != END_TSO_QUEUE); + cap->run_queue_hd = t->_link; + + StgTSO *link = RELAXED_LOAD(&t->_link); + if (link != END_TSO_QUEUE) { + link->block_info.prev = END_TSO_QUEUE; + } + RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd + + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_tl = END_TSO_QUEUE; + } + cap->n_run_queue--; + return t; +} + + /* ----------------------------------------------------------------------------- raiseExceptionHelper ===================================== rts/Schedule.h ===================================== @@ -136,67 +136,16 @@ void resurrectThreads (StgTSO *); * NOTE: tso->link should be END_TSO_QUEUE before calling this macro. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso) -{ - ASSERT(tso->_link == END_TSO_QUEUE); - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_hd = tso; - tso->block_info.prev = END_TSO_QUEUE; - } else { - setTSOLink(cap, cap->run_queue_tl, tso); - setTSOPrev(cap, tso, cap->run_queue_tl); - } - cap->run_queue_tl = tso; - cap->n_run_queue++; -} +void appendToRunQueue (Capability *cap, StgTSO *tso); /* Push a thread on the beginning of the run queue. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso) -{ - setTSOLink(cap, tso, cap->run_queue_hd); - tso->block_info.prev = END_TSO_QUEUE; - if (cap->run_queue_hd != END_TSO_QUEUE) { - setTSOPrev(cap, cap->run_queue_hd, tso); - } - cap->run_queue_hd = tso; - if (cap->run_queue_tl == END_TSO_QUEUE) { - cap->run_queue_tl = tso; - } - cap->n_run_queue++; -} +void pushOnRunQueue (Capability *cap, StgTSO *tso); /* Pop the first thread off the runnable queue. */ -INLINE_HEADER StgTSO * -popRunQueue (Capability *cap) -{ - ASSERT(cap->n_run_queue > 0); - StgTSO *t = cap->run_queue_hd; - ASSERT(t != END_TSO_QUEUE); - cap->run_queue_hd = t->_link; - - StgTSO *link = RELAXED_LOAD(&t->_link); - if (link != END_TSO_QUEUE) { - link->block_info.prev = END_TSO_QUEUE; - } - RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd - - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_tl = END_TSO_QUEUE; - } - cap->n_run_queue--; - return t; -} +StgTSO *popRunQueue (Capability *cap); INLINE_HEADER StgTSO * peekRunQueue (Capability *cap) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bc1e289bb15f272bdcdc131b06a90dc0dde83cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bc1e289bb15f272bdcdc131b06a90dc0dde83cf You're receiving 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 Oct 11 18:16:02 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Oct 2022 14:16:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T21936 Message-ID: <6345b2e2e6f47_1eea6a6375ad88134612d@gitlab.mail> Ben Gamari pushed new branch wip/T21936 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T21936 You're receiving 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 Oct 11 18:16:28 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Oct 2022 14:16:28 -0400 Subject: [Git][ghc/ghc][wip/T12971] 83 commits: hadrian: Use a stamp file to record when a package is built in a certain way Message-ID: <6345b2fcc4f9f_1eea6a6375ad88134822a@gitlab.mail> Ben Gamari pushed to branch wip/T12971 at Glasgow Haskell Compiler / GHC Commits: 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - ca92ad53 by Ben Gamari at 2022-10-11T14:16:21-04:00 Fix manifest filename when writing Windows .rc files As noted in #12971, we previously used `show`,l which resulted in inappropriate escaping of non-ASCII characters. - - - - - 123be331 by Ben Gamari at 2022-10-11T14:16:22-04:00 Write response files in UTF-8 on Windows This reverts the workaround introduced in f63c8ef33ec9666688163abe4ccf2d6c0428a7e7, which taught our response file logic to write response files with the `latin1` encoding to workaround `gcc`'s lacking Unicode support. This is now no longer necessary (and in fact actively unhelpful) since we rather use Clang. - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Reg.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/CFG/Dominators.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9842dba71cc80aa26c3b306728d73da2c2e49715...123be3318fd6b7a99ac7d7d03c47410ac4238e6b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9842dba71cc80aa26c3b306728d73da2c2e49715...123be3318fd6b7a99ac7d7d03c47410ac4238e6b You're receiving 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 Oct 11 19:31:17 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Tue, 11 Oct 2022 15:31:17 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: Remove shims and refactor Cpp Message-ID: <6345c485eb643_1eea6a5141413779be@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 5883d641 by Sylvain Henry at 2022-10-11T21:34:32+02:00 Remove shims and refactor Cpp I've removed the use of js/rts.h and js/constants.h again. We generate their contents at cpp time. Instead of wiring z-encoded strings into these macros, we should derive them from wired-in Names so that they stay correct in the future. Using wired-in Names as single source of truth. - - - - - 0015d2d9 by Sylvain Henry at 2022-10-11T21:34:32+02:00 Support RTS globals (used by GHC) and EISDIR Did this while trying to fix CallArity1 (still failing) - - - - - 26 changed files: - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - − compiler/GHC/JS/Parser/Header.hs - compiler/GHC/StgToJS/Linker/Linker.hs - − compiler/GHC/StgToJS/Linker/Shims.hs - compiler/GHC/StgToJS/Linker/Utils.hs - + compiler/GHC/SysTools/Cpp.hs - compiler/ghc.cabal.in - libraries/base/jsbits/base.js - libraries/base/jsbits/errno.js - − rts/include/js/constants.h - − rts/include/js/rts.h - rts/js/arith.js - rts/js/compact.js - rts/js/environment.js - + rts/js/globals.js - rts/js/hscore.js - rts/js/mem.js - rts/js/object.js - rts/js/rts.js - rts/js/staticpointer.js - rts/js/string.js - rts/js/thread.js - rts/js/weak.js - rts/rts.cabal.in Changes: ===================================== compiler/GHC/Driver/Backend.hs ===================================== @@ -960,7 +960,7 @@ Such a function may be applied in one of two ways: applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String] @ - Function `applyCDefs` is defined in module "GHC.Driver.Pipeline.Execute". + Function `applyCDefs` is defined in module "GHC.SysTools.Cpp". I don't love this solution, but defunctionalization is a standard thing, and it makes the meanings of the enumeration values clear. ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -72,6 +72,7 @@ import GHC.Driver.Hooks import GHC.Platform.Ways import GHC.SysTools +import GHC.SysTools.Cpp import GHC.Utils.TmpFs import GHC.Linker.ExtraObj ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Utils.Error import Data.Maybe import GHC.CmmToLlvm.Mangler import GHC.SysTools +import GHC.SysTools.Cpp import GHC.Utils.Panic.Plain import System.Directory import System.FilePath @@ -61,7 +62,6 @@ import GHC.Iface.Make import Data.Time import GHC.Driver.Config.Parser import GHC.Parser.Header -import qualified GHC.JS.Parser.Header as JSHeader import GHC.Data.StringBuffer import GHC.Types.SourceError import GHC.Unit.Finder @@ -69,21 +69,19 @@ import GHC.Runtime.Loader import Data.IORef import GHC.Types.Name.Env import GHC.Platform.Ways -import GHC.Platform.ArchOS import GHC.Driver.LlvmConfigCache (readLlvmConfigCache) -import GHC.CmmToLlvm.Config (llvmVersionList, LlvmTarget (..), LlvmConfig (..)) +import GHC.CmmToLlvm.Config (LlvmTarget (..), LlvmConfig (..)) import {-# SOURCE #-} GHC.Driver.Pipeline (compileForeign, compileEmptyStub) import GHC.Settings import System.IO import GHC.Linker.ExtraObj import GHC.Linker.Dynamic -import Data.Version import GHC.Utils.Panic import GHC.Unit.Module.Env import GHC.Driver.Env.KnotVars import GHC.Driver.Config.Finder import GHC.Rename.Names -import GHC.StgToJS.Object (isJsObjectFile) +import GHC.StgToJS.Linker.Linker (embedJsFile) import Language.Haskell.Syntax.Module.Name @@ -351,56 +349,14 @@ runAsPhase with_cpp pipe_env hsc_env location input_fn = do -- | Embed .js files into .o files runJsPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath runJsPhase pipe_env hsc_env input_fn = do - let dflags = hsc_dflags hsc_env - let logger = hsc_logger hsc_env - let tmpfs = hsc_tmpfs hsc_env - let unit_env = hsc_unit_env hsc_env - - output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env Nothing - - -- if the input filename is the same as the output, then we've probably - -- generated the object ourselves, we leave the file alone - when (input_fn /= output_fn) $ do - - -- the header lets the linker recognize processed JavaScript files - -- But don't add JavaScript header to object files! - - is_js_obj <- if True - then pure False - else isJsObjectFile input_fn - -- FIXME (Sylvain 2022-09): this call makes the - -- testsuite go into a loop, I don't know why yet! - -- Disabling it for now. - - if is_js_obj - then copyWithHeader "" input_fn output_fn - else do - -- header appended to JS files stored as .o to recognize them. - let header = "//JavaScript\n" - jsFileNeedsCpp input_fn >>= \case - False -> copyWithHeader header input_fn output_fn - True -> do - -- run CPP on the input JS file - tmp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" - doCpp logger - tmpfs - dflags - unit_env - (CppOpts - { cppUseCc = True - , cppLinePragmas = False - }) - [] - input_fn - tmp_fn - copyWithHeader header tmp_fn output_fn - - return output_fn + let dflags = hsc_dflags hsc_env + let logger = hsc_logger hsc_env + let tmpfs = hsc_tmpfs hsc_env + let unit_env = hsc_unit_env hsc_env -jsFileNeedsCpp :: FilePath -> IO Bool -jsFileNeedsCpp fn = do - opts <- JSHeader.getOptionsFromJsFile fn - pure (JSHeader.CPP `elem` opts) + output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env Nothing + embedJsFile logger dflags tmpfs unit_env input_fn output_fn + return output_fn applyAssemblerInfoGetter @@ -1030,153 +986,6 @@ llvmOptions llvm_config dflags = _ -> "" --- Note [Filepaths and Multiple Home Units] -offsetIncludePaths :: DynFlags -> IncludeSpecs -> IncludeSpecs -offsetIncludePaths dflags (IncludeSpecs incs quotes impl) = - let go = map (augmentByWorkingDirectory dflags) - in IncludeSpecs (go incs) (go quotes) (go impl) --- ----------------------------------------------------------------------------- --- Running CPP - -data CppOpts = CppOpts - { cppUseCc :: !Bool -- ^ Use "cc -E" as preprocessor, otherwise use "cpp" - , cppLinePragmas :: !Bool -- ^ Enable generation of LINE pragmas - } - --- | Run CPP --- --- UnitEnv is needed to compute MIN_VERSION macros -doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> [Option] -> FilePath -> FilePath -> IO () -doCpp logger tmpfs dflags unit_env opts extra_opts input_fn output_fn = do - let hscpp_opts = picPOpts dflags - let cmdline_include_paths = offsetIncludePaths dflags (includePaths dflags) - let unit_state = ue_units unit_env - pkg_include_dirs <- mayThrowUnitErr - (collectIncludeDirs <$> preloadUnitsInfo unit_env) - -- MP: This is not quite right, the headers which are supposed to be installed in - -- the package might not be the same as the provided include paths, but it's a close - -- enough approximation for things to work. A proper solution would be to have to declare which paths should - -- be propagated to dependent packages. - let home_pkg_deps = - [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- ue_transitiveHomeDeps (ue_currentUnit unit_env) unit_env] - dep_pkg_extra_inputs = [offsetIncludePaths fs (includePaths fs) | fs <- home_pkg_deps] - - let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) [] - (includePathsGlobal cmdline_include_paths ++ pkg_include_dirs - ++ concatMap includePathsGlobal dep_pkg_extra_inputs) - let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) [] - (includePathsQuote cmdline_include_paths ++ - includePathsQuoteImplicit cmdline_include_paths) - let include_paths = include_paths_quote ++ include_paths_global - - let verbFlags = getVerbFlags dflags - - let cpp_prog args - | cppUseCc opts = GHC.SysTools.runCc Nothing logger tmpfs dflags - (GHC.SysTools.Option "-E" : args) - | otherwise = GHC.SysTools.runCpp logger dflags args - - let platform = targetPlatform dflags - targetArch = stringEncodeArch $ platformArch platform - targetOS = stringEncodeOS $ platformOS platform - isWindows = platformOS platform == OSMinGW32 - let target_defs = - [ "-D" ++ HOST_OS ++ "_BUILD_OS", - "-D" ++ HOST_ARCH ++ "_BUILD_ARCH", - "-D" ++ targetOS ++ "_HOST_OS", - "-D" ++ targetArch ++ "_HOST_ARCH" ] - -- remember, in code we *compile*, the HOST is the same our TARGET, - -- and BUILD is the same as our HOST. - - let io_manager_defs = - [ "-D__IO_MANAGER_WINIO__=1" | isWindows ] ++ - [ "-D__IO_MANAGER_MIO__=1" ] - - let sse_defs = - [ "-D__SSE__" | isSseEnabled platform ] ++ - [ "-D__SSE2__" | isSse2Enabled platform ] ++ - [ "-D__SSE4_2__" | isSse4_2Enabled dflags ] - - let avx_defs = - [ "-D__AVX__" | isAvxEnabled dflags ] ++ - [ "-D__AVX2__" | isAvx2Enabled dflags ] ++ - [ "-D__AVX512CD__" | isAvx512cdEnabled dflags ] ++ - [ "-D__AVX512ER__" | isAvx512erEnabled dflags ] ++ - [ "-D__AVX512F__" | isAvx512fEnabled dflags ] ++ - [ "-D__AVX512PF__" | isAvx512pfEnabled dflags ] - - backend_defs <- applyCDefs (backendCDefs $ backend dflags) logger dflags - - let th_defs = [ "-D__GLASGOW_HASKELL_TH__" ] - -- Default CPP defines in Haskell source - ghcVersionH <- getGhcVersionPathName dflags unit_env - let hsSourceCppOpts = [ "-include", ghcVersionH ] - - -- MIN_VERSION macros - let uids = explicitUnits unit_state - pkgs = mapMaybe (lookupUnit unit_state . fst) uids - mb_macro_include <- - if not (null pkgs) && gopt Opt_VersionMacros dflags - then do macro_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "h" - writeFile macro_stub (generatePackageVersionMacros pkgs) - -- Include version macros for every *exposed* package. - -- Without -hide-all-packages and with a package database - -- size of 1000 packages, it takes cpp an estimated 2 - -- milliseconds to process this file. See #10970 - -- comment 8. - return [GHC.SysTools.FileOption "-include" macro_stub] - else return [] - - let line_pragmas - | cppLinePragmas opts = [] -- on by default - | otherwise = [GHC.SysTools.Option "-P"] -- disable LINE markers - - cpp_prog ( map GHC.SysTools.Option verbFlags - ++ map GHC.SysTools.Option include_paths - ++ map GHC.SysTools.Option hsSourceCppOpts - ++ map GHC.SysTools.Option target_defs - ++ map GHC.SysTools.Option backend_defs - ++ map GHC.SysTools.Option th_defs - ++ map GHC.SysTools.Option hscpp_opts - ++ map GHC.SysTools.Option sse_defs - ++ map GHC.SysTools.Option avx_defs - ++ map GHC.SysTools.Option io_manager_defs - ++ mb_macro_include - ++ extra_opts - ++ line_pragmas - -- Set the language mode to assembler-with-cpp when preprocessing. This - -- alleviates some of the C99 macro rules relating to whitespace and the hash - -- operator, which we tend to abuse. Clang in particular is not very happy - -- about this. - ++ [ GHC.SysTools.Option "-x" - , GHC.SysTools.Option "assembler-with-cpp" - , GHC.SysTools.Option input_fn - -- We hackily use Option instead of FileOption here, so that the file - -- name is not back-slashed on Windows. cpp is capable of - -- dealing with / in filenames, so it works fine. Furthermore - -- if we put in backslashes, cpp outputs #line directives - -- with *double* backslashes. And that in turn means that - -- our error messages get double backslashes in them. - -- In due course we should arrange that the lexer deals - -- with these \\ escapes properly. - , GHC.SysTools.Option "-o" - , GHC.SysTools.FileOption "" output_fn - ]) - -applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String] -applyCDefs NoCDefs _ _ = return [] -applyCDefs LlvmCDefs logger dflags = do - llvmVer <- figureLlvmVersion logger dflags - return $ case fmap llvmVersionList llvmVer of - Just [m] -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,0) ] - Just (m:n:_) -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,n) ] - _ -> [] - where - format (major, minor) - | minor >= 100 = error "backendCDefs: Unsupported minor version" - | otherwise = show (100 * major + minor :: Int) -- Contract is Int - - -- | What phase to run after one of the backend code generators has run hscPostBackendPhase :: HscSource -> Backend -> Phase hscPostBackendPhase HsBootFile _ = StopLn @@ -1327,36 +1136,6 @@ linkDynLibCheck logger tmpfs dflags unit_env o_files dep_units = do --- --------------------------------------------------------------------------- --- Macros (cribbed from Cabal) - -generatePackageVersionMacros :: [UnitInfo] -> String -generatePackageVersionMacros pkgs = concat - -- Do not add any C-style comments. See #3389. - [ generateMacros "" pkgname version - | pkg <- pkgs - , let version = unitPackageVersion pkg - pkgname = map fixchar (unitPackageNameString pkg) - ] - -fixchar :: Char -> Char -fixchar '-' = '_' -fixchar c = c - -generateMacros :: String -> String -> Version -> String -generateMacros prefix name version = - concat - ["#define ", prefix, "VERSION_",name," ",show (showVersion version),"\n" - ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n" - ," (major1) < ",major1," || \\\n" - ," (major1) == ",major1," && (major2) < ",major2," || \\\n" - ," (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")" - ,"\n\n" - ] - where - (major1:major2:minor:_) = map show (versionBranch version ++ repeat 0) - - -- ----------------------------------------------------------------------------- -- Misc. @@ -1367,22 +1146,6 @@ touchObjectFile logger dflags path = do createDirectoryIfMissing True $ takeDirectory path GHC.SysTools.touch logger dflags "Touching object file" path --- | Find out path to @ghcversion.h@ file -getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath -getGhcVersionPathName dflags unit_env = do - candidates <- case ghcVersionFile dflags of - Just path -> return [path] - Nothing -> do - ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env [rtsUnitId]) - return (( "ghcversion.h") <$> collectIncludeDirs ps) - - found <- filterM doesFileExist candidates - case found of - [] -> throwGhcExceptionIO (InstallationError - ("ghcversion.h missing; tried: " - ++ intercalate ", " candidates)) - (x:_) -> return x - -- Note [-fPIC for assembler] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- When compiling .c source file GHC's driver pipeline basically ===================================== compiler/GHC/JS/Parser/Header.hs deleted ===================================== @@ -1,54 +0,0 @@ -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE OverloadedStrings #-} - ------------------------------------------------------------------------------ --- --- | Parsing the top of a JS source file to get its options. --- ------------------------------------------------------------------------------ - -module GHC.JS.Parser.Header - ( getOptionsFromJsFile - , JSOption(..) - ) -where - -import GHC.Prelude - -import System.IO -import Data.Char (isSpace) -import qualified Data.ByteString as B -import qualified Control.Exception as Exception - -getOptionsFromJsFile :: FilePath -- ^ Input file - -> IO [JSOption] -- ^ Parsed options, if any. -getOptionsFromJsFile filename - = Exception.bracket - (openBinaryFile filename ReadMode) - hClose - getJsOptions - -data JSOption = CPP deriving (Eq, Ord) - -getJsOptions :: Handle -> IO [JSOption] -getJsOptions handle = do - hSetEncoding handle utf8 - prefix' <- B.hGet handle prefixLen - if prefix == prefix' - then parseJsOptions <$> hGetLine handle - else pure [] - where - prefix :: B.ByteString - prefix = "//#OPTIONS:" - prefixLen = B.length prefix - -parseJsOptions :: String -> [JSOption] -parseJsOptions xs = go xs - where - trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace - go [] = [] - go xs = let (tok, rest) = break (== ',') xs - tok' = trim tok - rest' = drop 1 rest - in if | tok' == "CPP" -> CPP : go rest' - | otherwise -> go rest' ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -22,6 +22,7 @@ module GHC.StgToJS.Linker.Linker ( jsLinkBinary + , embedJsFile ) where @@ -33,6 +34,8 @@ import GHC.JS.Syntax import GHC.Driver.Session (DynFlags(..)) import Language.Haskell.Syntax.Module.Name +import GHC.SysTools.Cpp +import GHC.SysTools import GHC.Linker.Static.Utils (exeFileName) @@ -58,8 +61,8 @@ import GHC.Utils.Error import GHC.Utils.Logger (Logger, logVerbAtLeast) import GHC.Utils.Binary import qualified GHC.Utils.Ppr as Ppr -import GHC.Utils.CliOption import GHC.Utils.Monad +import GHC.Utils.TmpFs import qualified GHC.SysTools.Ar as Ar @@ -794,3 +797,70 @@ readDepsFromObj = \case readObjectDeps file >>= \case Nothing -> pure Nothing Just deps -> pure $ Just (deps,ObjectFile file) + + +-- | Embed a JS file into a .o file +-- +-- The JS file is merely copied into a .o file with an additional header +-- ("//Javascript") in order to be recognized later on. +-- +-- JS files may contain option pragmas of the form: //#OPTIONS: +-- For now, only the CPP option is supported. If the CPP option is set, we +-- append some common CPP definitions to the file and call cpp on it. +embedJsFile :: Logger -> DynFlags -> TmpFs -> UnitEnv -> FilePath -> FilePath -> IO () +embedJsFile logger dflags tmpfs unit_env input_fn output_fn = do + let profiling = False -- FIXME: add support for profiling way + + -- if the input filename is the same as the output, then we've probably + -- generated the object ourselves, we leave the file alone + when (input_fn /= output_fn) $ do + + -- the header lets the linker recognize processed JavaScript files + -- But don't add JavaScript header to object files! + + is_js_obj <- if True + then pure False + else isJsObjectFile input_fn + -- FIXME (Sylvain 2022-09): this call makes the + -- testsuite go into a loop, I don't know why yet! + -- Disabling it for now. + + if is_js_obj + then copyWithHeader "" input_fn output_fn + else do + -- header appended to JS files stored as .o to recognize them. + let header = "//JavaScript\n" + jsFileNeedsCpp input_fn >>= \case + False -> copyWithHeader header input_fn output_fn + True -> do + + -- append common CPP definitions to the .js file. + -- They define macros that avoid directly wiring zencoded names + -- in RTS JS files + pp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" + payload <- B.readFile input_fn + B.writeFile pp_fn (commonCppDefs profiling <> payload) + + -- run CPP on the input JS file + js_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" + let + cpp_opts = CppOpts + { cppUseCc = True + , cppLinePragmas = False -- LINE pragmas aren't JS compatible + } + extra_opts = [] + doCpp logger + tmpfs + dflags + unit_env + cpp_opts + extra_opts + pp_fn + js_fn + -- add header to recognize the object as a JS file + copyWithHeader header js_fn output_fn + +jsFileNeedsCpp :: FilePath -> IO Bool +jsFileNeedsCpp fn = do + opts <- getOptionsFromJsFile fn + pure (CPP `elem` opts) ===================================== compiler/GHC/StgToJS/Linker/Shims.hs deleted ===================================== @@ -1,195 +0,0 @@ -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE DeriveFunctor #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE TupleSections #-} - ------------------------------------------------------------------------------ --- | --- Module : GHC.StgToJS.Linker.Shims --- Copyright : (c) The University of Glasgow 2001 --- License : BSD-style (see the file LICENSE) --- --- Maintainer : Jeffrey Young --- Luite Stegeman --- Sylvain Henry --- Josh Meredith --- Stability : experimental --- --- A small DSL to handle Shim files in the JS backend, mostly used in --- 'GHC.StgToJS.Linker.Linker' --- ------------------------------------------------------------------------------ -module GHC.StgToJS.Linker.Shims - ( Shim() - , withShim - , parseShim - , readShimFiles - , tryReadShimFile - , streamShims - ) where - -import GHC.StgToJS.Linker.Utils - -import System.FilePath -import GHC.Driver.Session -import GHC.Driver.Pipeline.Execute (doCpp, CppOpts(..)) - -import GHC.Unit.Env -import GHC.Utils.TmpFs -import GHC.Utils.Logger -import GHC.Utils.Panic - -import Data.Foldable (toList) -import qualified Data.ByteString as B -import Data.Set (Set) -import qualified Data.Set as Set - -import Prelude - --- | A sum type to represent shims. Its sole purpose is to guarentee the --- ordering of shims during link time. This makes it much harder to compile the --- js-backend if the link ordering of shims is wrong. Each data constructor --- represents a single shim file located in either @JS_RTS_PATH@ or --- @JS_BASE_PATH at . See 'link'' for the call site. --- --- ** Invariant: The order of data constructors in 'Shim'' determines the shim --- link time ordering and there is a one-to-one correspondance between each --- shim file and each data constructor -type Shim = Shim' B.ByteString - -newtype Shim' a = Shim' { unShim :: (ShimLbl, a) } - deriving newtype Functor - --- | projections from Shims; project the shim label tag --- shimLabel :: Shim -> ShimLbl --- shimLabel = fst . unShim - --- | projections from Shims, project the payload -shimPayload :: Shim' a -> a -shimPayload = snd . unShim - --- | Take a shim and modify the payload, note that the shim label cannot change --- as this might invalidate the shim invariant -withShim :: Shim' a -> (a -> IO b) -> IO (Shim' b) -withShim (Shim' (lbl, payload)) f = Shim' . (lbl,) <$> f payload - - -instance Eq (Shim' a) where - (Shim' (l,_)) == (Shim' (r,_)) = l == r - -instance Ord (Shim' a) where - (Shim' (l,_)) `compare` (Shim' (r,_)) = l `compare` r - --- | A tag to label shim payloads, the ordering dictates the ordering shim files --- are linked. -data ShimLbl - -- Platform must be loaded quite early as it sets h$isNode which is used by - -- other shims (e.g. ShEnvironment) - = ShPlatform - | ShStructs - | ShProfiling - | ShRts - | ShGc - | ShArith - | ShCompact - | ShDebug - | ShEnum - | ShEnvironment - | ShErrno - | ShGoog - | ShHsCore - | ShMd5 - | ShMem - | ShNodeExports - | ShObject - | ShStablePtr - | ShStaticPtr - | ShStm - | ShString - | ShThread - | ShUnicode - | ShVerify - | ShWeak - | ShBase - deriving (Eq, Ord) - --- | Given a file path, check that the file is a shim file and construct a Shim --- value if so. This is the sole exported constructor for a Shim type. -parseShim :: FilePath -> IO Shim -parseShim f = let shimFn = takeFileName f - in case shimFn of - "rts.js.pp" -> (Shim' . (ShRts,)) <$> B.readFile f - "gc.js.pp" -> (Shim' . (ShGc,)) <$> B.readFile f - "arith.js.pp" -> (Shim' . (ShArith,)) <$> B.readFile f - "compact.js.pp" -> (Shim' . (ShCompact,)) <$> B.readFile f - "debug.js.pp" -> (Shim' . (ShDebug,)) <$> B.readFile f - "enum.js.pp" -> (Shim' . (ShEnum,)) <$> B.readFile f - "environment.js.pp" -> (Shim' . (ShEnvironment,)) <$> B.readFile f - "errno.js.pp" -> (Shim' . (ShErrno,)) <$> B.readFile f - "goog.js" -> (Shim' . (ShGoog,)) <$> B.readFile f - "hscore.js.pp" -> (Shim' . (ShHsCore,)) <$> B.readFile f - "md5.js" -> (Shim' . (ShMd5,)) <$> B.readFile f - "mem.js.pp" -> (Shim' . (ShMem,)) <$> B.readFile f - "node-exports.js" -> (Shim' . (ShNodeExports,)) <$> B.readFile f - "object.js.pp" -> (Shim' . (ShObject,)) <$> B.readFile f - "platform.js.pp" -> (Shim' . (ShPlatform,)) <$> B.readFile f - "profiling.js.pp" -> (Shim' . (ShProfiling,)) <$> B.readFile f - "stableptr.js.pp" -> (Shim' . (ShStablePtr,)) <$> B.readFile f - "staticpointer.js.pp" -> (Shim' . (ShStaticPtr,)) <$> B.readFile f - "stm.js.pp" -> (Shim' . (ShStm,)) <$> B.readFile f - "string.js.pp" -> (Shim' . (ShString,)) <$> B.readFile f - "structs.js.pp" -> (Shim' . (ShStructs,)) <$> B.readFile f - "thread.js.pp" -> (Shim' . (ShThread,)) <$> B.readFile f - "unicode.js" -> (Shim' . (ShUnicode,)) <$> B.readFile f - "verify.js.pp" -> (Shim' . (ShVerify,)) <$> B.readFile f - "weak.js.pp" -> (Shim' . (ShWeak,)) <$> B.readFile f - "base.js.pp" -> (Shim' . (ShBase,)) <$> B.readFile f - other -> panic $ - "parseShim: unrecognized shim file: " ++ show other - --- | Convert any Foldable thing that holds shims into a stream of shim payloads. --- This function frequently used in concert with 'Data.ByteString.fromChunks' in --- 'GHC.StgToJS.Linker.Linker' -streamShims :: Foldable f => f Shim -> [B.ByteString] -streamShims = fmap shimPayload . toList - --- | read a sequence of possible shim files into a Set of shims. The set is --- purposefully chosen to ensure a stable and order preserving container. -readShimFiles :: Logger -> TmpFs -> DynFlags -> UnitEnv -> [FilePath] -> IO (Set Shim) -readShimFiles logger tmpfs dflags unit_env = - fmap Set.fromList . mapM (tryReadShimFile logger tmpfs dflags unit_env) - --- | Attempt to read a shim file. This function may panic if the shim file --- cannot be parsed to an expected shim file as defined by the 'Shim' type. -tryReadShimFile :: Logger -> TmpFs -> DynFlags -> UnitEnv -> FilePath -> IO Shim -tryReadShimFile logger tmpfs dflags unit_env file = do - if needsCpp file - then do - let profiling = False - cpp_opts = CppOpts - { cppUseCc = True - , cppLinePragmas = False -- LINE pragmas aren't JS compatible - } - extra_opts = [] - - -- load the shim into memory - shim <- parseShim file - -- make a temp file for doCpp - infile <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "jsppx" - - withShim shim $ \payload -> - do -- preparation: append common CPP definitions to the .pp file. - B.writeFile infile $ (commonCppDefs profiling) <> payload - outfile <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "jspp" - -- do the business - doCpp logger tmpfs dflags unit_env cpp_opts extra_opts infile outfile - B.readFile outfile - else parseShim file - --- | Test if file has ".pp" extension --- --- running the C preprocessor on JS files is a bit fragile --- and breaks in some situations. Therefore we only preprocess --- files with .pp extension, for example lib.js.pp -needsCpp :: FilePath -> Bool -needsCpp file = "pp" `isExtensionOf` file ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE MultiWayIf #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.StgToJS.Linker.Utils @@ -15,13 +16,20 @@ -- ----------------------------------------------------------------------------- -module GHC.StgToJS.Linker.Utils where +module GHC.StgToJS.Linker.Utils + ( getOptionsFromJsFile + , JSOption(..) + , jsExeFileName + , getInstalledPackageLibDirs + , getInstalledPackageHsLibs + , commonCppDefs + ) +where import System.FilePath import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as Char8 import Data.ByteString (ByteString) -import System.IO (withBinaryFile, IOMode(WriteMode)) import GHC.Driver.Session import GHC.Settings.Config (cProjectVersion) @@ -36,6 +44,10 @@ import Prelude import GHC.Platform import Data.List (isPrefixOf) import System.Directory (createDirectoryIfMissing) +import System.IO +import Data.Char (isSpace) +import qualified Data.ByteString as B +import qualified Control.Exception as Exception -- | Given a FilePath and payload, write a file to disk creating any directories -- along the way if needed. @@ -145,24 +157,6 @@ genCommonCppDefs profiling = mconcat then "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM))\n" else "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset)))\n" - -- GHC.Integer.GMP.Internals - , "#define IS_INTEGER_S(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e)\n" - , "#define IS_INTEGER_Jp(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e)\n" - , "#define IS_INTEGER_Jn(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e)\n" - , "#define INTEGER_S_DATA(cl) ((cl).d1)\n" - , "#define INTEGER_J_DATA(cl) ((cl).d1)\n" - , if profiling - then mconcat - [ "#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii), h$CCS_SYSTEM));\n" - , "#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii), h$CCS_SYSTEM));\n" - , "#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii), h$CCS_SYSTEM));\n" - ] - else mconcat - [ "#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii)));\n" - , "#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii)));\n" - , "#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii)));\n" - ] - -- Data.Maybe.Maybe , "#define HS_NOTHING h$baseZCGHCziMaybeziNothing\n" , "#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e)\n" @@ -297,3 +291,38 @@ jsExeFileName dflags dropPrefix prefix xs | prefix `isPrefixOf` xs = drop (length prefix) xs | otherwise = xs + + +-- | Parse option pragma in JS file +getOptionsFromJsFile :: FilePath -- ^ Input file + -> IO [JSOption] -- ^ Parsed options, if any. +getOptionsFromJsFile filename + = Exception.bracket + (openBinaryFile filename ReadMode) + hClose + getJsOptions + +data JSOption = CPP deriving (Eq, Ord) + +getJsOptions :: Handle -> IO [JSOption] +getJsOptions handle = do + hSetEncoding handle utf8 + prefix' <- B.hGet handle prefixLen + if prefix == prefix' + then parseJsOptions <$> hGetLine handle + else pure [] + where + prefix :: B.ByteString + prefix = "//#OPTIONS:" + prefixLen = B.length prefix + +parseJsOptions :: String -> [JSOption] +parseJsOptions xs = go xs + where + trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace + go [] = [] + go xs = let (tok, rest) = break (== ',') xs + tok' = trim tok + rest' = drop 1 rest + in if | tok' == "CPP" -> CPP : go rest' + | otherwise -> go rest' ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -0,0 +1,235 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE LambdaCase #-} + +#include + +module GHC.SysTools.Cpp + ( doCpp + , CppOpts (..) + , getGhcVersionPathName + , applyCDefs + , offsetIncludePaths + ) +where + +import GHC.Prelude +import GHC.Driver.Session +import GHC.Driver.Backend +import GHC.CmmToLlvm.Config +import GHC.Platform +import GHC.Platform.ArchOS + +import GHC.SysTools + +import GHC.Unit.Env +import GHC.Unit.Info +import GHC.Unit.State +import GHC.Unit.Types + +import GHC.Utils.Logger +import GHC.Utils.TmpFs +import GHC.Utils.Panic + +import Data.Version +import Data.List (intercalate) +import Data.Maybe + +import Control.Monad + +import System.Directory +import System.FilePath + +data CppOpts = CppOpts + { cppUseCc :: !Bool -- ^ Use "cc -E" as preprocessor, otherwise use "cpp" + , cppLinePragmas :: !Bool -- ^ Enable generation of LINE pragmas + } + +-- | Run CPP +-- +-- UnitEnv is needed to compute MIN_VERSION macros +doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> [Option] -> FilePath -> FilePath -> IO () +doCpp logger tmpfs dflags unit_env opts extra_opts input_fn output_fn = do + let hscpp_opts = picPOpts dflags + let cmdline_include_paths = offsetIncludePaths dflags (includePaths dflags) + let unit_state = ue_units unit_env + pkg_include_dirs <- mayThrowUnitErr + (collectIncludeDirs <$> preloadUnitsInfo unit_env) + -- MP: This is not quite right, the headers which are supposed to be installed in + -- the package might not be the same as the provided include paths, but it's a close + -- enough approximation for things to work. A proper solution would be to have to declare which paths should + -- be propagated to dependent packages. + let home_pkg_deps = + [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- ue_transitiveHomeDeps (ue_currentUnit unit_env) unit_env] + dep_pkg_extra_inputs = [offsetIncludePaths fs (includePaths fs) | fs <- home_pkg_deps] + + let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) [] + (includePathsGlobal cmdline_include_paths ++ pkg_include_dirs + ++ concatMap includePathsGlobal dep_pkg_extra_inputs) + let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) [] + (includePathsQuote cmdline_include_paths ++ + includePathsQuoteImplicit cmdline_include_paths) + let include_paths = include_paths_quote ++ include_paths_global + + let verbFlags = getVerbFlags dflags + + let cpp_prog args + | cppUseCc opts = GHC.SysTools.runCc Nothing logger tmpfs dflags + (GHC.SysTools.Option "-E" : args) + | otherwise = GHC.SysTools.runCpp logger dflags args + + let platform = targetPlatform dflags + targetArch = stringEncodeArch $ platformArch platform + targetOS = stringEncodeOS $ platformOS platform + isWindows = platformOS platform == OSMinGW32 + let target_defs = + [ "-D" ++ HOST_OS ++ "_BUILD_OS", + "-D" ++ HOST_ARCH ++ "_BUILD_ARCH", + "-D" ++ targetOS ++ "_HOST_OS", + "-D" ++ targetArch ++ "_HOST_ARCH" ] + -- remember, in code we *compile*, the HOST is the same our TARGET, + -- and BUILD is the same as our HOST. + + let io_manager_defs = + [ "-D__IO_MANAGER_WINIO__=1" | isWindows ] ++ + [ "-D__IO_MANAGER_MIO__=1" ] + + let sse_defs = + [ "-D__SSE__" | isSseEnabled platform ] ++ + [ "-D__SSE2__" | isSse2Enabled platform ] ++ + [ "-D__SSE4_2__" | isSse4_2Enabled dflags ] + + let avx_defs = + [ "-D__AVX__" | isAvxEnabled dflags ] ++ + [ "-D__AVX2__" | isAvx2Enabled dflags ] ++ + [ "-D__AVX512CD__" | isAvx512cdEnabled dflags ] ++ + [ "-D__AVX512ER__" | isAvx512erEnabled dflags ] ++ + [ "-D__AVX512F__" | isAvx512fEnabled dflags ] ++ + [ "-D__AVX512PF__" | isAvx512pfEnabled dflags ] + + backend_defs <- applyCDefs (backendCDefs $ backend dflags) logger dflags + + let th_defs = [ "-D__GLASGOW_HASKELL_TH__" ] + -- Default CPP defines in Haskell source + ghcVersionH <- getGhcVersionPathName dflags unit_env + let hsSourceCppOpts = [ "-include", ghcVersionH ] + + -- MIN_VERSION macros + let uids = explicitUnits unit_state + pkgs = mapMaybe (lookupUnit unit_state . fst) uids + mb_macro_include <- + if not (null pkgs) && gopt Opt_VersionMacros dflags + then do macro_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "h" + writeFile macro_stub (generatePackageVersionMacros pkgs) + -- Include version macros for every *exposed* package. + -- Without -hide-all-packages and with a package database + -- size of 1000 packages, it takes cpp an estimated 2 + -- milliseconds to process this file. See #10970 + -- comment 8. + return [GHC.SysTools.FileOption "-include" macro_stub] + else return [] + + let line_pragmas + | cppLinePragmas opts = [] -- on by default + | otherwise = [GHC.SysTools.Option "-P"] -- disable LINE markers + + cpp_prog ( map GHC.SysTools.Option verbFlags + ++ map GHC.SysTools.Option include_paths + ++ map GHC.SysTools.Option hsSourceCppOpts + ++ map GHC.SysTools.Option target_defs + ++ map GHC.SysTools.Option backend_defs + ++ map GHC.SysTools.Option th_defs + ++ map GHC.SysTools.Option hscpp_opts + ++ map GHC.SysTools.Option sse_defs + ++ map GHC.SysTools.Option avx_defs + ++ map GHC.SysTools.Option io_manager_defs + ++ mb_macro_include + ++ extra_opts + ++ line_pragmas + -- Set the language mode to assembler-with-cpp when preprocessing. This + -- alleviates some of the C99 macro rules relating to whitespace and the hash + -- operator, which we tend to abuse. Clang in particular is not very happy + -- about this. + ++ [ GHC.SysTools.Option "-x" + , GHC.SysTools.Option "assembler-with-cpp" + , GHC.SysTools.Option input_fn + -- We hackily use Option instead of FileOption here, so that the file + -- name is not back-slashed on Windows. cpp is capable of + -- dealing with / in filenames, so it works fine. Furthermore + -- if we put in backslashes, cpp outputs #line directives + -- with *double* backslashes. And that in turn means that + -- our error messages get double backslashes in them. + -- In due course we should arrange that the lexer deals + -- with these \\ escapes properly. + , GHC.SysTools.Option "-o" + , GHC.SysTools.FileOption "" output_fn + ]) + +-- --------------------------------------------------------------------------- +-- Macros (cribbed from Cabal) + +generatePackageVersionMacros :: [UnitInfo] -> String +generatePackageVersionMacros pkgs = concat + -- Do not add any C-style comments. See #3389. + [ generateMacros "" pkgname version + | pkg <- pkgs + , let version = unitPackageVersion pkg + pkgname = map fixchar (unitPackageNameString pkg) + ] + +fixchar :: Char -> Char +fixchar '-' = '_' +fixchar c = c + +generateMacros :: String -> String -> Version -> String +generateMacros prefix name version = + concat + ["#define ", prefix, "VERSION_",name," ",show (showVersion version),"\n" + ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n" + ," (major1) < ",major1," || \\\n" + ," (major1) == ",major1," && (major2) < ",major2," || \\\n" + ," (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")" + ,"\n\n" + ] + where + take3 = \case + (a:b:c:_) -> (a,b,c) + _ -> error "take3" + (major1,major2,minor) = take3 $ map show (versionBranch version) ++ repeat "0" + + +-- | Find out path to @ghcversion.h@ file +getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath +getGhcVersionPathName dflags unit_env = do + candidates <- case ghcVersionFile dflags of + Just path -> return [path] + Nothing -> do + ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env [rtsUnitId]) + return (( "ghcversion.h") <$> collectIncludeDirs ps) + + found <- filterM doesFileExist candidates + case found of + [] -> throwGhcExceptionIO (InstallationError + ("ghcversion.h missing; tried: " + ++ intercalate ", " candidates)) + (x:_) -> return x + +applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String] +applyCDefs NoCDefs _ _ = return [] +applyCDefs LlvmCDefs logger dflags = do + llvmVer <- figureLlvmVersion logger dflags + return $ case fmap llvmVersionList llvmVer of + Just [m] -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,0) ] + Just (m:n:_) -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,n) ] + _ -> [] + where + format (major, minor) + | minor >= 100 = error "backendCDefs: Unsupported minor version" + | otherwise = show (100 * major + minor :: Int) -- Contract is Int + + +-- Note [Filepaths and Multiple Home Units] +offsetIncludePaths :: DynFlags -> IncludeSpecs -> IncludeSpecs +offsetIncludePaths dflags (IncludeSpecs incs quotes impl) = + let go = map (augmentByWorkingDirectory dflags) + in IncludeSpecs (go incs) (go quotes) (go impl) + ===================================== compiler/ghc.cabal.in ===================================== @@ -520,7 +520,6 @@ Library GHC.JS.Ppr GHC.JS.Syntax GHC.JS.Transform - GHC.JS.Parser.Header GHC.Linker GHC.Linker.Dynamic GHC.Linker.ExtraObj @@ -666,11 +665,11 @@ Library GHC.StgToJS.Linker.Linker GHC.StgToJS.Linker.Types GHC.StgToJS.Linker.Utils - GHC.StgToJS.Linker.Shims GHC.Stg.Unarise GHC.SysTools GHC.SysTools.Ar GHC.SysTools.BaseDir + GHC.SysTools.Cpp GHC.SysTools.Elf GHC.SysTools.Info GHC.SysTools.Process ===================================== libraries/base/jsbits/base.js ===================================== @@ -1,8 +1,6 @@ //#OPTIONS: CPP #include "HsBaseConfig.h" -#include - // #define GHCJS_TRACE_IO 1 #ifdef GHCJS_TRACE_IO ===================================== libraries/base/jsbits/errno.js ===================================== @@ -1,8 +1,6 @@ //#OPTIONS: CPP #include "HsBaseConfig.h" -#include - #ifdef GHCJS_TRACE_ERRNO function h$logErrno() { h$log.apply(h$log,arguments); } @@ -41,6 +39,7 @@ function h$setErrno(e) { var es = e.toString(); var getErr = function() { if(es.indexOf('ENOTDIR') !== -1) return CONST_ENOTDIR; + if(es.indexOf('EISDIR') !== -1) return CONST_EISDIR; if(es.indexOf('ENOENT') !== -1) return CONST_ENOENT; if(es.indexOf('EEXIST') !== -1) return CONST_EEXIST; if(es.indexOf('ENETUNREACH') !== -1) return CONST_EINVAL; // fixme @@ -63,6 +62,7 @@ var h$errorStrs = { CONST_E2BIG: "Argument list too long" , CONST_EINVAL: "Invalid argument" , CONST_EBADF: "Bad file descriptor" , CONST_ENOTDIR: "Not a directory" + , CONST_EISDIR: "Illegal operation on a directory" , CONST_ENOENT: "No such file or directory" , CONST_EPERM: "Operation not permitted" , CONST_EEXIST: "File exists" ===================================== rts/include/js/constants.h deleted ===================================== @@ -1,18 +0,0 @@ -#ifndef __GHCJS_CONSTANTS_H_ -#define __GHCJS_CONSTANTS_H_ - -// values defined in Gen2.ClosureInfo -#define CLOSURE_TYPE_FUN (1) -#define CLOSURE_TYPE_CON (2) -#define CLOSURE_TYPE_THUNK (0) -#define CLOSURE_TYPE_PAP (3) -#define CLOSURE_TYPE_BLACKHOLE (5) -#define CLOSURE_TYPE_STACKFRAME (-1) - -// thread status -#define THREAD_RUNNING (0) -#define THREAD_BLOCKED (1) -#define THREAD_FINISHED (16) -#define THREAD_DIED (17) - -#endif ===================================== rts/include/js/rts.h deleted ===================================== @@ -1,196 +0,0 @@ -#ifndef __GHCJS_RTS_H_ -#define __GHCJS_RTS_H_ - -#include "constants.h" - -/* - * low-level heap object manipulation macros - */ - -#ifdef GHCJS_PROF -#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM)) -#else -#define MK_TUP2(x1,x2) (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2))) -#define MK_TUP3(x1,x2,x3) (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3))) -#define MK_TUP4(x1,x2,x3,x4) (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4))) -#define MK_TUP5(x1,x2,x3,x4,x5) (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5))) -#define MK_TUP6(x1,x2,x3,x4,x5,x6) (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6))) -#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7) (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7))) -#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8))) -#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9))) -#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10))) -#endif - -#define TUP2_1(x) ((x).d1) -#define TUP2_2(x) ((x).d2) - - - -// GHC.JS.Prim.JSVal -#ifdef GHCJS_PROF -#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x), h$CCS_SYSTEM)) -#else -#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x))) -#endif -#define JSVAL_VAL(x) ((x).d1) - -// GHC.JS.Prim.JSException -#ifdef GHCJS_PROF -#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg),h$CCS_SYSTEM)) -#else -#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg))) -#endif -// Exception dictionary for JSException -#define HS_JSEXCEPTION_EXCEPTION h$baseZCGHCziJSziPrimzizdfExceptionJSException - -// SomeException -#ifdef GHCJS_PROF -#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except),h$CCS_SYSTEM)) -#else -#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except))) -#endif - -// GHC.Ptr.Ptr -#ifdef GHCJS_PROF -#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM)) -#else -#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset))) -#endif - -// GHC.Integer.GMP.Internals -#define IS_INTEGER_S(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e) -#define IS_INTEGER_Jp(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e) -#define IS_INTEGER_Jn(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e) -#define INTEGER_S_DATA(cl) ((cl).d1) -#define INTEGER_J_DATA(cl) ((cl).d1) -#ifdef GHCJS_PROF -#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii), h$CCS_SYSTEM)); -#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii), h$CCS_SYSTEM)); -#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii), h$CCS_SYSTEM)); -#else -#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii))); -#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii))); -#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii))); -#endif - -// Data.Maybe.Maybe -#define HS_NOTHING h$baseZCGHCziMaybeziNothing -#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e) -#define IS_JUST(cl) ((cl).f === h$baseZCGHCziMaybeziJust_con_e) -#define JUST_VAL(jj) ((jj).d1) -// #define HS_NOTHING h$nothing -#ifdef GHCJS_PROF -#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val), h$CCS_SYSTEM)) -#else -#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val))) -#endif - -// Data.List -#define HS_NIL h$ghczmprimZCGHCziTypesziZMZN -#define HS_NIL_CON h$ghczmprimZCGHCziTypesziZMZN_con_e -#define IS_CONS(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZC_con_e) -#define IS_NIL(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZMZN_con_e) -#define CONS_HEAD(cl) ((cl).d1) -#define CONS_TAIL(cl) ((cl).d2) -#ifdef GHCJS_PROF -#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), h$CCS_SYSTEM)) -#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), (cc))) -#else -#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail))) -#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail))) -#endif - -// Data.Text -#define DATA_TEXT_ARRAY(x) ((x).d1) -#define DATA_TEXT_OFFSET(x) ((x).d2.d1) -#define DATA_TEXT_LENGTH(x) ((x).d2.d2) - -// Data.Text.Lazy -#define LAZY_TEXT_IS_CHUNK(x) ((x).f.a === 2) -#define LAZY_TEXT_IS_NIL(x) ((x).f.a === 1) -#define LAZY_TEXT_CHUNK_HEAD(x) ((x)) -#define LAZY_TEXT_CHUNK_TAIL(x) ((x).d2.d3) - -// black holes -// can we skip the indirection for black holes? -#define IS_BLACKHOLE(x) (typeof (x) === 'object' && (x) && (x).f && (x).f.t === CLOSURE_TYPE_BLACKHOLE) -#define BLACKHOLE_TID(bh) ((bh).d1) -#define SET_BLACKHOLE_TID(bh,tid) ((bh).d1 = (tid)) -#define BLACKHOLE_QUEUE(bh) ((bh).d2) -#define SET_BLACKHOLE_QUEUE(bh,val) ((bh).d2 = (val)) - -// resumable thunks -#define MAKE_RESUMABLE(closure,stack) { (closure).f = h$resume_e; (closure).d1 = (stack), (closure).d2 = null; } - -// general deconstruction -#define IS_THUNK(x) ((x).f.t === CLOSURE_TYPE_THUNK) -#define CONSTR_TAG(x) ((x).f.a) - -// retrieve a numeric value that's possibly stored as an indirection -#define IS_WRAPPED_NUMBER(val) ((typeof(val)==='object')&&(val).f === h$unbox_e) -#define UNWRAP_NUMBER(val) ((typeof(val) === 'number')?(val):(val).d1) - -// generic lazy values -#ifdef GHCJS_PROF -#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun), h$CCS_SYSTEM)) -#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun), (cc))) -#else -#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun))) -#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun))) -#endif - -// generic data constructors and selectors -#ifdef GHCJS_PROF -#define MK_DATA1_1(val) (h$c1(h$data1_e, (val), h$CCS_SYSTEM)) -#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM)) -#define MK_DATA2_1(val) (h$c1(h$data2_e, (val), h$CCS_SYSTEM)) -#define MK_DATA2_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM)) -#define MK_SELECT1(val) (h$c1(h$select1_e, (val), h$CCS_SYSTEM)) -#define MK_SELECT2(val) (h$c1(h$select2_e, (val), h$CCS_SYSTEM)) -#define MK_AP1(fun,val) (h$c2(h$ap1_e, (fun), (val), h$CCS_SYSTEM)) -#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e, (fun), (val1), (val2), h$CCS_SYSTEM)) -#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3), h$CCS_SYSTEM)) -#else -#define MK_DATA1_1(val) (h$c1(h$data1_e, (val))) -#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2))) -#define MK_DATA2_1(val) (h$c1(h$data2_e, (val))) -#define MK_DATA2_2(val1,val2) (h$c2(h$data2_e, (val1), (val2))) -#define MK_SELECT1(val) (h$c1(h$select1_e, (val))) -#define MK_SELECT2(val) (h$c1(h$select2_e, (val))) -#define MK_AP1(fun,val) (h$c2(h$ap1_e,(fun),(val))) -#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e,(fun),(val1),(val2))) -#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3))) -#endif - -// unboxed tuple returns -// #define RETURN_UBX_TUP1(x) return x; -#define RETURN_UBX_TUP2(x1,x2) { h$ret1 = (x2); return (x1); } -#define RETURN_UBX_TUP3(x1,x2,x3) { h$ret1 = (x2); h$ret2 = (x3); return (x1); } -#define RETURN_UBX_TUP4(x1,x2,x3,x4) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); return (x1); } -#define RETURN_UBX_TUP5(x1,x2,x3,x4,x5) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); return (x1); } -#define RETURN_UBX_TUP6(x1,x2,x3,x4,x5,x6) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); return (x1); } -#define RETURN_UBX_TUP7(x1,x2,x3,x4,x5,x6,x7) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); return (x1); } -#define RETURN_UBX_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); return (x1); } -#define RETURN_UBX_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); return (x1); } -#define RETURN_UBX_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); h$ret9 = (x10); return (x1); } - -#define CALL_UBX_TUP2(r1,r2,c) { (r1) = (c); (r2) = h$ret1; } -#define CALL_UBX_TUP3(r1,r2,r3,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; } -#define CALL_UBX_TUP4(r1,r2,r3,r4,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; } -#define CALL_UBX_TUP5(r1,r2,r3,r4,r5,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; } -#define CALL_UBX_TUP6(r1,r2,r3,r4,r5,r6,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; } -#define CALL_UBX_TUP7(r1,r2,r3,r4,r5,r6,r7,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; } -#define CALL_UBX_TUP8(r1,r2,r3,r4,r5,r6,r7,r8,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; } -#define CALL_UBX_TUP9(r1,r2,r3,r4,r5,r6,r7,r8,r9,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; } -#define CALL_UBX_TUP10(r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; (r10) = h$ret9; } - - -#endif ===================================== rts/js/arith.js ===================================== @@ -1,8 +1,6 @@ //#OPTIONS: CPP // #define GHCJS_TRACE_ARITH 1 -#include - #ifdef GHCJS_TRACE_ARITH function h$logArith() { h$log.apply(h$log,arguments); } #define TRACE_ARITH(args...) h$logArith(args) ===================================== rts/js/compact.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - #ifdef GHCJS_TRACE_COMPACT function h$logCompact() { h$log.apply(h$log,arguments); } #define TRACE_COMPACT(args...) h$logCompact(args) ===================================== rts/js/environment.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - #ifdef GHCJS_TRACE_ENV function h$logEnv() { h$log.apply(h$log,arguments); } #define TRACE_ENV(args...) h$logEnv(args) ===================================== rts/js/globals.js ===================================== @@ -0,0 +1,19 @@ +//#OPTIONS: CPP + +// Globals used by GHC + +#define GVAR(name,nvar) \ + var h$global_ ## nvar ## _a = null;\ + var h$global_ ## nvar ## _o = null;\ + function name(a,o) {\ + if (!h$global_ ## nvar ## _a) {\ + h$global_ ## nvar ## _a = a;\ + h$global_ ## nvar ## _o = o;\ + }\ + RETURN_UBX_TUP2(h$global_ ## nvar ##_a, h$global_ ## nvar ##_o);\ + } + +GVAR(h$getOrSetLibHSghcGlobalHasPprDebug, has_ppr_debug) +GVAR(h$getOrSetLibHSghcGlobalHasNoDebugOutput, has_no_debug_output) +GVAR(h$getOrSetLibHSghcGlobalHasNoStateHack, has_no_state_hack) +GVAR(h$getOrSetLibHSghcFastStringTable, faststring_table) ===================================== rts/js/hscore.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - #ifdef GHCJS_TRACE_HSCORE function h$logHscore() { h$log.apply(h$log,arguments); } #define TRACE_HSCORE(args...) h$logHscore(args) ===================================== rts/js/mem.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // #define GHCJS_TRACE_META 1 #ifdef GHCJS_TRACE_META ===================================== rts/js/object.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // JS Objects stuff function h$isFloat (n) { ===================================== rts/js/rts.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - var h$start = new Date(); function h$rts_eval(action, unbox) { ===================================== rts/js/staticpointer.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // static pointers var h$static_pointer_table = null; var h$static_pointer_table_keys = null; ===================================== rts/js/string.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // encode a string constant function h$str(s) { var enc = null; ===================================== rts/js/thread.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // preemptive threading support // run gc when this much time has passed (ms) ===================================== rts/js/weak.js ===================================== @@ -1,7 +1,5 @@ //#OPTIONS: CPP -#include - // weak reference support var h$weakPointerList = []; ===================================== rts/rts.cabal.in ===================================== @@ -84,6 +84,7 @@ library js/enum.js js/environment.js js/gc.js + js/globals.js js/goog.js js/hscore.js js/md5.js @@ -107,8 +108,6 @@ library stg/MachRegs.h stg/MachRegsForHost.h stg/Types.h - js/rts.h - js/constants.h else -- If we are using an in-tree libffi then we must declare it as a bundled View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ec975cac75be10ac77b472550d7df4dabdb2da4...0015d2d96866b09142cf58fcc27ef4ffbfcda9bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ec975cac75be10ac77b472550d7df4dabdb2da4...0015d2d96866b09142cf58fcc27ef4ffbfcda9bc You're receiving 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 Oct 11 19:53:10 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 15:53:10 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Tidy implicit binds Message-ID: <6345c9a6e90f_1eea6a5181c22413884d0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 4b8d66b3 by Bodigrim at 2022-10-11T15:52:50-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 6827249c by jwaldmann at 2022-10-11T15:52:50-04:00 Expand comment for Data.List.permutations - - - - - c480bd0a by Bodigrim at 2022-10-11T15:52:52-04:00 ByteArray# is unlifted, not unboxed - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Types/SrcLoc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8387bf129fde37d181cc8344238ea2f045bec330...c480bd0a37d192e59b8483cd3eee9b51481cb7ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8387bf129fde37d181cc8344238ea2f045bec330...c480bd0a37d192e59b8483cd3eee9b51481cb7ea You're receiving 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 Oct 11 20:31:31 2022 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Tue, 11 Oct 2022 16:31:31 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Test big return frames Message-ID: <6345d2a320c0c_1eea6a5fada5c01408114@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 98f7acc0 by Sven Tennie at 2022-10-11T20:30:59+00:00 Test big return frames - - - - - 3 changed files: - libraries/ghc-heap/GHC/Exts/DecodeStack.hs - libraries/ghc-heap/tests/TestUtils.hs - libraries/ghc-heap/tests/all.T Changes: ===================================== libraries/ghc-heap/GHC/Exts/DecodeStack.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +#if MIN_VERSION_base(4,17,0) {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GHCForeignImportPrim #-} {-# LANGUAGE MagicHash #-} @@ -12,9 +13,12 @@ {-# LANGUAGE BangPatterns #-} -- TODO: Find better place than top level. Re-export from top-level? -module GHC.Exts.DecodeStack where +module GHC.Exts.DecodeStack ( + StackFrame(..), + BitmapPayload(..), + decodeStack + ) where -#if MIN_VERSION_base(4,17,0) import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) import Data.Maybe import Data.Bits @@ -233,7 +237,7 @@ data StackFrame = UnderflowFrame { nextChunk:: StackSnapshot } | StopFrame | RetSmall SpecialRetSmall [BitmapPayload] | - RetBig [BitmapPayload] | + RetBig { payload :: [BitmapPayload] } | RetFun | RetBCO deriving (Show) @@ -259,4 +263,6 @@ decodeStack' s = unpackStackFrameIter (stackHead s) : go (advanceStackFrameIter go Nothing = [] go (Just sfi) = unpackStackFrameIter sfi : go (advanceStackFrameIter sfi) +#else +module GHC.Exts.DecodeStack where #endif ===================================== libraries/ghc-heap/tests/TestUtils.hs ===================================== @@ -1,7 +1,24 @@ -{-# LANGUAGE MagicHash #-} +{-# LANGUAGE LambdaCase #-} + module TestUtils where -assertEqual :: (Show a, Eq a) => a -> a -> IO () +import GHC.Exts.DecodeStack +import GHC.Stack (HasCallStack) + +assertEqual :: (HasCallStack, Monad m, Show a, Eq a) => a -> a -> m () assertEqual a b | a /= b = error (show a ++ " /= " ++ show b) - | otherwise = return () + | otherwise = pure () + +assertThat :: (HasCallStack, Monad m) => String -> (a -> Bool) -> a -> m () +assertThat s f a = if f a then pure () else error s + +assertStackInvariants :: (HasCallStack, Monad m) => [StackFrame] -> m () +assertStackInvariants decodedStack = + assertThat + "Last frame is stop frame" + ( \case + StopFrame -> True + _ -> False + ) + (last decodedStack) ===================================== libraries/ghc-heap/tests/all.T ===================================== @@ -60,15 +60,20 @@ test('decode_cloned_stack', [only_ways(['normal'])], compile_and_run, ['-debug -optc-g -g']) -# TODO: Are debug flags needed here? -test('decode_cloned_stack_big_ret', - [only_ways(['normal'])], - compile_and_run, ['-debug -optc-g -g -DDEBUG']) +test('stack_big_ret', + [ + extra_files(['TestUtils.hs']), + ignore_stdout, + ignore_stderr + ], + compile_and_run, + ['']) # Options: # - `-kc512B -kb64B`: Make stack chunk size small to provoke underflow stack frames. test('stack_underflow', [ + extra_files(['TestUtils.hs']), extra_run_opts('+RTS -kc512B -kb64B -RTS'), ignore_stdout, ignore_stderr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/98f7acc048ca29d49719f9537565aae43cc28c6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/98f7acc048ca29d49719f9537565aae43cc28c6c You're receiving 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 Oct 11 21:01:28 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Oct 2022 17:01:28 -0400 Subject: [Git][ghc/ghc][wip/T21851] 9 commits: Tidy implicit binds Message-ID: <6345d9a8ad3f_1eea6a5fada5c01411115@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851 at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 7a90f5f7 by Simon Peyton Jones at 2022-10-11T22:01:07+01:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b1ddd8784556ba6c9a69cca1c80d665b5e991b...7a90f5f76355ab122de705f0a87e40483ea1133f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b1ddd8784556ba6c9a69cca1c80d665b5e991b...7a90f5f76355ab122de705f0a87e40483ea1133f You're receiving 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 Oct 11 22:03:18 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 18:03:18 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Extend documentation for Data.List, mostly wrt infinite lists Message-ID: <6345e82625e59_1eea6a5141414237d1@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - 3 changed files: - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/List.hs Changes: ===================================== libraries/base/Data/List.hs ===================================== @@ -229,14 +229,23 @@ import GHC.Base ( Bool(..), Eq((==)), otherwise ) -- -- @since 4.8.0.0 -- --- ==== __Examples__ --- -- >>> isSubsequenceOf "GHC" "The Glorious Haskell Compiler" -- True -- >>> isSubsequenceOf ['a','d'..'z'] ['a'..'z'] -- True -- >>> isSubsequenceOf [1..10] [10,9..0] -- False +-- +-- For the result to be 'True', the first list must be finite; +-- for the result to be 'False', the second list must be finite: +-- +-- >>> [0,2..10] `isSubsequenceOf` [0..] +-- True +-- >>> [0..] `isSubsequenceOf` [0,2..10] +-- False +-- >>> [0,2..] `isSubsequenceOf` [0..] +-- * Hangs forever* +-- isSubsequenceOf :: (Eq a) => [a] -> [a] -> Bool isSubsequenceOf [] _ = True isSubsequenceOf _ [] = False ===================================== libraries/base/Data/OldList.hs ===================================== @@ -266,6 +266,7 @@ stripPrefix _ _ = Nothing -- | The 'elemIndex' function returns the index of the first element -- in the given list which is equal (by '==') to the query element, -- or 'Nothing' if there is no such element. +-- For the result to be 'Nothing', the list must be finite. -- -- >>> elemIndex 4 [0..] -- Just 4 @@ -283,6 +284,7 @@ elemIndices x xs = findIndices (x==) xs -- arity 2 so that we don't get a PAP; # -- | The 'find' function takes a predicate and a list and returns the -- first element in the list matching the predicate, or 'Nothing' if -- there is no such element. +-- For the result to be 'Nothing', the list must be finite. -- -- >>> find (> 4) [1..] -- Just 5 @@ -295,6 +297,7 @@ find p = listToMaybe . filter p -- | The 'findIndex' function takes a predicate and a list and returns -- the index of the first element in the list satisfying the predicate, -- or 'Nothing' if there is no such element. +-- For the result to be 'Nothing', the list must be finite. -- -- >>> findIndex isSpace "Hello World!" -- Just 5 @@ -325,23 +328,41 @@ findIndices p ls = build $ \c n -> -- -- >>> "Hello" `isPrefixOf` "Hello World!" -- True --- -- >>> "Hello" `isPrefixOf` "Wello Horld!" -- False +-- +-- For the result to be 'True', the first list must be finite; +-- 'False', however, results from any mismatch: +-- +-- >>> [0..] `isPrefixOf` [1..] +-- False +-- >>> [0..] `isPrefixOf` [0..99] +-- False +-- >>> [0..99] `isPrefixOf` [0..] +-- True +-- >>> [0..] `isPrefixOf` [0..] +-- * Hangs forever * +-- isPrefixOf :: (Eq a) => [a] -> [a] -> Bool isPrefixOf [] _ = True isPrefixOf _ [] = False isPrefixOf (x:xs) (y:ys)= x == y && isPrefixOf xs ys -- | The 'isSuffixOf' function takes two lists and returns 'True' iff --- the first list is a suffix of the second. The second list must be --- finite. +-- the first list is a suffix of the second. -- -- >>> "ld!" `isSuffixOf` "Hello World!" -- True --- -- >>> "World" `isSuffixOf` "Hello World!" -- False +-- +-- The second list must be finite; however the first list may be infinite: +-- +-- >>> [0..] `isSuffixOf` [0..99] +-- False +-- >>> [0..99] `isSuffixOf` [0..] +-- * Hangs forever * +-- isSuffixOf :: (Eq a) => [a] -> [a] -> Bool ns `isSuffixOf` hs = maybe False id $ do delta <- dropLengthMaybe ns hs @@ -383,9 +404,19 @@ dropLengthMaybe (_:x') (_:y') = dropLengthMaybe x' y' -- -- >>> isInfixOf "Haskell" "I really like Haskell." -- True --- -- >>> isInfixOf "Ial" "I really like Haskell." -- False +-- +-- For the result to be 'True', the first list must be finite; +-- for the result to be 'False', the second list must be finite: +-- +-- >>> [20..50] `isInfixOf` [0..] +-- True +-- >>> [0..] `isInfixOf` [20..50] +-- False +-- >>> [0..] `isInfixOf` [0..] +-- * Hangs forever * +-- isInfixOf :: (Eq a) => [a] -> [a] -> Bool isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack) @@ -396,6 +427,12 @@ isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack) -- -- >>> nub [1,2,3,4,3,2,1,2,4,3,5] -- [1,2,3,4,5] +-- +-- If the order of outputs does not matter and there exists @instance Ord a@, +-- it's faster to use +-- 'map' @Data.List.NonEmpty.@'Data.List.NonEmpty.head' . @Data.List.NonEmpty.@'Data.List.NonEmpty.group' . 'sort', +-- which takes only \(\mathcal{O}(n \log n)\) time. +-- nub :: (Eq a) => [a] -> [a] nub = nubBy (==) @@ -454,56 +491,103 @@ deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys -- | The '\\' function is list difference (non-associative). -- In the result of @xs@ '\\' @ys@, the first occurrence of each element of -- @ys@ in turn (if any) has been removed from @xs at . Thus --- --- > (xs ++ ys) \\ xs == ys. +-- @(xs ++ ys) \\\\ xs == ys at . -- -- >>> "Hello World!" \\ "ell W" -- "Hoorld!" -- -- It is a special case of 'deleteFirstsBy', which allows the programmer -- to supply their own equality test. - +-- +-- The second list must be finite, but the first may be infinite. +-- +-- >>> take 5 ([0..] \\ [2..4]) +-- [0,1,5,6,7] +-- >>> take 5 ([0..] \\ [2..]) +-- * Hangs forever * +-- (\\) :: (Eq a) => [a] -> [a] -> [a] (\\) = foldl (flip delete) -- | The 'union' function returns the list union of the two lists. +-- It is a special case of 'unionBy', which allows the programmer to supply +-- their own equality test. -- For example, -- -- >>> "dog" `union` "cow" -- "dogcw" -- --- Duplicates, and elements of the first list, are removed from the --- the second list, but if the first list contains duplicates, so will --- the result. --- It is a special case of 'unionBy', which allows the programmer to supply --- their own equality test. - +-- If equal elements are present in both lists, an element from the first list +-- will be used. If the second list contains equal elements, only the first one +-- will be retained: +-- +-- >>> import Data.Semigroup +-- >>> union [Arg () "dog"] [Arg () "cow"] +-- [Arg () "dog"] +-- >>> union [] [Arg () "dog", Arg () "cow"] +-- [Arg () "dog"] +-- +-- However if the first list contains duplicates, so will +-- the result: +-- +-- >>> "coot" `union` "duck" +-- "cootduk" +-- >>> "duck" `union` "coot" +-- "duckot" +-- +-- 'union' is productive even if both arguments are infinite. +-- union :: (Eq a) => [a] -> [a] -> [a] union = unionBy (==) -- | The 'unionBy' function is the non-overloaded version of 'union'. +-- Both arguments may be infinite. +-- unionBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] unionBy eq xs ys = xs ++ foldl (flip (deleteBy eq)) (nubBy eq ys) xs -- | The 'intersect' function takes the list intersection of two lists. +-- It is a special case of 'intersectBy', which allows the programmer to +-- supply their own equality test. -- For example, -- -- >>> [1,2,3,4] `intersect` [2,4,6,8] -- [2,4] -- --- If the first list contains duplicates, so will the result. +-- If equal elements are present in both lists, an element from the first list +-- will be used, and all duplicates from the second list quashed: -- --- >>> [1,2,2,3,4] `intersect` [6,4,4,2] --- [2,2,4] +-- >>> import Data.Semigroup +-- >>> intersect [Arg () "dog"] [Arg () "cow", Arg () "cat"] +-- [Arg () "dog"] +-- +-- However if the first list contains duplicates, so will the result. +-- +-- >>> "coot" `intersect` "heron" +-- "oo" +-- >>> "heron" `intersect` "coot" +-- "o" +-- +-- If the second list is infinite, 'intersect' either hangs +-- or returns its first argument in full. Otherwise if the first list +-- is infinite, 'intersect' might be productive: +-- +-- >>> intersect [100..] [0..] +-- [100,101,102,103... +-- >>> intersect [0] [1..] +-- * Hangs forever * +-- >>> intersect [1..] [0] +-- * Hangs forever * +-- >>> intersect (cycle [1..3]) [2] +-- [2,2,2,2... -- --- It is a special case of 'intersectBy', which allows the programmer to --- supply their own equality test. If the element is found in both the first --- and the second list, the element from the first list will be used. - intersect :: (Eq a) => [a] -> [a] -> [a] intersect = intersectBy (==) -- | The 'intersectBy' function is the non-overloaded version of 'intersect'. +-- It is productive for infinite arguments only if the first one +-- is a subset of the second. +-- intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] intersectBy _ [] _ = [] intersectBy _ _ [] = [] @@ -547,6 +631,12 @@ intercalate xs xss = concat (intersperse xs xss) -- -- >>> transpose [[10,11],[20],[],[30,31,32]] -- [[10,20,30],[11,31],[32]] +-- +-- For this reason the outer list must be finite; otherwise 'transpose' hangs: +-- +-- >>> transpose (repeat []) +-- * Hangs forever * +-- transpose :: [[a]] -> [[a]] transpose [] = [] transpose ([] : xss) = transpose xss @@ -681,7 +771,8 @@ insertBy cmp x ys@(y:ys') GT -> y : insertBy cmp x ys' _ -> x : ys --- | The 'maximumBy' function takes a comparison function and a list +-- | The 'maximumBy' function is the non-overloaded version of 'maximum', +-- which takes a comparison function and a list -- and returns the greatest element of the list by the comparison function. -- The list must be finite and non-empty. -- @@ -697,7 +788,8 @@ maximumBy cmp xs = foldl1 maxBy xs GT -> x _ -> y --- | The 'minimumBy' function takes a comparison function and a list +-- | The 'minimumBy' function is the non-overloaded version of 'minimum', +-- which takes a comparison function and a list -- and returns the least element of the list by the comparison function. -- The list must be finite and non-empty. -- @@ -1045,23 +1137,42 @@ unzip7 = foldr (\(a,b,c,d,e,f,g) ~(as,bs,cs,ds,es,fs,gs) -> -- | The 'deleteFirstsBy' function takes a predicate and two lists and -- returns the first list with the first occurrence of each element of --- the second list removed. +-- the second list removed. This is the non-overloaded version of '(\\)'. +-- +-- The second list must be finite, but the first may be infinite. +-- deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] deleteFirstsBy eq = foldl (flip (deleteBy eq)) -- | The 'group' function takes a list and returns a list of lists such -- that the concatenation of the result is equal to the argument. Moreover, --- each sublist in the result contains only equal elements. For example, +-- each sublist in the result is non-empty and all elements are equal +-- to the first one. For example, -- -- >>> group "Mississippi" -- ["M","i","ss","i","ss","i","pp","i"] -- --- It is a special case of 'groupBy', which allows the programmer to supply +-- 'group' is a special case of 'groupBy', which allows the programmer to supply -- their own equality test. +-- +-- It's often preferable to use @Data.List.NonEmpty.@'Data.List.NonEmpty.group', +-- which provides type-level guarantees of non-emptiness of inner lists. +-- group :: Eq a => [a] -> [[a]] group = groupBy (==) -- | The 'groupBy' function is the non-overloaded version of 'group'. +-- +-- When a supplied relation is not transitive, it is important +-- to remember that equality is checked against the first element in the group, +-- not against the nearest neighbour: +-- +-- >>> groupBy (\a b -> b - a < 5) [0..19] +-- [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14],[15,16,17,18,19]] +-- +-- It's often preferable to use @Data.List.NonEmpty.@'Data.List.NonEmpty.groupBy', +-- which provides type-level guarantees of non-emptiness of inner lists. +-- groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy _ [] = [] groupBy eq (x:xs) = (x:ys) : groupBy eq zs @@ -1078,6 +1189,10 @@ groupBy eq (x:xs) = (x:ys) : groupBy eq zs -- -- In particular, -- @inits _|_ = [] : _|_@ +-- +-- 'inits' is semantically equivalent to @'map' 'reverse' . 'scanl' ('flip' (:)) []@, +-- but under the hood uses a queue to amortize costs of 'reverse'. +-- inits :: [a] -> [[a]] inits = map toListSB . scanl' snocSB emptySB {-# NOINLINE inits #-} @@ -1106,6 +1221,12 @@ tails lst = build (\c n -> -- -- >>> subsequences "abc" -- ["","a","b","ab","c","ac","bc","abc"] +-- +-- This function is productive on infinite inputs: +-- +-- >>> take 8 $ subsequences ['a'..] +-- ["","a","b","ab","c","ac","bc","abc"] +-- subsequences :: [a] -> [[a]] subsequences xs = [] : nonEmptySubsequences xs @@ -1124,7 +1245,26 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- >>> permutations "abc" -- ["abc","bac","cba","bca","cab","acb"] +-- +-- The 'permutations' function is maximally lazy: +-- for each @n@, the value of @'permutations' xs@ starts with those permutations +-- that permute @'take' n xs@ and keep @'drop' n xs at . +-- This function is productive on infinite inputs: +-- +-- >>> take 6 $ map (take 3) $ permutations ['a'..] +-- ["abc","bac","cba","bca","cab","acb"] +-- +-- Note that the order of permutations is not lexicographic. +-- It satisfies the following property: +-- +-- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] +-- permutations :: [a] -> [[a]] +-- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 +-- for the analysis of this rather cryptic implementation. +-- Related discussions: +-- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html +-- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html permutations xs0 = xs0 : perms xs0 [] where perms [] _ = [] @@ -1147,12 +1287,22 @@ permutations xs0 = xs0 : perms xs0 [] -- -- >>> sort [1,6,4,3,2,5] -- [1,2,3,4,5,6] +-- +-- The argument must be finite. +-- sort :: (Ord a) => [a] -> [a] -- | The 'sortBy' function is the non-overloaded version of 'sort'. +-- The argument must be finite. -- -- >>> sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] +-- +-- The supplied comparison relation is supposed to be reflexive and antisymmetric, +-- otherwise, e. g., for @\_ _ -> GT@, the ordered list simply does not exist. +-- The relation is also expected to be transitive: if it is not then 'sortBy' +-- might fail to find an ordered permutation, even if it exists. +-- sortBy :: (a -> a -> Ordering) -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) @@ -1310,10 +1460,10 @@ rqpart cmp x (y:ys) rle rgt r = #endif /* USE_REPORT_PRELUDE */ -- | Sort a list by comparing the results of a key function applied to each --- element. @sortOn f@ is equivalent to @sortBy (comparing f)@, but has the +-- element. @'sortOn' f@ is equivalent to @'sortBy' ('comparing' f)@, but has the -- performance advantage of only evaluating @f@ once for each element in the -- input list. This is called the decorate-sort-undecorate paradigm, or --- Schwartzian transform. +-- . -- -- Elements are arranged from lowest to highest, keeping duplicates in -- the order they appeared in the input. @@ -1321,6 +1471,8 @@ rqpart cmp x (y:ys) rle rgt r = -- >>> sortOn fst [(2, "world"), (4, "!"), (1, "Hello")] -- [(1,"Hello"),(2,"world"),(4,"!")] -- +-- The argument must be finite. +-- -- @since 4.8.0.0 sortOn :: Ord b => (a -> b) -> [a] -> [a] sortOn f = @@ -1397,35 +1549,29 @@ unfoldr f b0 = build (\c n -> -- Functions on strings -- | Splits the argument into a list of /lines/ stripped of their terminating --- @\n@ characters. The @\n@ terminator is optional in a final non-empty +-- @\\n@ characters. The @\\n@ terminator is optional in a final non-empty -- line of the argument string. -- -- For example: -- -- >>> lines "" -- empty input contains no lines -- [] --- -- >>> lines "\n" -- single empty line -- [""] --- -- >>> lines "one" -- single unterminated line -- ["one"] --- -- >>> lines "one\n" -- single non-empty line -- ["one"] --- -- >>> lines "one\n\n" -- second line is empty -- ["one",""] --- -- >>> lines "one\ntwo" -- second line is unterminated -- ["one","two"] --- -- >>> lines "one\ntwo\n" -- two non-empty lines -- ["one","two"] -- --- When the argument string is empty, or ends in a @\n@ character, it can be +-- When the argument string is empty, or ends in a @\\n@ character, it can be -- recovered by passing the result of 'lines' to the 'unlines' function. --- Otherwise, 'unlines' appends the missing terminating @\n at . This makes +-- Otherwise, 'unlines' appends the missing terminating @\\n at . This makes -- @unlines . lines@ /idempotent/: -- -- > (unlines . lines) . (unlines . lines) = (unlines . lines) @@ -1443,15 +1589,13 @@ lines s = cons (case break (== '\n') s of where cons ~(h, t) = h : t --- | Appends a @\n@ character to each input string, then concatenates the --- results. Equivalent to @'foldMap' (\s -> s '++' "\n")@. +-- | Appends a @\\n@ character to each input string, then concatenates the +-- results. Equivalent to @'foldMap' (\s -> s '++' "\\n")@. -- -- >>> unlines ["Hello", "World", "!"] -- "Hello\nWorld\n!\n" -- --- = Note --- --- @'unlines' '.' 'lines' '/=' 'id'@ when the input is not @\n at -terminated: +-- Note that @'unlines' '.' 'lines' '/=' 'id'@ when the input is not @\\n at -terminated: -- -- >>> unlines . lines $ "foo\nbar" -- "foo\nbar\n" @@ -1466,10 +1610,14 @@ unlines (l:ls) = l ++ '\n' : unlines ls #endif -- | 'words' breaks a string up into a list of words, which were delimited --- by white space. +-- by white space (as defined by 'isSpace'). This function trims any white spaces +-- at the beginning and at the end. -- -- >>> words "Lorem ipsum\ndolor" -- ["Lorem","ipsum","dolor"] +-- >>> words " foo bar " +-- ["foo","bar"] +-- words :: String -> [String] {-# NOINLINE [1] words #-} words s = case dropWhile {-partain:Char.-}isSpace s of @@ -1491,11 +1639,18 @@ wordsFB c n = go s' -> w `c` go s'' where (w, s'') = break isSpace s' --- | 'unwords' is an inverse operation to 'words'. --- It joins words with separating spaces. +-- | 'unwords' joins words with separating spaces (U+0020 SPACE). -- -- >>> unwords ["Lorem", "ipsum", "dolor"] -- "Lorem ipsum dolor" +-- +-- 'unwords' is neither left nor right inverse of 'words': +-- +-- >>> words (unwords [" "]) +-- [] +-- >>> unwords (words "foo\nbar") +-- "foo bar" +-- unwords :: [String] -> String #if defined(USE_REPORT_PRELUDE) unwords [] = "" ===================================== libraries/base/GHC/List.hs ===================================== @@ -801,8 +801,8 @@ iterate'FB c f x0 = go x0 -- | 'repeat' @x@ is an infinite list, with @x@ the value of every element. -- --- >>> take 20 $ repeat 17 ---[17,17,17,17,17,17,17,17,17... +-- >>> repeat 17 +-- [17,17,17,17,17,17,17,17,17... repeat :: a -> [a] {-# INLINE [0] repeat #-} -- The pragma just gives the rules more chance to fire @@ -839,9 +839,9 @@ replicate n x = take n (repeat x) -- -- >>> cycle [] -- *** Exception: Prelude.cycle: empty list --- >>> take 20 $ cycle [42] +-- >>> cycle [42] -- [42,42,42,42,42,42,42,42,42,42... --- >>> take 20 $ cycle [2, 5, 7] +-- >>> cycle [2, 5, 7] -- [2,5,7,2,5,7,2,5,7,2,5,7... cycle :: HasCallStack => [a] -> [a] cycle [] = errorEmptyList "cycle" @@ -1284,6 +1284,7 @@ notElem x (y:ys)= x /= y && notElem x ys -- | \(\mathcal{O}(n)\). 'lookup' @key assocs@ looks up a key in an association -- list. +-- For the result to be 'Nothing', the list must be finite. -- -- >>> lookup 2 [] -- Nothing @@ -1291,6 +1292,7 @@ notElem x (y:ys)= x /= y && notElem x ys -- Nothing -- >>> lookup 2 [(1, "first"), (2, "second"), (3, "third")] -- Just "second" +-- lookup :: (Eq a) => a -> [(a,b)] -> Maybe b lookup _key [] = Nothing lookup key ((x,y):xys) @@ -1349,8 +1351,8 @@ concat = foldr (++) [] -- >>> ['a', 'b', 'c'] !! (-1) -- *** Exception: Prelude.!!: negative index -- --- WARNING: This function is partial. You can use <'atMay' --- https://hackage.haskell.org/package/safe-0.3.19/docs/Safe.html#v:atMay> +-- WARNING: This function is partial. You can use +-- -- instead. #if defined(USE_REPORT_PRELUDE) (!!) :: [a] -> Int -> a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dce9f320ce7275fa97f49abef604abbc3b0f9a9c...9c099387ae82b7bf91232b714a3d35f429d6ffe3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dce9f320ce7275fa97f49abef604abbc3b0f9a9c...9c099387ae82b7bf91232b714a3d35f429d6ffe3 You're receiving 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 Oct 11 22:04:00 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 18:04:00 -0400 Subject: [Git][ghc/ghc][master] ByteArray# is unlifted, not unboxed Message-ID: <6345e85082ff_1eea6a5143c14273af@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - 1 changed file: - libraries/base/Data/Array/Byte.hs Changes: ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -30,11 +30,11 @@ import GHC.Show (intToDigit) import GHC.ST (ST(..), runST) import GHC.Word (Word8(..)) --- | Boxed wrapper for 'ByteArray#'. +-- | Lifted wrapper for 'ByteArray#'. -- -- Since 'ByteArray#' is an unlifted type and not a member of kind 'Data.Kind.Type', -- things like @[ByteArray#]@ or @IO ByteArray#@ are ill-typed. To work around this --- inconvenience this module provides a standard boxed wrapper, inhabiting 'Data.Kind.Type'. +-- inconvenience this module provides a standard lifted wrapper, inhabiting 'Data.Kind.Type'. -- Clients are expected to use 'ByteArray' in higher-level APIs, -- but wrap and unwrap 'ByteArray' internally as they please -- and use functions from "GHC.Exts". @@ -42,11 +42,11 @@ import GHC.Word (Word8(..)) -- @since 4.17.0.0 data ByteArray = ByteArray ByteArray# --- | Boxed wrapper for 'MutableByteArray#'. +-- | Lifted wrapper for 'MutableByteArray#'. -- -- Since 'MutableByteArray#' is an unlifted type and not a member of kind 'Data.Kind.Type', -- things like @[MutableByteArray#]@ or @IO MutableByteArray#@ are ill-typed. To work around this --- inconvenience this module provides a standard boxed wrapper, inhabiting 'Data.Kind.Type'. +-- inconvenience this module provides a standard lifted wrapper, inhabiting 'Data.Kind.Type'. -- Clients are expected to use 'MutableByteArray' in higher-level APIs, -- but wrap and unwrap 'MutableByteArray' internally as they please -- and use functions from "GHC.Exts". View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3863cb7418b77f3cd49c219f1f42f64efb2cc93 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3863cb7418b77f3cd49c219f1f42f64efb2cc93 You're receiving 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 Oct 12 01:35:17 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 21:35:17 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Extend documentation for Data.List, mostly wrt infinite lists Message-ID: <634619d54d53c_1eea6a5fada5c0144704@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - 09182e7b by Ben Gamari at 2022-10-11T21:35:05-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - ffed413d by Ben Gamari at 2022-10-11T21:35:05-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - 1cee3dc1 by Ben Gamari at 2022-10-11T21:35:05-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - ee99db81 by Ben Gamari at 2022-10-11T21:35:05-04:00 rts: Refactor IPE tracing support - - - - - d6f382b0 by Ben Gamari at 2022-10-11T21:35:05-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 89c7f86a by Ben Gamari at 2022-10-11T21:35:05-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 3fc25b6b by Krzysztof Gogolewski at 2022-10-11T21:35:05-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - + compiler/GHC/StgToCmm/InfoTableProv.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/ghc.cabal.in - libraries/base/Data/Array/Byte.hs - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/Foreign/C/String.hs - libraries/base/GHC/Foreign.hs - + libraries/base/GHC/InfoProv.hsc - libraries/base/GHC/List.hs - libraries/base/GHC/Stack/CCS.hsc - libraries/base/GHC/Stack/CloneStack.hs - libraries/base/base.cabal - rts/IPE.c - rts/IPE.h - rts/RtsStartup.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/include/Cmm.h - rts/include/Rts.h - rts/include/rts/IPE.h - rts/include/stg/MiscClosures.h - rts/include/stg/SMP.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c480bd0a37d192e59b8483cd3eee9b51481cb7ea...3fc25b6bb8688d2e1eddaadad168af2e34860ee6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c480bd0a37d192e59b8483cd3eee9b51481cb7ea...3fc25b6bb8688d2e1eddaadad168af2e34860ee6 You're receiving 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 Oct 12 03:45:29 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 23:45:29 -0400 Subject: [Git][ghc/ghc][master] 6 commits: rts: Add missing declaration of stg_noDuplicate Message-ID: <6346385964e63_1eea6a5face52c1483719@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - + compiler/GHC/StgToCmm/InfoTableProv.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/ghc.cabal.in - libraries/base/Foreign/C/String.hs - libraries/base/GHC/Foreign.hs - + libraries/base/GHC/InfoProv.hsc - libraries/base/GHC/Stack/CCS.hsc - libraries/base/GHC/Stack/CloneStack.hs - libraries/base/base.cabal - rts/IPE.c - rts/IPE.h - rts/RtsStartup.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/include/Cmm.h - rts/include/Rts.h - rts/include/rts/IPE.h - rts/include/stg/MiscClosures.h - rts/include/stg/SMP.h - rts/sm/NonMoving.h - testsuite/tests/profiling/should_run/staticcallstack001.hs - testsuite/tests/profiling/should_run/staticcallstack001.stdout - testsuite/tests/profiling/should_run/staticcallstack002.hs - testsuite/tests/profiling/should_run/staticcallstack002.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3863cb7418b77f3cd49c219f1f42f64efb2cc93...9b572d541d1d356d7836408ffa98a7b300d02174 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3863cb7418b77f3cd49c219f1f42f64efb2cc93...9b572d541d1d356d7836408ffa98a7b300d02174 You're receiving 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 Oct 12 03:46:03 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Oct 2022 23:46:03 -0400 Subject: [Git][ghc/ghc][master] Make Cmm Lint messages use dump style Message-ID: <6346387b35079_1eea6a529f4f8c14891ce@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 1 changed file: - compiler/GHC/Cmm/Lint.hs Changes: ===================================== compiler/GHC/Cmm/Lint.hs ===================================== @@ -50,7 +50,8 @@ cmmLintGraph platform g = runCmmLint platform lintCmmGraph g runCmmLint :: OutputableP Platform a => Platform -> (a -> CmmLint b) -> a -> Maybe SDoc runCmmLint platform l p = case unCL (l p) platform of - Left err -> Just (vcat [text "Cmm lint error:", + Left err -> Just (withPprStyle defaultDumpStyle $ vcat + [text "Cmm lint error:", nest 2 err, text "Program was:", nest 2 (pdoc platform p)]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27978ceb649e929df29a94e98916c341169395af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27978ceb649e929df29a94e98916c341169395af You're receiving 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 Oct 12 06:47:38 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Wed, 12 Oct 2022 02:47:38 -0400 Subject: [Git][ghc/ghc][wip/fragile-T7919] 19 commits: Tidy implicit binds Message-ID: <6346630a7dcc7_1eea6a5face52c1511390@gitlab.mail> Bryan R pushed to branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 5614b0c4 by Bryan Richter at 2022-10-12T09:47:22+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5072e6c34af3e526476b17320614193061845b3b...5614b0c41863ef33f7e8ea42dfeedfe17b09aead -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5072e6c34af3e526476b17320614193061845b3b...5614b0c41863ef33f7e8ea42dfeedfe17b09aead You're receiving 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 Oct 12 06:53:19 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Wed, 12 Oct 2022 02:53:19 -0400 Subject: [Git][ghc/ghc][wip/fragile-T7919] Mark T7919 as fragile Message-ID: <6346645faf3c1_1eea6a529f4f8c15170f5@gitlab.mail> Bryan R pushed to branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC Commits: 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 1 changed file: - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/rts/all.T ===================================== @@ -267,9 +267,13 @@ test('T7815', [ multi_cpu_race, test('ffishutdown', [ignore_stderr, only_ways(['threaded1','threaded2'])], compile_and_run, ['']) -# Times out in ghci way -test('T7919', [when(fast(), skip), omit_ways(['ghci'] + prof_ways)], compile_and_run, - [config.ghc_th_way_flags]) +# Times out in ghci way. +# Also times out on x86_64-linux from time to time. +test('T7919', [ when(fast(), skip) + , omit_ways(['ghci'] + prof_ways) + , when(platform('x86_64-unknown-linux'), fragile(22283)) + ] + , compile_and_run, [config.ghc_th_way_flags]) test('T8035', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64a390d9c57b35edb6e7cf09b9324b43a3d08671 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64a390d9c57b35edb6e7cf09b9324b43a3d08671 You're receiving 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 Oct 12 06:54:46 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 12 Oct 2022 02:54:46 -0400 Subject: [Git][ghc/ghc][wip/T22277] Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <634664b648454_1eea6a5141415174b6@gitlab.mail> Sebastian Graf pushed to branch wip/T22277 at Glasgow Haskell Compiler / GHC Commits: cb2a39c8 by Sebastian Graf at 2022-10-12T08:54:34+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 6 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/SpecConstr.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22277.hs - + testsuite/tests/simplCore/should_compile/T22277.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,13 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind top_lvl env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + , let env' | isTopLevel top_lvl = extendScInScope env (bindersOfBinds binds) + | otherwise = env + -- At top level, scBinds assumes that we've already put all binders into scope; see initScEnv + = scBinds top_lvl env' binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1447,89 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs, body) <- collectBinders rhs + , notNull xs || isJoinId f -- otherwise we destroy sharing of rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds`. +It might be interesting to specialise `f` and `g` for call patterns in `rest`, +but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/T22277.stderr ===================================== @@ -0,0 +1,132 @@ +[1 of 1] Compiling T22277 ( T22277.hs, T22277.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 110, types: 49, coercions: 0, joins: 3/4} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T22277.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule3 = GHC.Types.TrNameS T22277.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T22277.$trModule2 = "T22277"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule1 = GHC.Types.TrNameS T22277.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule + = GHC.Types.Module T22277.$trModule3 T22277.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry2 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry2 = GHC.Types.I# 13# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry1 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry1 = GHC.Types.I# 24# + +-- RHS size: {terms: 89, types: 40, coercions: 0, joins: 3/4} +entry :: Int -> Int +[GblId, + Arity=1, + Str=<1P(SL)>, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 403 0}] +entry + = \ (n :: Int) -> + case n of wild { GHC.Types.I# ds -> + join { + $w$sexit [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int + [LclId[JoinId(1)(Nothing)], Arity=1, Str=] + $w$sexit (ww [OS=OneShot] :: GHC.Prim.Int#) + = join { + $j [Dmd=1C(1,!P(L))] :: [Int] -> Int + [LclId[JoinId(1)(Just [!])], Arity=1, Str=<1L>, Unf=OtherCon []] + $j (arg [OS=OneShot] :: [Int]) + = case GHC.List.$wlenAcc + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 @Int arg (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + 0# + of ww1 + { __DEFAULT -> + GHC.Types.I# (GHC.Prim.+# ww1 ds) + } } in + case GHC.Prim.># 0# ww of { + __DEFAULT -> + letrec { + go3 [Occ=LoopBreaker, Dmd=SC(S,L)] :: GHC.Prim.Int# -> [Int] + [LclId, Arity=1, Str=, Unf=OtherCon []] + go3 + = \ (x :: GHC.Prim.Int#) -> + GHC.Types.: + @Int + (GHC.Types.I# x) + (case GHC.Prim.==# x ww of { + __DEFAULT -> go3 (GHC.Prim.+# x 1#); + 1# -> GHC.Types.[] @Int + }); } in + jump $j (go3 0#); + 1# -> jump $j (GHC.Types.[] @Int) + } } in + joinrec { + $s$wg [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,!P(L))))] + :: Int -> Int -> GHC.Prim.Int# -> Int + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + $s$wg (sc :: Int) (sc1 :: Int) (sc2 :: GHC.Prim.Int#) + = case GHC.Prim.remInt# sc2 2# of { + __DEFAULT -> + case GHC.Prim.># sc2 43# of { + __DEFAULT -> sc; + 1# -> jump $s$wg sc sc1 (GHC.Prim.-# sc2 1#) + }; + 0# -> jump $w$sexit sc2 + }; } in + case ds of ds1 { + __DEFAULT -> jump $s$wg wild wild ds1; + 0# -> jump $s$wg T22277.entry2 T22277.entry1 0# + } + } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -434,3 +437,5 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb2a39c85caf6463c593e9634eb5ed212d0a2774 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb2a39c85caf6463c593e9634eb5ed212d0a2774 You're receiving 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 Oct 12 07:00:02 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 12 Oct 2022 03:00:02 -0400 Subject: [Git][ghc/ghc][wip/T22277] Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <634665f29493d_1eea6a514c81520989@gitlab.mail> Sebastian Graf pushed to branch wip/T22277 at Glasgow Haskell Compiler / GHC Commits: 3ea7c3b7 by Sebastian Graf at 2022-10-12T08:59:55+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 6 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/SpecConstr.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22277.hs - + testsuite/tests/simplCore/should_compile/T22277.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,14 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind top_lvl env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + , let env' | isTopLevel top_lvl = extendScInScope env (bindersOfBinds binds) + | otherwise = env + -- At top level, scBinds assumes that we've already put all binders into scope; see initScEnv + -- , pprTrace "denest" (ppr bndr <+> ppr app $$ ppr binds) True + = scBinds top_lvl env' binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1448,89 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs, body) <- collectBinders rhs + , notNull xs || isJoinId f -- if f is a thunk, we would destroy sharing of rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds` and `f` is not +a thunk. It might be interesting to specialise `f` and `g` for call patterns in +`rest`, but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/T22277.stderr ===================================== @@ -0,0 +1,132 @@ +[1 of 1] Compiling T22277 ( T22277.hs, T22277.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 110, types: 49, coercions: 0, joins: 3/4} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T22277.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule3 = GHC.Types.TrNameS T22277.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T22277.$trModule2 = "T22277"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule1 = GHC.Types.TrNameS T22277.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule + = GHC.Types.Module T22277.$trModule3 T22277.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry2 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry2 = GHC.Types.I# 13# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry1 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry1 = GHC.Types.I# 24# + +-- RHS size: {terms: 89, types: 40, coercions: 0, joins: 3/4} +entry :: Int -> Int +[GblId, + Arity=1, + Str=<1P(SL)>, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 403 0}] +entry + = \ (n :: Int) -> + case n of wild { GHC.Types.I# ds -> + join { + $w$sexit [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int + [LclId[JoinId(1)(Nothing)], Arity=1, Str=] + $w$sexit (ww [OS=OneShot] :: GHC.Prim.Int#) + = join { + $j [Dmd=1C(1,!P(L))] :: [Int] -> Int + [LclId[JoinId(1)(Just [!])], Arity=1, Str=<1L>, Unf=OtherCon []] + $j (arg [OS=OneShot] :: [Int]) + = case GHC.List.$wlenAcc + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 @Int arg (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + 0# + of ww1 + { __DEFAULT -> + GHC.Types.I# (GHC.Prim.+# ww1 ds) + } } in + case GHC.Prim.># 0# ww of { + __DEFAULT -> + letrec { + go3 [Occ=LoopBreaker, Dmd=SC(S,L)] :: GHC.Prim.Int# -> [Int] + [LclId, Arity=1, Str=, Unf=OtherCon []] + go3 + = \ (x :: GHC.Prim.Int#) -> + GHC.Types.: + @Int + (GHC.Types.I# x) + (case GHC.Prim.==# x ww of { + __DEFAULT -> go3 (GHC.Prim.+# x 1#); + 1# -> GHC.Types.[] @Int + }); } in + jump $j (go3 0#); + 1# -> jump $j (GHC.Types.[] @Int) + } } in + joinrec { + $s$wg [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,!P(L))))] + :: Int -> Int -> GHC.Prim.Int# -> Int + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + $s$wg (sc :: Int) (sc1 :: Int) (sc2 :: GHC.Prim.Int#) + = case GHC.Prim.remInt# sc2 2# of { + __DEFAULT -> + case GHC.Prim.># sc2 43# of { + __DEFAULT -> sc; + 1# -> jump $s$wg sc sc1 (GHC.Prim.-# sc2 1#) + }; + 0# -> jump $w$sexit sc2 + }; } in + case ds of ds1 { + __DEFAULT -> jump $s$wg wild wild ds1; + 0# -> jump $s$wg T22277.entry2 T22277.entry1 0# + } + } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -434,3 +437,5 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ea7c3b7e7fc06c706202c468b9026bc3ca568cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ea7c3b7e7fc06c706202c468b9026bc3ca568cc You're receiving 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 Oct 12 07:46:21 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 12 Oct 2022 03:46:21 -0400 Subject: [Git][ghc/ghc][wip/T21470] 20 commits: Tidy implicit binds Message-ID: <634670cd58cd3_1eea6a5fc830fc15406f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21470 at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - d2487d94 by Simon Peyton Jones at 2022-10-12T08:48:17+01:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - faa99048 by Simon Peyton Jones at 2022-10-12T08:48:17+01:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f74984fa4d46793e3d5d03a5266e25aaf5b1cf2b...faa9904866396b129651e359be6f86c69bfd4377 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f74984fa4d46793e3d5d03a5266e25aaf5b1cf2b...faa9904866396b129651e359be6f86c69bfd4377 You're receiving 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 Oct 12 07:49:12 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 12 Oct 2022 03:49:12 -0400 Subject: [Git][ghc/ghc][wip/T21851] 11 commits: Extend documentation for Data.List, mostly wrt infinite lists Message-ID: <63467178bec8d_1eea6a529f4f64154356f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21851 at Glasgow Haskell Compiler / GHC Commits: da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - a45d8e6f by Simon Peyton Jones at 2022-10-12T08:51:10+01:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Core.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Main.hs - + compiler/GHC/StgToCmm/InfoTableProv.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/GHC/Unit/External.hs - compiler/ghc.cabal.in - libraries/base/Data/Array/Byte.hs - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/Foreign/C/String.hs - libraries/base/GHC/Foreign.hs - + libraries/base/GHC/InfoProv.hsc - libraries/base/GHC/List.hs - libraries/base/GHC/Real.hs - libraries/base/GHC/Stack/CCS.hsc - libraries/base/GHC/Stack/CloneStack.hs - libraries/base/base.cabal The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a90f5f76355ab122de705f0a87e40483ea1133f...a45d8e6f09d21f22dc13abb44b360a5304f61590 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a90f5f76355ab122de705f0a87e40483ea1133f...a45d8e6f09d21f22dc13abb44b360a5304f61590 You're receiving 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 Oct 12 09:48:13 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 05:48:13 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: rts: Add missing declaration of stg_noDuplicate Message-ID: <63468d5d4d059_1eea6a514c8159267a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 8b4b224a by Ben Gamari at 2022-10-12T05:47:56-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Main.hs - + compiler/GHC/StgToCmm/InfoTableProv.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/ghc.cabal.in - libraries/base/Foreign/C/String.hs - libraries/base/GHC/Foreign.hs - + libraries/base/GHC/InfoProv.hsc - libraries/base/GHC/Stack/CCS.hsc - libraries/base/GHC/Stack/CloneStack.hs - libraries/base/base.cabal - rts/IPE.c - rts/IPE.h - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/include/Cmm.h - rts/include/Rts.h - rts/include/rts/IPE.h - rts/include/stg/MiscClosures.h - rts/include/stg/SMP.h - rts/sm/NonMoving.h - testsuite/tests/profiling/should_run/staticcallstack001.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3fc25b6bb8688d2e1eddaadad168af2e34860ee6...8b4b224a3770669e1c49f7425283322bfaa11332 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3fc25b6bb8688d2e1eddaadad168af2e34860ee6...8b4b224a3770669e1c49f7425283322bfaa11332 You're receiving 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 Oct 12 10:15:50 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 06:15:50 -0400 Subject: [Git][ghc/ghc][wip/21619] Fix nested type splices in hie files Message-ID: <634693d68fc_1eea6a529f4f64160833e@gitlab.mail> Matthew Pickering pushed to branch wip/21619 at Glasgow Haskell Compiler / GHC Commits: 941a8014 by Matthew Pickering at 2022-10-12T11:15:32+01:00 Fix nested type splices in hie files The issue is that when we compile a typed bracket we replace the splice with HsSpliced (unTypeCode ...). Then when computing types for > [|| T $$(...) ||] GHC is asked to compute the type of `T $$(..)`, which panics because of the bogus type of T applied to `HsSpliced`, which is not type correct. The fix is to not attempt to compute the type for `HsSpliceE` constructors if we come across them as they should have either been already evaluated or lifted into a splice environment. As part of the patch I made hie files traverse into the splice environments so now we also get type information for things used inside nested splices. Fixes #21619 - - - - - 9 changed files: - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Tc/Gen/Splice.hs - testsuite/tests/hiefile/should_compile/all.T - + testsuite/tests/hiefile/should_compile/hie011.hs - + testsuite/tests/hiefile/should_compile/hie011.stderr - + testsuite/tests/hiefile/should_run/SpliceTypes.hs - + testsuite/tests/hiefile/should_run/SpliceTypes.stdout - testsuite/tests/hiefile/should_run/all.T Changes: ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -131,11 +131,11 @@ hsExprType (ArithSeq _ mb_overloaded_op asi) = case mb_overloaded_op of asi_ty = arithSeqInfoType asi hsExprType (HsTypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType (HsUntypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty +-- This is ugly but HsSpliced things here are not real, they are inserted +-- by GHC.Tc.Gen.Splice as an application of unType applied to the original expression. +--hsExprType (HsSpliceE _ (HsSpliced _ _ (HsSplicedExpr (HsApp _ _e1 e2)))) = pprTrace "loc" callStackDoc $ pprTraceIt "ty" $ lhsExprType e2 hsExprType e@(HsSpliceE{}) = pprPanic "hsExprType: Unexpected HsSpliceE" (ppr e) - -- Typed splices should have been eliminated during zonking, but we - -- can't use `dataConCantHappen` since they are still present before - -- than in the typechecked AST. hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top hsExprType (HsStatic (_, ty) _s) = ty hsExprType (HsPragE _ _ e) = lhsExprType e ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -744,6 +744,9 @@ instance HiePass p => HasType (LocatedA (HsExpr (GhcPass p))) where RecordCon con_expr _ _ -> computeType con_expr ExprWithTySig _ e _ -> computeLType e HsPragE _ _ e -> computeLType e + -- By this point all splices are lifted into splice environments so + -- the remainins HsSpliceE in the syntax tree contain bogus information. + HsSpliceE {} -> Nothing XExpr (ExpansionExpr (HsExpanded (HsGetField _ _ _) e)) -> Just (hsExprType e) -- for record-dot-syntax XExpr (ExpansionExpr (HsExpanded _ e)) -> computeType e XExpr (HsTick _ e) -> computeLType e @@ -1873,10 +1876,10 @@ instance ToHie (HsQuote a) where toHie _ = pure [] instance ToHie PendingRnSplice where - toHie _ = pure [] + toHie (PendingRnSplice _ _ e) = toHie e instance ToHie PendingTcSplice where - toHie _ = pure [] + toHie (PendingTcSplice _ e) = toHie e instance ToHie (LBooleanFormula (LocatedN Name)) where toHie (L span form) = concatM $ makeNode form (locA span) : case form of ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -652,6 +652,7 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl -- But we still return a plausible expression -- (a) in case we print it in debug messages, and -- (b) because we test whether it is tagToEnum in Tc.Gen.Expr.tcApp + -- (c) because we use it to compute a type in hsExprType ; return (HsSpliceE noAnn $ HsSpliced noExtField (ThModFinalizers []) $ HsSplicedExpr (unLoc expr'')) } ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -16,6 +16,7 @@ test('hie007', normal, compile, ['-fno-code -fwrite-ide- test('hie008', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie009', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie010', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) +test('hie011', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('CPP', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Constructors', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Scopes', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/hiefile/should_compile/hie011.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fwrite-ide-info #-} +module M where + +import Language.Haskell.TH.Syntax + +newtype T = T { getT :: Int } + +instance Lift T where + lift = undefined + liftTyped v = [||T $$(liftTyped (getT v))||] + + +top_level :: () +top_level = $$([|| () ||]) ===================================== testsuite/tests/hiefile/should_compile/hie011.stderr ===================================== @@ -0,0 +1,2 @@ +Got valid scopes +Got no roundtrip errors ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import TestUtils +import qualified Data.Map as M +import Data.Foldable +import Language.Haskell.TH.Syntax + + +newtype T = T { getT :: Int } + +instance Lift T where + liftTyped v = [||T $$(liftTyped (getT v))||] +-- ^ ^ ^ ^ ^ +-- 1 2 3 4 5 +-- + +top_level :: () +top_level = $$([|| () ||]) +-- ^ ^ +-- 1 2 + +p1,p2, p3, p4:: (Int,Int) +p1 = (14,18) +p2 = (14,21) +p3 = (14,24) +p4 = (14,29) +p5 = (14,41) + +q1 = (20, 19) +q2 = (20, 21) + +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc + +main = do + (df, hf) <- readTestHie "SpliceTypes.hie" + forM_ [p1,p2,p3, p4, p5, q1, q2] $ \point -> do + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point + case types of + [] -> putStrLn $ "No types at " ++ show point + _ -> do + putStr $ "At " ++ show point ++ ", got type: " + forM_ types $ \typ -> do + putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.stdout ===================================== @@ -0,0 +1,9 @@ +No types at (14,18) +At (14,21), got type: Int -> T +No types at (14,24) +At (14,29), got type: Int -> Code m Int +forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t +forall (m :: * -> *). Quote m => Int -> Code m Int +At (14,41), got type: T +No types at (20,19) +No types at (20,21) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -2,3 +2,4 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, [ test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('T20341', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('RecordDotTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('SpliceTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/941a80140c984404331d0797818f9000f8532a2f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/941a80140c984404331d0797818f9000f8532a2f You're receiving 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 Oct 12 10:17:52 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 06:17:52 -0400 Subject: [Git][ghc/ghc][wip/21619] Fix nested type splices in hie files Message-ID: <63469450afc92_1eea6a51414161039d@gitlab.mail> Matthew Pickering pushed to branch wip/21619 at Glasgow Haskell Compiler / GHC Commits: 96e5aa44 by Matthew Pickering at 2022-10-12T11:17:46+01:00 Fix nested type splices in hie files The issue is that when we compile a typed bracket we replace the splice with HsSpliced (unTypeCode ...). Then when computing types for > [|| T $$(...) ||] GHC is asked to compute the type of `T $$(..)`, which panics because of the bogus type of T applied to `HsSpliced`, which is not type correct. The fix is to not attempt to compute the type for `HsSpliceE` constructors if we come across them as they should have either been already evaluated or lifted into a splice environment. As part of the patch I made hie files traverse into the splice environments so now we also get type information for things used inside nested splices. Fixes #21619 - - - - - 8 changed files: - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Iface/Ext/Ast.hs - testsuite/tests/hiefile/should_compile/all.T - + testsuite/tests/hiefile/should_compile/hie011.hs - + testsuite/tests/hiefile/should_compile/hie011.stderr - + testsuite/tests/hiefile/should_run/SpliceTypes.hs - + testsuite/tests/hiefile/should_run/SpliceTypes.stdout - testsuite/tests/hiefile/should_run/all.T Changes: ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -133,9 +133,9 @@ hsExprType (HsTypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType (HsUntypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType e@(HsSpliceE{}) = pprPanic "hsExprType: Unexpected HsSpliceE" (ppr e) - -- Typed splices should have been eliminated during zonking, but we - -- can't use `dataConCantHappen` since they are still present before - -- than in the typechecked AST. + -- Typed splices should have been eliminated during zonking, but we + -- can't use `dataConCantHappen` since they are still present before + -- than in the typechecked AST hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top hsExprType (HsStatic (_, ty) _s) = ty hsExprType (HsPragE _ _ e) = lhsExprType e ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -744,6 +744,9 @@ instance HiePass p => HasType (LocatedA (HsExpr (GhcPass p))) where RecordCon con_expr _ _ -> computeType con_expr ExprWithTySig _ e _ -> computeLType e HsPragE _ _ e -> computeLType e + -- By this point all splices are lifted into splice environments so + -- the remainins HsSpliceE in the syntax tree contain bogus information. + HsSpliceE {} -> Nothing XExpr (ExpansionExpr (HsExpanded (HsGetField _ _ _) e)) -> Just (hsExprType e) -- for record-dot-syntax XExpr (ExpansionExpr (HsExpanded _ e)) -> computeType e XExpr (HsTick _ e) -> computeLType e @@ -1873,10 +1876,10 @@ instance ToHie (HsQuote a) where toHie _ = pure [] instance ToHie PendingRnSplice where - toHie _ = pure [] + toHie (PendingRnSplice _ _ e) = toHie e instance ToHie PendingTcSplice where - toHie _ = pure [] + toHie (PendingTcSplice _ e) = toHie e instance ToHie (LBooleanFormula (LocatedN Name)) where toHie (L span form) = concatM $ makeNode form (locA span) : case form of ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -16,6 +16,7 @@ test('hie007', normal, compile, ['-fno-code -fwrite-ide- test('hie008', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie009', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie010', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) +test('hie011', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('CPP', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Constructors', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Scopes', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/hiefile/should_compile/hie011.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fwrite-ide-info #-} +module M where + +import Language.Haskell.TH.Syntax + +newtype T = T { getT :: Int } + +instance Lift T where + lift = undefined + liftTyped v = [||T $$(liftTyped (getT v))||] + + +top_level :: () +top_level = $$([|| () ||]) ===================================== testsuite/tests/hiefile/should_compile/hie011.stderr ===================================== @@ -0,0 +1,2 @@ +Got valid scopes +Got no roundtrip errors ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import TestUtils +import qualified Data.Map as M +import Data.Foldable +import Language.Haskell.TH.Syntax + + +newtype T = T { getT :: Int } + +instance Lift T where + liftTyped v = [||T $$(liftTyped (getT v))||] +-- ^ ^ ^ ^ ^ +-- 1 2 3 4 5 +-- + +top_level :: () +top_level = $$([|| () ||]) +-- ^ ^ +-- 1 2 + +p1,p2, p3, p4:: (Int,Int) +p1 = (14,18) +p2 = (14,21) +p3 = (14,24) +p4 = (14,29) +p5 = (14,41) + +q1 = (20, 19) +q2 = (20, 21) + +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc + +main = do + (df, hf) <- readTestHie "SpliceTypes.hie" + forM_ [p1,p2,p3, p4, p5, q1, q2] $ \point -> do + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point + case types of + [] -> putStrLn $ "No types at " ++ show point + _ -> do + putStr $ "At " ++ show point ++ ", got type: " + forM_ types $ \typ -> do + putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.stdout ===================================== @@ -0,0 +1,9 @@ +No types at (14,18) +At (14,21), got type: Int -> T +No types at (14,24) +At (14,29), got type: Int -> Code m Int +forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t +forall (m :: * -> *). Quote m => Int -> Code m Int +At (14,41), got type: T +No types at (20,19) +No types at (20,21) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -2,3 +2,4 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, [ test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('T20341', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('RecordDotTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('SpliceTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96e5aa44da9308bf0f474b1ba1601be21c672905 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96e5aa44da9308bf0f474b1ba1601be21c672905 You're receiving 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 Oct 12 10:37:40 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 06:37:40 -0400 Subject: [Git][ghc/ghc][wip/andreask/testsuite-tntc] 82 commits: Tag inference: Fix #21954 by retaining tagsigs of vars in function position. Message-ID: <634698f45aa6b_1eea6a529f4f6416274c0@gitlab.mail> Matthew Pickering pushed to branch wip/andreask/testsuite-tntc at Glasgow Haskell Compiler / GHC Commits: d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - c71f5ce9 by Andreas Klebinger at 2022-10-12T11:36:33+01:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/CFG/Dominators.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/52f472b0691faba5170156898d57f9567bf7c214...c71f5ce96c844a37581bc6a230892a3ce580c8d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/52f472b0691faba5170156898d57f9567bf7c214...c71f5ce96c844a37581bc6a230892a3ce580c8d2 You're receiving 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 Oct 12 11:09:16 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 07:09:16 -0400 Subject: [Git][ghc/ghc][wip/test-speed-ci] 217 commits: Note [Trimming auto-rules]: State that this improves compiler perf. Message-ID: <6346a05cd2bc6_1eea6a5143c163962f@gitlab.mail> Matthew Pickering pushed to branch wip/test-speed-ci at Glasgow Haskell Compiler / GHC Commits: 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - ad04f37c by Ben Gamari at 2022-10-12T12:06:02+01:00 gitlab-ci: Add support for test speed - - - - - 7f5b56f3 by Ben Gamari at 2022-10-12T12:08:23+01:00 gitlab-ci: Use slow test speed in debug job - - - - - 4ef98eeb by Ben Gamari at 2022-10-12T12:08:25+01:00 testsuite: ds014 is not longer broken It now appears to pass in the ways it was marked as broken in. Closes #14901. - - - - - 8ad494a5 by Ben Gamari at 2022-10-12T12:08:25+01:00 testsuite: Overflow test is not longer broken in hpc way Closes #16543. - - - - - c574c9ff by Ben Gamari at 2022-10-12T12:08:25+01:00 testsuite: T4012 is not longer broken in ghci way Fixed by !6904. Closes #7388. - - - - - 3e372073 by Ben Gamari at 2022-10-12T12:08:25+01:00 testsuite: T9646 is no longer broken in ghci way Perhaps due to the recent improvements in GHCi's unboxed tuple support? Closes #9646 - - - - - 4669ad49 by Ben Gamari at 2022-10-12T12:08:57+01:00 testsuite: Only run stack cloning tests in the normal way These are too dependent upon code generation specifics to pass in most other ways. - - - - - 30 changed files: - − .appveyor.sh - .editorconfig - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Liveness.hs - compiler/GHC/Cmm/Node.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9d7c67b986b58b68c286eac274b5b97d339b1cf...4669ad4950491db410acbe510129cd852730a071 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9d7c67b986b58b68c286eac274b5b97d339b1cf...4669ad4950491db410acbe510129cd852730a071 You're receiving 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 Oct 12 11:18:20 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 12 Oct 2022 07:18:20 -0400 Subject: [Git][ghc/ghc][wip/T22277] Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <6346a27c4aa14_1eea6a5fc830fc16427b2@gitlab.mail> Sebastian Graf pushed to branch wip/T22277 at Glasgow Haskell Compiler / GHC Commits: f4bfd14b by Sebastian Graf at 2022-10-12T13:15:31+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 6 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/SpecConstr.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22277.hs - + testsuite/tests/simplCore/should_compile/T22277.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,15 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind NotTopLevel env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + -- We don't denest at the top-level, because we will extend the substitution + -- and top-level binders have already been put into scope and (had their + -- unfoldings!) substituted due to Note [Glomming], so we wouldn't be able + -- to discard the NonRec. + -- , pprTrace "denest" (ppr bndr <+> ppr app $$ ppr binds) True + = scBinds NotTopLevel env binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1449,88 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs@(_:_), body) <- collectBinders rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds` and `xs` is +not empty. It might be interesting to specialise `f` and `g` for call patterns +in `rest`, but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` (hence `xs` non-empty) + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/T22277.stderr ===================================== @@ -0,0 +1,132 @@ +[1 of 1] Compiling T22277 ( T22277.hs, T22277.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 110, types: 49, coercions: 0, joins: 3/4} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T22277.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule3 = GHC.Types.TrNameS T22277.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T22277.$trModule2 = "T22277"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule1 = GHC.Types.TrNameS T22277.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule + = GHC.Types.Module T22277.$trModule3 T22277.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry2 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry2 = GHC.Types.I# 13# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry1 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry1 = GHC.Types.I# 24# + +-- RHS size: {terms: 89, types: 40, coercions: 0, joins: 3/4} +entry :: Int -> Int +[GblId, + Arity=1, + Str=<1P(SL)>, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 403 0}] +entry + = \ (n :: Int) -> + case n of wild { GHC.Types.I# ds -> + join { + $w$sexit [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int + [LclId[JoinId(1)(Nothing)], Arity=1, Str=] + $w$sexit (ww [OS=OneShot] :: GHC.Prim.Int#) + = join { + $j [Dmd=1C(1,!P(L))] :: [Int] -> Int + [LclId[JoinId(1)(Just [!])], Arity=1, Str=<1L>, Unf=OtherCon []] + $j (arg [OS=OneShot] :: [Int]) + = case GHC.List.$wlenAcc + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 @Int arg (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + 0# + of ww1 + { __DEFAULT -> + GHC.Types.I# (GHC.Prim.+# ww1 ds) + } } in + case GHC.Prim.># 0# ww of { + __DEFAULT -> + letrec { + go3 [Occ=LoopBreaker, Dmd=SC(S,L)] :: GHC.Prim.Int# -> [Int] + [LclId, Arity=1, Str=, Unf=OtherCon []] + go3 + = \ (x :: GHC.Prim.Int#) -> + GHC.Types.: + @Int + (GHC.Types.I# x) + (case GHC.Prim.==# x ww of { + __DEFAULT -> go3 (GHC.Prim.+# x 1#); + 1# -> GHC.Types.[] @Int + }); } in + jump $j (go3 0#); + 1# -> jump $j (GHC.Types.[] @Int) + } } in + joinrec { + $s$wg [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,!P(L))))] + :: Int -> Int -> GHC.Prim.Int# -> Int + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + $s$wg (sc :: Int) (sc1 :: Int) (sc2 :: GHC.Prim.Int#) + = case GHC.Prim.remInt# sc2 2# of { + __DEFAULT -> + case GHC.Prim.># sc2 43# of { + __DEFAULT -> sc; + 1# -> jump $s$wg sc sc1 (GHC.Prim.-# sc2 1#) + }; + 0# -> jump $w$sexit sc2 + }; } in + case ds of ds1 { + __DEFAULT -> jump $s$wg wild wild ds1; + 0# -> jump $s$wg T22277.entry2 T22277.entry1 0# + } + } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -434,3 +437,5 @@ test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4bfd14be676e75c6b126721251097524fd83d46 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4bfd14be676e75c6b126721251097524fd83d46 You're receiving 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 Oct 12 11:26:18 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 12 Oct 2022 07:26:18 -0400 Subject: [Git][ghc/ghc][wip/T22227] 4 commits: Denest NonRecs in SpecConstr for more specialisation (#22277) Message-ID: <6346a45abccb2_1eea6a5fada5c016450fd@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: f4bfd14b by Sebastian Graf at 2022-10-12T13:15:31+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. - - - - - 1b814e02 by Sebastian Graf at 2022-10-12T13:15:32+02:00 Loopification in OccurAnal (#22227, #14068) - - - - - b00847e9 by Sebastian Graf at 2022-10-12T13:15:32+02:00 Do join point loopification only pre-simplification - - - - - 31c14aed by Sebastian Graf at 2022-10-12T13:15:32+02:00 DmdAnal: Look through DataConWrappers (#22241) - - - - - 15 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - testsuite/tests/linear/should_compile/LinearLetRec.hs - + testsuite/tests/simplCore/should_compile/T14951.hs - + testsuite/tests/simplCore/should_compile/T22227.hs - + testsuite/tests/simplCore/should_compile/T22227.stderr - + testsuite/tests/simplCore/should_compile/T22277.hs - + testsuite/tests/simplCore/should_compile/T22277.stderr - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/T5075.hs - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -41,7 +41,7 @@ module GHC.Core ( isId, cmpAltCon, cmpAlt, ltAlt, -- ** Simple 'Expr' access functions and predicates - bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, collectLets, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1940,6 +1940,15 @@ flattenBinds (NonRec b r : binds) = (b,r) : flattenBinds binds flattenBinds (Rec prs1 : binds) = prs1 ++ flattenBinds binds flattenBinds [] = [] +-- | We often want to strip off leading 'Let's before getting down to +-- business. The inverse of 'mkLets'. +collectLets :: Expr b -> ([Bind b], Expr b) +collectLets expr + = go [] expr + where + go bs (Let b e) = go (b:bs) e + go bs e = (reverse bs, e) + -- | We often want to strip off leading lambdas before getting down to -- business. Variants are 'collectTyBinders', 'collectValBinders', -- and 'collectTyAndValBinders' @@ -1957,7 +1966,7 @@ collectBinders expr = go [] expr where go bs (Lam b e) = go (b:bs) e - go bs e = (reverse bs, e) + go bs e = (reverse bs, e) collectTyBinders expr = go [] expr ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,9 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -58,7 +58,44 @@ import GHC.Utils.Trace import GHC.Builtin.Names( runRWKey ) import GHC.Unit.Module( Module ) -import Data.List (mapAccumL, mapAccumR) +import Data.List (mapAccumL, mapAccumR, find) + +{- +************************************************************************ +* * + OccurAnalConfig +* * +************************************************************************ +-} + +data OccurAnalConfig + = OAC { oac_unf_act :: !(Id -> Bool) -- ^ Which Id unfoldings are active + , oac_rule_act :: !(Activation -> Bool) -- ^ Which rules are active + -- See Note [Finding rule RHS free vars] + , oac_loopify :: !Bool -- ^ Do loopification? + -- See Note [Join point loopification] + } + +pureOccurAnalConfig :: OccurAnalConfig +pureOccurAnalConfig + -- Used in the pure 'occurAnalyseExpr'. + -- To be conservative, we say that all + -- inlines and rules are active and that + -- loopification is deactivated + = OAC { oac_unf_act = \_ -> True + , oac_rule_act = \_ -> True + , oac_loopify = False + } + +fullOccurAnalConfig :: (Id -> Bool) -> (Activation -> Bool) -> OccurAnalConfig +fullOccurAnalConfig active_unf active_rule + -- Used in the full, pre-Simplification 'occurAnalysePgm'. + -- There we know the precise unfolding and rule activation + -- and we want loopification to happen. + = OAC { oac_unf_act = active_unf + , oac_rule_act = active_rule + , oac_loopify = True + } {- ************************************************************************ @@ -74,7 +111,7 @@ Here's the externally-callable interface: occurAnalyseExpr :: CoreExpr -> CoreExpr occurAnalyseExpr expr = expr' where - (WithUsageDetails _ expr') = occAnal initOccEnv expr + (WithUsageDetails _ expr') = occAnal (initOccEnv pureOccurAnalConfig) expr occurAnalysePgm :: Module -- Used only in debug output -> (Id -> Bool) -- Active unfoldings @@ -89,8 +126,7 @@ occurAnalysePgm this_mod active_unf active_rule imp_rules binds = warnPprTrace True "Glomming in" (hang (ppr this_mod <> colon) 2 (ppr final_usage)) occ_anald_glommed_binds where - init_env = initOccEnv { occ_rule_act = active_rule - , occ_unf_act = active_unf } + init_env = initOccEnv (fullOccurAnalConfig active_unf active_rule) (WithUsageDetails final_usage occ_anald_binds) = go init_env binds (WithUsageDetails _ occ_anald_glommed_binds) = occAnalRecBind init_env TopLevel @@ -856,15 +892,33 @@ occAnalRec !_ lvl (AcyclicSCC (ND { nd_bndr = bndr, nd_rhs = rhs -- See Note [Recursive bindings: the grand plan] -- See Note [Loop breaking] occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails body_uds binds) - | not (any (`usedIn` body_uds) bndrs) -- NB: look at body_uds, not total_uds + | null used_bndrs = WithUsageDetails body_uds binds -- See Note [Dead code] + | oac_loopify (occ_config env) -- Check for Note [Join point loopification] + , [loop_entry] <- used_bndrs + , not (isJoinId loop_entry) + , let loop_occ = lookupDetails body_uds loop_entry + , NoTailCallInfo <- tailCallInfo loop_occ -- otherwise turn it into a joinrec rightaway + , case loop_occ of OneOcc{occ_int_cxt=int} -> int == IsInteresting; _ -> True -- otherwise loop_entry is not applied and there is no point. also trouble with CorePrep in andy_cherry: f (letrec match ... in match) + , let unadj_uds = foldr (andUDs . nd_uds) emptyDetails details_s + , decideJoinPointHood lvl unadj_uds bndrs + , AlwaysTailCalled arity <- tailCallInfo $ lookupDetails unadj_uds loop_entry + , Just loop_nds <- find ((== loop_entry) . nd_bndr) details_s + , (!lam_bndrs,_) <- collectNBinders arity (nd_rhs loop_nds) + , let !loop_body_uds = mkOneOcc loop_entry IsInteresting arity + , WithUsageDetails new_rhs_uds loop_binds <- occAnalRec env lvl (CyclicSCC details_s) (WithUsageDetails loop_body_uds []) + , (body_uds',loop_entry') <- tagNonRecBinder lvl body_uds loop_entry + , let new_bind = NonRec loop_entry' (mkLams lam_bndrs (mkLets loop_binds (mkVarApps (Var loop_entry') lam_bndrs))) + = WithUsageDetails (markAllNonTail new_rhs_uds `andUDs` body_uds') (new_bind : binds) + | otherwise -- At this point we always build a single Rec = -- pprTrace "occAnalRec" (ppr loop_breaker_nodes) WithUsageDetails final_uds (Rec pairs : binds) where bndrs = map nd_bndr details_s + used_bndrs = filter (`usedIn` body_uds) bndrs -- NB: look at body_uds, not total_uds all_simple = all nd_simple details_s ------------------------------ @@ -1433,7 +1487,7 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs) (WithUsageDetails unf_uds unf') = occAnalUnfolding rhs_env Recursive mb_join_arity unf --------- IMP-RULES -------- - is_active = occ_rule_act env :: Activation -> Bool + is_active = oac_rule_act (occ_config env) :: Activation -> Bool imp_rule_info = lookupImpRules imp_rule_edges bndr imp_rule_uds = impRulesScopeUsage imp_rule_info imp_rule_fvs = impRulesActiveFvs is_active bndr_set imp_rule_info @@ -1487,7 +1541,7 @@ mkLoopBreakerNodes !env lvl body_uds details_s -- Note [Deterministic SCC] in GHC.Data.Graph.Directed. where new_nd = nd { nd_bndr = new_bndr, nd_score = score } - score = nodeScore env new_bndr lb_deps nd + score = nodeScore (occ_config env) new_bndr lb_deps nd lb_deps = extendFvs_ rule_fv_env inl_fvs -- See Note [Loop breaker dependencies] @@ -1519,12 +1573,12 @@ group { f1 = e1; ...; fn = en } are: -} ------------------------------------------ -nodeScore :: OccEnv +nodeScore :: OccurAnalConfig -> Id -- Binder with new occ-info -> VarSet -- Loop-breaker dependencies -> Details -> NodeScore -nodeScore !env new_bndr lb_deps +nodeScore !cfg 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 @@ -1533,7 +1587,7 @@ nodeScore !env new_bndr lb_deps | old_bndr `elemVarSet` lb_deps -- Self-recursive things are great loop breakers = (0, 0, True) -- See Note [Self-recursion and loop breakers] - | not (occ_unf_act env old_bndr) -- A binder whose inlining is inactive (e.g. has + | not (oac_unf_act cfg old_bndr) -- A binder whose inlining is inactive (e.g. has = (0, 0, True) -- a NOINLINE pragma) makes a great loop breaker | exprIsTrivial rhs @@ -2454,12 +2508,9 @@ scrutinised y). -} data OccEnv - = OccEnv { occ_encl :: !OccEncl -- Enclosing context information + = OccEnv { occ_config :: !OccurAnalConfig + , occ_encl :: !OccEncl -- Enclosing context information , occ_one_shots :: !OneShots -- See Note [OneShots] - , 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] - -- See Note [The binder-swap substitution] -- If x :-> (y, co) is in the env, -- then please replace x by (y |> sym mco) @@ -2500,18 +2551,13 @@ instance Outputable OccEncl where -- See Note [OneShots] type OneShots = [OneShotInfo] -initOccEnv :: OccEnv -initOccEnv - = OccEnv { occ_encl = OccVanilla +initOccEnv :: OccurAnalConfig -> OccEnv +initOccEnv cfg + = OccEnv { occ_config = cfg + , occ_encl = OccVanilla , occ_one_shots = [] - - -- To be conservative, we say that all - -- inlines and rules are active - , occ_unf_act = \_ -> True - , occ_rule_act = \_ -> True - - , occ_bs_env = emptyVarEnv - , occ_bs_rng = emptyVarSet } + , occ_bs_env = emptyVarEnv + , occ_bs_rng = emptyVarSet } noBinderSwaps :: OccEnv -> Bool noBinderSwaps (OccEnv { occ_bs_env = bs_env }) = isEmptyVarEnv bs_env ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.Core import GHC.Core.Subst import GHC.Core.Utils import GHC.Core.Unfold -import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars ) +import GHC.Core.FVs ( exprsFreeVarsList, exprFreeVars, exprsFreeVars, exprSomeFreeVarsList ) import GHC.Core.Opt.Monad import GHC.Core.Opt.WorkWrap.Utils import GHC.Core.DataCon @@ -52,6 +52,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id import GHC.Types.Id.Info ( IdDetails(..) ) +import GHC.Types.Var ( setIdDetails ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -80,10 +81,11 @@ import GHC.Exts( SpecConstrAnnotation(..) ) import GHC.Serialized ( deserializeWithData ) import Control.Monad ( zipWithM ) -import Data.List (nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) +import Data.List ( nubBy, sortBy, partition, dropWhileEnd, mapAccumL ) import Data.Maybe( mapMaybe ) import Data.Ord( comparing ) import Data.Tuple +import Data.Bifunctor ( first ) {- ----------------------------------------------------- @@ -773,10 +775,21 @@ specConstrProgram guts ; return (guts { mg_binds = binds' }) } scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) -scTopBinds _env [] = return (nullUsage, []) -scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ - (\env -> scTopBinds env bs) - ; return (usg, b' ++ bs') } +scTopBinds env bs = do + (usg, bs, ()) <- scBinds TopLevel env bs (\_env -> return (nullUsage, ())) + return (usg, bs) + +scBinds :: TopLevelFlag -> ScEnv -> [InBind] + -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the bindings + -> UniqSM (ScUsage, [OutBind], a) +scBinds _lvl env [] k = do + (usg, a) <- k env + return (usg, [], a) +scBinds lvl env (b:bs) k = do + (usg, b', (bs', a)) <- scBind lvl env b $ \env -> do + (usg, bs', a) <- scBinds lvl env bs k + return (usg, (bs',a)) + return (usg, b' ++ bs', a) {- ************************************************************************ @@ -1018,6 +1031,9 @@ extendScInScope env qvars extendScSubst :: ScEnv -> Var -> OutExpr -> ScEnv extendScSubst env var expr = env { sc_subst = extendSubst (sc_subst env) var expr } +extendScSubstPre :: ScEnv -> Var -> InExpr -> ScEnv +extendScSubstPre env var expr = extendScSubst env var (substExpr (sc_subst env) expr) + extendScSubstList :: ScEnv -> [(Var,OutExpr)] -> ScEnv extendScSubstList env prs = env { sc_subst = extendSubstList (sc_subst env) prs } @@ -1330,6 +1346,15 @@ creates specialised versions of functions. scBind :: TopLevelFlag -> ScEnv -> InBind -> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> UniqSM (ScUsage, [OutBind], a) +scBind NotTopLevel env (NonRec bndr rhs) do_body + | Just (app, binds) <- denest_nonrec_let (getSubstInScope (sc_subst env)) bndr rhs + -- See Note [Denesting non-recursive let bindings] + -- We don't denest at the top-level, because we will extend the substitution + -- and top-level binders have already been put into scope and (had their + -- unfoldings!) substituted due to Note [Glomming], so we wouldn't be able + -- to discard the NonRec. + -- , pprTrace "denest" (ppr bndr <+> ppr app $$ ppr binds) True + = scBinds NotTopLevel env binds (\env -> do_body $ extendScSubstPre env bndr app) scBind top_lvl env (NonRec bndr rhs) do_body | isTyVar bndr -- Type-lets may be created by doBeta = do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) @@ -1424,8 +1449,88 @@ scBind top_lvl env (Rec prs) do_body rhs_env2 = extendHowBound rhs_env1 bndrs' RecFun -{- Note [Specialising local let bindings] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- | Implements Note [Denesting non-recursive let bindings]. +-- +-- The call `denest_nonrec_let in_scope f (\xs -> let binds in g ys)` returns +-- `Just (\xs -> g' ys, binds')`, where `g'` and `binds'` were stripped of their +-- join-point-ness (if `f` was not a join point itself). +-- The function returns `Nothing` if the code does not match. +-- +-- The `InScopeSet` makes sure that `binds` do not shadow existing bindings +-- that are used in ..., in which case this function will return `Nothing`, too. +denest_nonrec_let :: InScopeSet -> InId -> InExpr -> Maybe (InExpr, [InBind]) +denest_nonrec_let in_scope f rhs + | (xs@(_:_), body) <- collectBinders rhs + , (binds@(_:_), call) <- collectLets body + , (Var g, args) <- collectArgs call + , let bndrs = bindersOfBinds binds + , (g', binds') <- need_zap_join_point_hood f g binds `orElse` (g, binds) + -- expensive tests last: + , bndrs `dont_shadow` in_scope -- floating binds out may not shadow bindings already in scope + , args `exprs_dont_mention` bndrs -- args may not mention binds + , binds `binds_dont_mention` xs -- binds may not mention xs + = Just (mkLams xs $ mkApps (Var g') args, binds') + | otherwise + = Nothing + where + dont_shadow :: [Var] -> InScopeSet -> Bool + dont_shadow bndrs in_scope = + disjointVarSet (getInScopeVars in_scope) (mkVarSet bndrs) + + exprs_dont_mention :: [CoreExpr] -> [Var] -> Bool + exprs_dont_mention exprs vs = + disjointVarSet (exprsFreeVars exprs) (mkVarSet vs) + + binds_dont_mention :: [CoreBind] -> [Var] -> Bool + binds_dont_mention binds vs = + let some_var = head (bindersOfBinds binds) + vs_set = mkVarSet vs + in null $ exprSomeFreeVarsList (`elemVarSet` vs_set) (mkLets binds (Var some_var)) + + need_zap_join_point_hood :: Id -> Id -> [CoreBind] -> Maybe (Id, [CoreBind]) + need_zap_join_point_hood f g binds + | isJoinId f = Nothing -- `f` and `g` share tail context + | not (isJoinId g) = Nothing -- `g` and thus `binds` never were joinpoints to begin with + | otherwise = Just (mark_non_join g, map (map_binders mark_non_join) binds) + + map_binders :: (b -> b) -> Bind b -> Bind b + map_binders f (NonRec b rhs) = NonRec (f b) rhs + map_binders f (Rec prs) = Rec (map (first f) prs) + + mark_non_join :: Id -> Id + mark_non_join id = case idDetails id of + JoinId _ Nothing -> id `setIdDetails` VanillaId + JoinId _ (Just cbv_marks) -> id `setIdDetails` WorkerLikeId cbv_marks + _ -> id + +{- Note [Denesting non-recursive let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we see (local or at top-level) + + f xs = let binds in g as; + rest + +where `xs` don't occur in `binds` and `as` do not mention `binds` and `xs` is +not empty. It might be interesting to specialise `f` and `g` for call patterns +in `rest`, but it is difficult to do it in this nested form, because + + 1. We only get to see `ScrutOcc`s on `g`, in its RHS + 2. The interesting call patterns in `rest` apply only to `f` (hence `xs` non-empty) + 3. Specialising `f` and `g` for those call patterns duplicates `binds` twice: + We keep one copy of `bind` in the original `f`, one copy of `bind` in `$sf` + and another specialised copy `$sbind` (containing `$sg`) in `$sf`. + +So for SpecConstr, we float out `binds` (removing potential join-point-ness) + + binds; + rest[f:=\xs -> g as] + +Because now all call patterns of `f` directly apply to `g` and might match up +with one of the `ScrutOcc`s in its RHS, while only needing a single duplicate of +`bind`. + +Note [Specialising local let bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is not uncommon to find this let $j = \x. in ...$j True...$j True... ===================================== testsuite/tests/linear/should_compile/LinearLetRec.hs ===================================== @@ -8,4 +8,13 @@ extendOrigNameCache _ _ = Name initNameCache :: Int -> [Name] -> NameCache initNameCache us names - = NameCache us (foldl extendOrigNameCache Name names) + = NameCache us (go Name names) + where + -- go will become a join point once $WNameCache inlines. That join point + -- has a nullary exit join point with a problematic linearity. + -- The NOINLINE makes sure that call-site loopification doesn't turn go into + -- a joinrec before $WNameCache inlines + go acc [] = acc + -- head names `seq` ... so that `go` doesn't float to top-level + go acc (n:ns) = head names `seq` go (extendOrigNameCache acc n) ns + {-# NOINLINE go #-} -- see above comment ===================================== testsuite/tests/simplCore/should_compile/T14951.hs ===================================== @@ -0,0 +1,24 @@ +-- {-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +-- {-# OPTIONS_GHC -O2 -fforce-recomp #-} +-- {-# LANGUAGE PatternSynonyms #-} +-- {-# LANGUAGE BangPatterns #-} +-- {-# LANGUAGE MagicHash, UnboxedTuples #-} + +module T14844Example (topLvl) where + +topLvl large = (bar1, bar2, foo) + where + foo :: Integer -> (a -> b -> Bool) -> (a,b) -> Bool + foo 0 _ _ = False + foo s f t = l s' t + where + l 0 t = False + l 1 t = case t of (x,y) -> f x y + l n (x,y) = l (n-1) (x,y) + s' = large s + + bar1 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar1 s f x y = foo s f (x,y) + + bar2 :: Integer -> (a -> b -> Bool) -> a -> b -> Bool + bar2 s f x y = foo (s + 1) f (x,y) ===================================== testsuite/tests/simplCore/should_compile/T22227.hs ===================================== @@ -0,0 +1,39 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +module Unboxed (test) where + +import GHC.Exts +import GHC.IO + +data Step s a = Yield a s | Done + +uninitialised = undefined + +test :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +test off n oldArr = runRW# $ \s0 -> + case newArray# n uninitialised s0 + of { (# s1, newArr #) -> + let + step' i + | isTrue# (i >=# n) = Done + | otherwise = + let (# D# x #) = indexArray# oldArr (off +# i) in + if isTrue# (x >## 10.0##) + then Yield (D# x) (I# (i +# 1#)) + else step' (i +# 1#) + loop i j s2 = + case step' i of + Yield x (I# s') -> + case writeArray# newArr j (x + 1) s2 + of { s3 -> + loop s' (j +# 1#) s3 + } + Done -> + case unsafeFreezeArray# newArr s2 + of { (# s3, out #) -> + (# 0#, j, out #) + } + in + loop 0# 0# s1 + } ===================================== testsuite/tests/simplCore/should_compile/T22227.stderr ===================================== @@ -0,0 +1,310 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 213, types: 211, coercions: 4, joins: 5/5} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl :: Addr# +[GblId, Unf=OtherCon []] +lvl = "undefined"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl1 :: [Char] +[GblId] +lvl1 = unpackCString# lvl + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule4 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl2 :: [Char] +[GblId] +lvl2 = unpackCString# Unboxed.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$trModule2 = "Unboxed"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl3 :: [Char] +[GblId] +lvl3 = unpackCString# Unboxed.$trModule2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +lvl4 :: Addr# +[GblId, Unf=OtherCon []] +lvl4 = "T22227.hs"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl5 :: [Char] +[GblId] +lvl5 = unpackCString# lvl4 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl6 :: Int +[GblId, Unf=OtherCon []] +lvl6 = GHC.Types.I# 11# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl7 :: Int +[GblId, Unf=OtherCon []] +lvl7 = GHC.Types.I# 17# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl8 :: Int +[GblId, Unf=OtherCon []] +lvl8 = GHC.Types.I# 26# + +-- RHS size: {terms: 8, types: 0, coercions: 0, joins: 0/0} +lvl9 :: GHC.Stack.Types.SrcLoc +[GblId, Unf=OtherCon []] +lvl9 = GHC.Stack.Types.SrcLoc lvl2 lvl3 lvl5 lvl6 lvl7 lvl6 lvl8 + +-- RHS size: {terms: 4, types: 0, coercions: 0, joins: 0/0} +lvl10 :: GHC.Stack.Types.CallStack +[GblId, Unf=OtherCon []] +lvl10 + = GHC.Stack.Types.PushCallStack + lvl1 lvl9 GHC.Stack.Types.EmptyCallStack + +-- RHS size: {terms: 3, types: 3, coercions: 4, joins: 0/0} +uninitialised :: forall {a}. a +[GblId, Str=b, Cpr=b] +uninitialised + = \ (@a) -> + undefined + @LiftedRep + @a + (lvl10 + `cast` (Sym (GHC.Classes.N:IP[0] + <"callStack">_N _N) + :: GHC.Stack.Types.CallStack + ~R# (?callStack::GHC.Stack.Types.CallStack))) + +-- RHS size: {terms: 90, types: 151, coercions: 0, joins: 5/5} +test + :: Int# -> Int# -> Array# Double -> (# Int#, Int#, Array# Double #) +[GblId, + Arity=3, + Str=, + Cpr=1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0 0] 137 0}] +test + = \ (off :: Int#) (n :: Int#) (oldArr :: Array# Double) -> + runRW# + @('TupleRep '[ 'IntRep, 'IntRep, UnliftedRep]) + @(# Int#, Int#, Array# Double #) + (\ (s [OS=OneShot] :: State# RealWorld) -> + case newArray# + @'Lifted @Double @RealWorld n (uninitialised @Double) s + of + { (# ipv, ipv1 #) -> + join { + exit [Dmd=SC(S,C(1,L))] + :: Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit (j [OS=OneShot] :: Int#) (s2 [OS=OneShot] :: State# RealWorld) + = case unsafeFreezeArray# @'Lifted @RealWorld @Double ipv1 s2 of + { (# ipv2, ipv3 #) -> + (# 0#, j, ipv3 #) + } } in + joinrec { + loop [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,L)))] + :: Int# + -> Int# -> State# RealWorld -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + loop (i :: Int#) (j :: Int#) (s2 :: State# RealWorld) + = join { + exit1 [Dmd=LC(S,C(1,!P(L,L,L)))] + :: Int# -> Double# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(2)(Nothing)], Arity=2, Str=] + exit1 (i1 [OS=OneShot] :: Int#) (x [OS=OneShot] :: Double#) + = case writeArray# + @'Lifted @RealWorld @Double ipv1 j (GHC.Types.D# (+## x 1.0##)) s2 + of s3 + { __DEFAULT -> + jump loop (+# i1 1#) (+# j 1#) s3 + } } in + join { + $j [Dmd=L!P(L,L,L)] :: (# Int#, Int#, Array# Double #) + [LclId[JoinId(0)(Nothing)]] + $j = jump exit j s2 } in + joinrec { + step' [Occ=LoopBreaker, Dmd=SC(S,!P(L,L,L))] + :: Int# -> (# Int#, Int#, Array# Double #) + [LclId[JoinId(1)(Nothing)], Arity=1, Str=, Unf=OtherCon []] + step' (i1 :: Int#) + = case >=# i1 n of { + __DEFAULT -> + case indexArray# @'Lifted @Double oldArr (+# off i1) of + { (# ipv2 #) -> + case ipv2 of { D# x -> + case >## x 10.0## of { + __DEFAULT -> jump step' (+# i1 1#); + 1# -> jump exit1 i1 x + } + } + }; + 1# -> jump $j + }; } in + jump step' i; } in + jump loop 0# 0# ipv + }) + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule3 = GHC.Types.TrNameS Unboxed.$trModule4 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule1 = GHC.Types.TrNameS Unboxed.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$trModule + = GHC.Types.Module Unboxed.$trModule3 Unboxed.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep = GHC.Types.KindRepVar 1# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$krep1 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep1 = GHC.Types.KindRepVar 0# + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep2 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Unboxed.$tcStep2 = "Step"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep1 = GHC.Types.TrNameS Unboxed.$tcStep2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tcStep :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tcStep + = GHC.Types.TyCon + 9345441458829744813##64 + 15928240119707513573##64 + Unboxed.$trModule + Unboxed.$tcStep1 + 0# + GHC.Types.krep$*->*->* + +-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +$krep2 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep2 + = GHC.Types.: + @GHC.Types.KindRep $krep (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep3 :: [GHC.Types.KindRep] +[GblId, Unf=OtherCon []] +$krep3 = GHC.Types.: @GHC.Types.KindRep $krep1 $krep2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Done1 + = GHC.Types.KindRepTyConApp Unboxed.$tcStep $krep3 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Done3 = "'Done"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done2 = GHC.Types.TrNameS Unboxed.$tc'Done3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Done :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Done + = GHC.Types.TyCon + 12965714903249458155##64 + 720712123234526269##64 + Unboxed.$trModule + Unboxed.$tc'Done2 + 2# + Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep4 :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +$krep4 = GHC.Types.KindRepFun $krep1 Unboxed.$tc'Done1 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield1 [InlPrag=[~]] :: GHC.Types.KindRep +[GblId, Unf=OtherCon []] +Unboxed.$tc'Yield1 = GHC.Types.KindRepFun $krep $krep4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield3 :: Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +Unboxed.$tc'Yield3 = "'Yield"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield2 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield2 = GHC.Types.TrNameS Unboxed.$tc'Yield3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +Unboxed.$tc'Yield :: GHC.Types.TyCon +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +Unboxed.$tc'Yield + = GHC.Types.TyCon + 16456917800457442198##64 + 7357499335137316903##64 + Unboxed.$trModule + Unboxed.$tc'Yield2 + 2# + Unboxed.$tc'Yield1 + + + ===================================== testsuite/tests/simplCore/should_compile/T22277.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T22277 where + +entry :: Int -> Int +entry n = case n of + 0 -> f n (13,24) + _ -> f n (n,n) + where + f :: Int -> (Int,Int) -> Int + f m x = g m x + where + exit m = (length $ reverse $ reverse $ reverse $ reverse $ [0..m]) + n + g n p | even n = exit n + | n > 43 = g (n-1) p + | otherwise = fst p ===================================== testsuite/tests/simplCore/should_compile/T22277.stderr ===================================== @@ -0,0 +1,132 @@ +[1 of 1] Compiling T22277 ( T22277.hs, T22277.o ) + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 110, types: 49, coercions: 0, joins: 3/4} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T22277.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule3 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule3 = GHC.Types.TrNameS T22277.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T22277.$trModule2 = "T22277"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule1 :: GHC.Types.TrName +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule1 = GHC.Types.TrNameS T22277.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T22277.$trModule :: GHC.Types.Module +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.$trModule + = GHC.Types.Module T22277.$trModule3 T22277.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry2 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry2 = GHC.Types.I# 13# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T22277.entry1 :: Int +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T22277.entry1 = GHC.Types.I# 24# + +-- RHS size: {terms: 89, types: 40, coercions: 0, joins: 3/4} +entry :: Int -> Int +[GblId, + Arity=1, + Str=<1P(SL)>, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 403 0}] +entry + = \ (n :: Int) -> + case n of wild { GHC.Types.I# ds -> + join { + $w$sexit [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int + [LclId[JoinId(1)(Nothing)], Arity=1, Str=] + $w$sexit (ww [OS=OneShot] :: GHC.Prim.Int#) + = join { + $j [Dmd=1C(1,!P(L))] :: [Int] -> Int + [LclId[JoinId(1)(Just [!])], Arity=1, Str=<1L>, Unf=OtherCon []] + $j (arg [OS=OneShot] :: [Int]) + = case GHC.List.$wlenAcc + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 + @Int + (GHC.List.reverse1 @Int arg (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + (GHC.Types.[] @Int)) + 0# + of ww1 + { __DEFAULT -> + GHC.Types.I# (GHC.Prim.+# ww1 ds) + } } in + case GHC.Prim.># 0# ww of { + __DEFAULT -> + letrec { + go3 [Occ=LoopBreaker, Dmd=SC(S,L)] :: GHC.Prim.Int# -> [Int] + [LclId, Arity=1, Str=, Unf=OtherCon []] + go3 + = \ (x :: GHC.Prim.Int#) -> + GHC.Types.: + @Int + (GHC.Types.I# x) + (case GHC.Prim.==# x ww of { + __DEFAULT -> go3 (GHC.Prim.+# x 1#); + 1# -> GHC.Types.[] @Int + }); } in + jump $j (go3 0#); + 1# -> jump $j (GHC.Types.[] @Int) + } } in + joinrec { + $s$wg [Occ=LoopBreaker, Dmd=SC(S,C(1,C(1,!P(L))))] + :: Int -> Int -> GHC.Prim.Int# -> Int + [LclId[JoinId(3)(Nothing)], + Arity=3, + Str=, + Unf=OtherCon []] + $s$wg (sc :: Int) (sc1 :: Int) (sc2 :: GHC.Prim.Int#) + = case GHC.Prim.remInt# sc2 2# of { + __DEFAULT -> + case GHC.Prim.># sc2 43# of { + __DEFAULT -> sc; + 1# -> jump $s$wg sc sc1 (GHC.Prim.-# sc2 1#) + }; + 0# -> jump $w$sexit sc2 + }; } in + case ds of ds1 { + __DEFAULT -> jump $s$wg wild wild ds1; + 0# -> jump $s$wg T22277.entry2 T22277.entry1 0# + } + } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -273,6 +273,9 @@ test('T14152a', [extra_files(['T14152.hs']), pre_cmd('cp T14152.hs T14152a.hs'), compile, ['-fno-exitification -ddump-simpl']) test('T13990', normal, compile, ['-dcore-lint -O']) test('T14650', normal, compile, ['-O2']) + +# SpecConstr should specialise `l` here: +test('T14951', [expect_broken(14591), grep_errmsg(r'\$sl') ], compile, ['-O2 -dsuppress-uniques -ddump-simpl']) test('T14959', normal, compile, ['-O']) test('T14978', normal, @@ -428,9 +431,13 @@ test('T21763', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T21763a', only_ways(['optasm']), compile, ['-O2 -ddump-rules']) test('T22028', normal, compile, ['-O -ddump-rule-firings']) test('T22114', normal, compile, ['-O']) -test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +test('T21286', normal, multimod_compile, ['T21286', '-O -ddump-rule-firings']) +# step should be loopified and turned into a join point +test('T22227', [grep_errmsg(r'jump \S*step') ], compile, ['-O -dsuppress-uniques -ddump-simpl']) # One module, T21851.hs, has OPTIONS_GHC -ddump-simpl test('T21851', [grep_errmsg(r'case.*w\$sf') ], multimod_compile, ['T21851', '-O -dno-typeable-binds -dsuppress-uniques']) # One module, T22097.hs, has OPTIONS_GHC -ddump-simpl test('T22097', [grep_errmsg(r'case.*wgoEven') ], multimod_compile, ['T22097', '-O -dno-typeable-binds -dsuppress-uniques']) +# SpecConstr should be able to specialise `go` for the pair +test('T22277', [grep_errmsg(r'\$s\$wgo') ], compile, ['-O2 -ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,12 @@ +module T22241 where + +data D = D !Int + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,15 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> + + + +==================== Cpr signatures ==================== +T22241.f: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> + + ===================================== testsuite/tests/stranal/sigs/T5075.hs ===================================== @@ -17,10 +17,10 @@ g x y = go x True -> Just x False -> go (x*2) --- Here, go is not a join point, but still should be WW'd for Just. --- Unfortunately, CPR can't see that (+?) returns Just, so h won't get the CPR --- property. It probably could by only considering the @Just@ case of the --- inlined (+?). +-- Here, go is not a join point (call-site loopification doesn't trigger because +-- it is marked NOINLINE), but still should be WW'd for Just. Unfortunately, +-- CPR can't see that (+?) returns Just, so h won't get the CPR property. It +-- probably could by only considering the @Just@ case of the inlined (+?). h :: Int -> Maybe Int h x = go x +? go (x+1) where @@ -29,3 +29,4 @@ h x = go x +? go (x+1) go z | z > 10 = Just (x + z) | otherwise = go (z*2) + {-# NOINLINE go #-} ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dbf837a217705c787c2fdbc9194d3b3c5aefe34...31c14aedc1c58e6be0f6ff29f51ca782f5930f8a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dbf837a217705c787c2fdbc9194d3b3c5aefe34...31c14aedc1c58e6be0f6ff29f51ca782f5930f8a You're receiving 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 Oct 12 12:08:17 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 08:08:17 -0400 Subject: [Git][ghc/ghc][master] Mark T7919 as fragile Message-ID: <6346ae3194a01_1eea6a5fada5c0165711d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 1 changed file: - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/rts/all.T ===================================== @@ -267,9 +267,13 @@ test('T7815', [ multi_cpu_race, test('ffishutdown', [ignore_stderr, only_ways(['threaded1','threaded2'])], compile_and_run, ['']) -# Times out in ghci way -test('T7919', [when(fast(), skip), omit_ways(['ghci'] + prof_ways)], compile_and_run, - [config.ghc_th_way_flags]) +# Times out in ghci way. +# Also times out on x86_64-linux from time to time. +test('T7919', [ when(fast(), skip) + , omit_ways(['ghci'] + prof_ways) + , when(platform('x86_64-unknown-linux'), fragile(22283)) + ] + , compile_and_run, [config.ghc_th_way_flags]) test('T8035', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64a390d9c57b35edb6e7cf09b9324b43a3d08671 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64a390d9c57b35edb6e7cf09b9324b43a3d08671 You're receiving 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 Oct 12 12:08:57 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 08:08:57 -0400 Subject: [Git][ghc/ghc][master] rts: Don't hint inlining of appendToRunQueue Message-ID: <6346ae5916468_1eea6a5fc830fc166233@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 2 changed files: - rts/Schedule.c - rts/Schedule.h Changes: ===================================== rts/Schedule.c ===================================== @@ -2915,6 +2915,61 @@ deleteThread_(StgTSO *tso) } #endif +/* + * Run queue manipulation + */ + +void +appendToRunQueue (Capability *cap, StgTSO *tso) +{ + ASSERT(tso->_link == END_TSO_QUEUE); + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_hd = tso; + tso->block_info.prev = END_TSO_QUEUE; + } else { + setTSOLink(cap, cap->run_queue_tl, tso); + setTSOPrev(cap, tso, cap->run_queue_tl); + } + cap->run_queue_tl = tso; + cap->n_run_queue++; +} + +void +pushOnRunQueue (Capability *cap, StgTSO *tso) +{ + setTSOLink(cap, tso, cap->run_queue_hd); + tso->block_info.prev = END_TSO_QUEUE; + if (cap->run_queue_hd != END_TSO_QUEUE) { + setTSOPrev(cap, cap->run_queue_hd, tso); + } + cap->run_queue_hd = tso; + if (cap->run_queue_tl == END_TSO_QUEUE) { + cap->run_queue_tl = tso; + } + cap->n_run_queue++; +} + +StgTSO *popRunQueue (Capability *cap) +{ + ASSERT(cap->n_run_queue > 0); + StgTSO *t = cap->run_queue_hd; + ASSERT(t != END_TSO_QUEUE); + cap->run_queue_hd = t->_link; + + StgTSO *link = RELAXED_LOAD(&t->_link); + if (link != END_TSO_QUEUE) { + link->block_info.prev = END_TSO_QUEUE; + } + RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd + + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_tl = END_TSO_QUEUE; + } + cap->n_run_queue--; + return t; +} + + /* ----------------------------------------------------------------------------- raiseExceptionHelper ===================================== rts/Schedule.h ===================================== @@ -136,67 +136,16 @@ void resurrectThreads (StgTSO *); * NOTE: tso->link should be END_TSO_QUEUE before calling this macro. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso) -{ - ASSERT(tso->_link == END_TSO_QUEUE); - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_hd = tso; - tso->block_info.prev = END_TSO_QUEUE; - } else { - setTSOLink(cap, cap->run_queue_tl, tso); - setTSOPrev(cap, tso, cap->run_queue_tl); - } - cap->run_queue_tl = tso; - cap->n_run_queue++; -} +void appendToRunQueue (Capability *cap, StgTSO *tso); /* Push a thread on the beginning of the run queue. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso) -{ - setTSOLink(cap, tso, cap->run_queue_hd); - tso->block_info.prev = END_TSO_QUEUE; - if (cap->run_queue_hd != END_TSO_QUEUE) { - setTSOPrev(cap, cap->run_queue_hd, tso); - } - cap->run_queue_hd = tso; - if (cap->run_queue_tl == END_TSO_QUEUE) { - cap->run_queue_tl = tso; - } - cap->n_run_queue++; -} +void pushOnRunQueue (Capability *cap, StgTSO *tso); /* Pop the first thread off the runnable queue. */ -INLINE_HEADER StgTSO * -popRunQueue (Capability *cap) -{ - ASSERT(cap->n_run_queue > 0); - StgTSO *t = cap->run_queue_hd; - ASSERT(t != END_TSO_QUEUE); - cap->run_queue_hd = t->_link; - - StgTSO *link = RELAXED_LOAD(&t->_link); - if (link != END_TSO_QUEUE) { - link->block_info.prev = END_TSO_QUEUE; - } - RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd - - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_tl = END_TSO_QUEUE; - } - cap->n_run_queue--; - return t; -} +StgTSO *popRunQueue (Capability *cap); INLINE_HEADER StgTSO * peekRunQueue (Capability *cap) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/481467a5ceb07bb28bb6edb1569c86ff3cac315f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/481467a5ceb07bb28bb6edb1569c86ff3cac315f You're receiving 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 Oct 12 12:37:04 2022 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Wed, 12 Oct 2022 08:37:04 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/fragile-T7919 Message-ID: <6346b4f0ca1b_1eea6a5fada5c01665364@gitlab.mail> Bryan R deleted branch wip/fragile-T7919 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Oct 12 12:51:15 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 08:51:15 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/foundation-tests Message-ID: <6346b8439406a_1eea6a5fc830fc16689cb@gitlab.mail> Matthew Pickering pushed new branch wip/foundation-tests at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/foundation-tests You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Oct 12 14:10:32 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 10:10:32 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: rts: Don't hint inlining of appendToRunQueue Message-ID: <6346cad8a0934_2c5d73514641106fc@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - f1636285 by Curran McConnell at 2022-10-12T10:10:09-04:00 remove name shadowing - - - - - f3799362 by Charles Taylor at 2022-10-12T10:10:13-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 8 changed files: - compiler/GHC/Parser/Lexer.x - docs/users_guide/9.6.1-notes.rst - ghc/GHCi/UI/Monad.hs - rts/Schedule.c - rts/Schedule.h - + testsuite/tests/overloadedrecflds/should_run/T11671_run.hs - + testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout - testsuite/tests/overloadedrecflds/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -163,6 +163,7 @@ $small = [$ascsmall $unismall \_] $uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $idchar = [$small $large $digit $uniidchar \'] +$labelchar = [$small $large $digit $uniidchar \' \.] $unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] @@ -451,7 +452,8 @@ $tab { warnTab } } <0> { - "#" @varid / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" $labelchar+ / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" \" / { ifExtension OverloadedLabelsBit } { lex_quoted_label } } <0> { @@ -2023,46 +2025,64 @@ lex_string_prag_comment mkTok span _buf _len _buf2 lex_string_tok :: Action lex_string_tok span buf _len _buf2 = do - tok <- lex_string "" + lexed <- lex_string (AI end bufEnd) <- getInput let - tok' = case tok of - ITprimstring _ bs -> ITprimstring (SourceText src) bs - ITstring _ s -> ITstring (SourceText src) s - _ -> panic "lex_string_tok" + tok = case lexed of + LexedPrimString s -> ITprimstring (SourceText src) (unsafeMkByteString s) + LexedRegularString s -> ITstring (SourceText src) (mkFastString s) src = lexemeToString buf (cur bufEnd - cur buf) - return (L (mkPsSpan (psSpanStart span) end) tok') + return $ L (mkPsSpan (psSpanStart span) end) tok -lex_string :: String -> P Token -lex_string s = do + +lex_quoted_label :: Action +lex_quoted_label span _buf _len _buf2 = do + s <- lex_string_helper "" + (AI end _) <- getInput + let + token = ITlabelvarid (mkFastString s) + start = psSpanStart span + + return $ L (mkPsSpan start end) token + + +data LexedString = LexedRegularString String | LexedPrimString String + +lex_string :: P LexedString +lex_string = do + s <- lex_string_helper "" + magicHash <- getBit MagicHashBit + if magicHash + then do + i <- getInput + case alexGetChar' i of + Just ('#',i) -> do + setInput i + when (any (> '\xFF') s) $ do + pState <- getPState + let msg = PsErrPrimStringInvalidChar + let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg + addError err + return $ LexedPrimString s + _other -> + return $ LexedRegularString s + else + return $ LexedRegularString s + + +lex_string_helper :: String -> P String +lex_string_helper s = do i <- getInput case alexGetChar' i of Nothing -> lit_error i Just ('"',i) -> do - setInput i - let s' = reverse s - magicHash <- getBit MagicHashBit - if magicHash - then do - i <- getInput - case alexGetChar' i of - Just ('#',i) -> do - setInput i - when (any (> '\xFF') s') $ do - pState <- getPState - let msg = PsErrPrimStringInvalidChar - let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg - addError err - return (ITprimstring (SourceText s') (unsafeMkByteString s')) - _other -> - return (ITstring (SourceText s') (mkFastString s')) - else - return (ITstring (SourceText s') (mkFastString s')) + setInput i + return (reverse s) Just ('\\',i) | Just ('&',i) <- next -> do - setInput i; lex_string s + setInput i; lex_string_helper s | Just (c,i) <- next, c <= '\x7f' && is_space c -> do -- is_space only works for <= '\x7f' (#3751, #5425) setInput i; lex_stringgap s @@ -2070,16 +2090,17 @@ lex_string s = do Just (c, i1) -> do case c of - '\\' -> do setInput i1; c' <- lex_escape; lex_string (c':s) - c | isAny c -> do setInput i1; lex_string (c:s) + '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s) + c | isAny c -> do setInput i1; lex_string_helper (c:s) _other -> lit_error i -lex_stringgap :: String -> P Token + +lex_stringgap :: String -> P String lex_stringgap s = do i <- getInput c <- getCharOrFail i case c of - '\\' -> lex_string s + '\\' -> lex_string_helper s c | c <= '\x7f' && is_space c -> lex_stringgap s -- is_space only works for <= '\x7f' (#3751, #5425) _other -> lit_error i ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -78,6 +78,15 @@ Language Then GHC will use the second quantified constraint to solve ``C a b Int``, as it has a strictly weaker precondition. +- GHC proposal `#170 Unrestricted OverloadedLabels + `_ + has been implemented. + This extends the variety syntax for constructing labels under :extension:`OverloadedLabels`. + Examples of newly allowed syntax: + - Leading capital letters: `#Foo` equivalant to `getLabel @"Foo"` + - Numeric characters: `#3.14` equivalent to `getLabel @"3.14"` + - Arbitrary strings: `#"Hello, World!"` equivalent to `getLabel @"Hello, World!"` + Compiler ~~~~~~~~ ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleInstances, DeriveFunctor, DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# OPTIONS -fno-warn-name-shadowing #-} ----------------------------------------------------------------------------- -- @@ -474,10 +473,10 @@ printStats dflags ActionStats{actionAllocs = mallocs, actionElapsedTime = secs} Just allocs -> text (separateThousands allocs) <+> text "bytes"))) where - separateThousands n = reverse . sep . reverse . show $ n - where sep n' + separateThousands n = reverse . separate . reverse . show $ n + where separate n' | n' `lengthAtMost` 3 = n' - | otherwise = take 3 n' ++ "," ++ sep (drop 3 n') + | otherwise = take 3 n' ++ "," ++ separate (drop 3 n') ----------------------------------------------------------------------------- -- reverting CAFs @@ -526,13 +525,13 @@ turnOffBuffering_ fhv = do liftIO $ evalIO interp fhv mkEvalWrapper :: GhcMonad m => String -> [String] -> m ForeignHValue -mkEvalWrapper progname args = +mkEvalWrapper progname' args' = runInternal $ GHC.compileParsedExprRemote - $ evalWrapper `GHC.mkHsApp` nlHsString progname - `GHC.mkHsApp` nlList (map nlHsString args) + $ evalWrapper' `GHC.mkHsApp` nlHsString progname' + `GHC.mkHsApp` nlList (map nlHsString args') where nlHsString = nlHsLit . mkHsString - evalWrapper = + evalWrapper' = GHC.nlHsVar $ RdrName.mkOrig gHC_GHCI_HELPERS (mkVarOcc "evalWrapper") -- | Run a 'GhcMonad' action to compile an expression for internal usage. ===================================== rts/Schedule.c ===================================== @@ -2915,6 +2915,61 @@ deleteThread_(StgTSO *tso) } #endif +/* + * Run queue manipulation + */ + +void +appendToRunQueue (Capability *cap, StgTSO *tso) +{ + ASSERT(tso->_link == END_TSO_QUEUE); + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_hd = tso; + tso->block_info.prev = END_TSO_QUEUE; + } else { + setTSOLink(cap, cap->run_queue_tl, tso); + setTSOPrev(cap, tso, cap->run_queue_tl); + } + cap->run_queue_tl = tso; + cap->n_run_queue++; +} + +void +pushOnRunQueue (Capability *cap, StgTSO *tso) +{ + setTSOLink(cap, tso, cap->run_queue_hd); + tso->block_info.prev = END_TSO_QUEUE; + if (cap->run_queue_hd != END_TSO_QUEUE) { + setTSOPrev(cap, cap->run_queue_hd, tso); + } + cap->run_queue_hd = tso; + if (cap->run_queue_tl == END_TSO_QUEUE) { + cap->run_queue_tl = tso; + } + cap->n_run_queue++; +} + +StgTSO *popRunQueue (Capability *cap) +{ + ASSERT(cap->n_run_queue > 0); + StgTSO *t = cap->run_queue_hd; + ASSERT(t != END_TSO_QUEUE); + cap->run_queue_hd = t->_link; + + StgTSO *link = RELAXED_LOAD(&t->_link); + if (link != END_TSO_QUEUE) { + link->block_info.prev = END_TSO_QUEUE; + } + RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd + + if (cap->run_queue_hd == END_TSO_QUEUE) { + cap->run_queue_tl = END_TSO_QUEUE; + } + cap->n_run_queue--; + return t; +} + + /* ----------------------------------------------------------------------------- raiseExceptionHelper ===================================== rts/Schedule.h ===================================== @@ -136,67 +136,16 @@ void resurrectThreads (StgTSO *); * NOTE: tso->link should be END_TSO_QUEUE before calling this macro. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -appendToRunQueue (Capability *cap, StgTSO *tso) -{ - ASSERT(tso->_link == END_TSO_QUEUE); - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_hd = tso; - tso->block_info.prev = END_TSO_QUEUE; - } else { - setTSOLink(cap, cap->run_queue_tl, tso); - setTSOPrev(cap, tso, cap->run_queue_tl); - } - cap->run_queue_tl = tso; - cap->n_run_queue++; -} +void appendToRunQueue (Capability *cap, StgTSO *tso); /* Push a thread on the beginning of the run queue. * ASSUMES: cap->running_task is the current task. */ -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso); - -EXTERN_INLINE void -pushOnRunQueue (Capability *cap, StgTSO *tso) -{ - setTSOLink(cap, tso, cap->run_queue_hd); - tso->block_info.prev = END_TSO_QUEUE; - if (cap->run_queue_hd != END_TSO_QUEUE) { - setTSOPrev(cap, cap->run_queue_hd, tso); - } - cap->run_queue_hd = tso; - if (cap->run_queue_tl == END_TSO_QUEUE) { - cap->run_queue_tl = tso; - } - cap->n_run_queue++; -} +void pushOnRunQueue (Capability *cap, StgTSO *tso); /* Pop the first thread off the runnable queue. */ -INLINE_HEADER StgTSO * -popRunQueue (Capability *cap) -{ - ASSERT(cap->n_run_queue > 0); - StgTSO *t = cap->run_queue_hd; - ASSERT(t != END_TSO_QUEUE); - cap->run_queue_hd = t->_link; - - StgTSO *link = RELAXED_LOAD(&t->_link); - if (link != END_TSO_QUEUE) { - link->block_info.prev = END_TSO_QUEUE; - } - RELAXED_STORE(&t->_link, END_TSO_QUEUE); // no write barrier req'd - - if (cap->run_queue_hd == END_TSO_QUEUE) { - cap->run_queue_tl = END_TSO_QUEUE; - } - cap->n_run_queue--; - return t; -} +StgTSO *popRunQueue (Capability *cap); INLINE_HEADER StgTSO * peekRunQueue (Capability *cap) ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE MagicHash #-} + +import Data.Foldable (traverse_) +import Data.Proxy (Proxy(..)) +import GHC.OverloadedLabels (IsLabel(..)) +import GHC.TypeLits (KnownSymbol, symbolVal) +import GHC.Prim (Addr#) + +instance KnownSymbol symbol => IsLabel symbol String where + fromLabel = symbolVal (Proxy :: Proxy symbol) + +(#) :: String -> Int -> String +(#) _ i = show i + +f :: Addr# -> Int -> String +f _ i = show i + +main :: IO () +main = traverse_ putStrLn + [ #a + , #number17 + , #do + , #type + , #Foo + , #3 + , #199.4 + , #17a23b + , #f'a' + , #'a' + , #' + , #''notTHSplice + , #... + , #привет + , #こんにちは + , #"3" + , #":" + , #"Foo" + , #"The quick brown fox" + , #"\"" + , (++) #hello#world + , (++) #"hello"#"world" + , #"hello"# 1 -- equivalent to `(fromLabel @"hello") # 1` + , f "hello"#2 -- equivalent to `f ("hello"# :: Addr#) 2` + ] ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout ===================================== @@ -0,0 +1,24 @@ +a +number17 +do +type +Foo +3 +199.4 +17a23b +f'a' +'a' +' +''notTHSplice +... +привет +こんにちは +3 +: +Foo +The quick brown fox +" +helloworld +helloworld +1 +2 ===================================== testsuite/tests/overloadedrecflds/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('hasfieldrun01', normal, compile_and_run, ['']) test('hasfieldrun02', normal, compile_and_run, ['']) test('T12243', normal, compile_and_run, ['']) test('T11228', normal, compile_and_run, ['']) +test('T11671_run', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b4b224a3770669e1c49f7425283322bfaa11332...f3799362d9a5582ea433f7be582efe6d04d2369e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b4b224a3770669e1c49f7425283322bfaa11332...f3799362d9a5582ea433f7be582efe6d04d2369e You're receiving 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 Oct 12 14:50:24 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 10:50:24 -0400 Subject: [Git][ghc/ghc][wip/foundation-tests] Run with -O Message-ID: <6346d430586a5_2c5d73515041207d@gitlab.mail> Matthew Pickering pushed to branch wip/foundation-tests at Glasgow Haskell Compiler / GHC Commits: 8937fa63 by Matthew Pickering at 2022-10-12T15:50:17+01:00 Run with -O - - - - - 1 changed file: - testsuite/tests/numeric/should_run/all.T Changes: ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,4 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) -test('foundation', normal, compile_and_run, ['-package transformers']) +test('foundation', normal, compile_and_run, ['-O -package transformers']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8937fa6306ae070f53fc8c985a251d81747e0136 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8937fa6306ae070f53fc8c985a251d81747e0136 You're receiving 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 Oct 12 14:52:59 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 10:52:59 -0400 Subject: [Git][ghc/ghc][wip/21619] Fix nested type splices in hie files Message-ID: <6346d4cbe8bc8_2c5d735146412304@gitlab.mail> Matthew Pickering pushed to branch wip/21619 at Glasgow Haskell Compiler / GHC Commits: c6d11bf5 by Matthew Pickering at 2022-10-12T15:52:49+01:00 Fix nested type splices in hie files The issue is that when we compile a typed bracket we replace the splice with HsSpliced (unTypeCode ...). Then when computing types for > [|| T $$(...) ||] GHC is asked to compute the type of `T $$(..)`, which panics because of the bogus type of T applied to `HsSpliced`, which is not type correct. The fix is to not attempt to compute the type for `HsSpliceE` constructors if we come across them as they should have either been already evaluated or lifted into a splice environment. As part of the patch I made hie files traverse into the splice environments so now we also get type information for things used inside nested splices. Fixes #21619 - - - - - 8 changed files: - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Iface/Ext/Ast.hs - testsuite/tests/hiefile/should_compile/all.T - + testsuite/tests/hiefile/should_compile/hie011.hs - + testsuite/tests/hiefile/should_compile/hie011.stderr - + testsuite/tests/hiefile/should_run/SpliceTypes.hs - + testsuite/tests/hiefile/should_run/SpliceTypes.stdout - testsuite/tests/hiefile/should_run/all.T Changes: ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -133,9 +133,9 @@ hsExprType (HsTypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType (HsUntypedBracket (HsBracketTc _ ty _wrap _pending) _) = ty hsExprType e@(HsSpliceE{}) = pprPanic "hsExprType: Unexpected HsSpliceE" (ppr e) - -- Typed splices should have been eliminated during zonking, but we - -- can't use `dataConCantHappen` since they are still present before - -- than in the typechecked AST. + -- Typed splices should have been eliminated during zonking, but we + -- can't use `dataConCantHappen` since they are still present before + -- than in the typechecked AST hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top hsExprType (HsStatic (_, ty) _s) = ty hsExprType (HsPragE _ _ e) = lhsExprType e ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -744,6 +744,9 @@ instance HiePass p => HasType (LocatedA (HsExpr (GhcPass p))) where RecordCon con_expr _ _ -> computeType con_expr ExprWithTySig _ e _ -> computeLType e HsPragE _ _ e -> computeLType e + -- By this point all splices are lifted into splice environments so + -- the remaining HsSpliceE in the syntax tree contain bogus information. + HsSpliceE {} -> Nothing XExpr (ExpansionExpr (HsExpanded (HsGetField _ _ _) e)) -> Just (hsExprType e) -- for record-dot-syntax XExpr (ExpansionExpr (HsExpanded _ e)) -> computeType e XExpr (HsTick _ e) -> computeLType e @@ -1873,10 +1876,10 @@ instance ToHie (HsQuote a) where toHie _ = pure [] instance ToHie PendingRnSplice where - toHie _ = pure [] + toHie (PendingRnSplice _ _ e) = toHie e instance ToHie PendingTcSplice where - toHie _ = pure [] + toHie (PendingTcSplice _ e) = toHie e instance ToHie (LBooleanFormula (LocatedN Name)) where toHie (L span form) = concatM $ makeNode form (locA span) : case form of ===================================== testsuite/tests/hiefile/should_compile/all.T ===================================== @@ -16,6 +16,7 @@ test('hie007', normal, compile, ['-fno-code -fwrite-ide- test('hie008', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie009', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('hie010', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) +test('hie011', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('CPP', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Constructors', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) test('Scopes', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info']) ===================================== testsuite/tests/hiefile/should_compile/hie011.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fwrite-ide-info #-} +module M where + +import Language.Haskell.TH.Syntax + +newtype T = T { getT :: Int } + +instance Lift T where + lift = undefined + liftTyped v = [||T $$(liftTyped (getT v))||] + + +top_level :: () +top_level = $$([|| () ||]) ===================================== testsuite/tests/hiefile/should_compile/hie011.stderr ===================================== @@ -0,0 +1,2 @@ +Got valid scopes +Got no roundtrip errors ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import TestUtils +import qualified Data.Map as M +import Data.Foldable +import Language.Haskell.TH.Syntax + + +newtype T = T { getT :: Int } + +instance Lift T where + liftTyped v = [||T $$(liftTyped (getT v))||] +-- ^ ^ ^ ^ ^ +-- 1 2 3 4 5 +-- + +top_level :: () +top_level = $$([|| () ||]) +-- ^ ^ +-- 1 2 + +p1,p2, p3, p4:: (Int,Int) +p1 = (14,18) +p2 = (14,21) +p3 = (14,24) +p4 = (14,29) +p5 = (14,41) + +q1 = (20, 19) +q2 = (20, 21) + +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc + +main = do + (df, hf) <- readTestHie "SpliceTypes.hie" + forM_ [p1,p2,p3, p4, p5, q1, q2] $ \point -> do + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point + case types of + [] -> putStrLn $ "No types at " ++ show point + _ -> do + putStr $ "At " ++ show point ++ ", got type: " + forM_ types $ \typ -> do + putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/SpliceTypes.stdout ===================================== @@ -0,0 +1,9 @@ +No types at (14,18) +At (14,21), got type: Int -> T +No types at (14,24) +At (14,29), got type: Int -> Code m Int +forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t +forall (m :: * -> *). Quote m => Int -> Code m Int +At (14,41), got type: T +No types at (20,19) +No types at (20,21) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -2,3 +2,4 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, [ test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('T20341', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) test('RecordDotTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('SpliceTypes', [extra_run_opts('"' + config.libdir + '"'), extra_files(['TestUtils.hs'])], compile_and_run, ['-package ghc -fwrite-ide-info']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6d11bf560c5b7c55f87de310561b60f728739a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6d11bf560c5b7c55f87de310561b60f728739a1 You're receiving 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 Oct 12 15:01:35 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Wed, 12 Oct 2022 11:01:35 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 4 commits: Remove JS keywords Message-ID: <6346d6cfb845e_2c5d7351428130958@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: c11368a0 by Sylvain Henry at 2022-10-12T14:05:52+02:00 Remove JS keywords 1. The list is incomplete 2. We prefix locals with "h$$" so there is no risk of conflict with JS keywords - - - - - 01c0b664 by Sylvain Henry at 2022-10-12T14:08:01+02:00 Remove dead code - - - - - e8b23bab by Sylvain Henry at 2022-10-12T14:09:05+02:00 Make ident supply strict (no need to make it lazy, list already is) - - - - - 21ef7cfb by Sylvain Henry at 2022-10-12T17:04:41+02:00 Add optional assign to DeclStat and remove dead code - - - - - 13 changed files: - compiler/GHC/JS/Make.hs - compiler/GHC/JS/Ppr.hs - compiler/GHC/JS/Syntax.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/DataCon.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/FFI.hs - compiler/GHC/StgToJS/Ids.hs - compiler/GHC/StgToJS/Linker/Compactor.hs - compiler/GHC/StgToJS/Linker/Types.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Printer.hs Changes: ===================================== compiler/GHC/JS/Make.hs ===================================== @@ -266,7 +266,7 @@ jVar :: ToSat a => a -> JStat jVar f = UnsatBlock . IS $ do (block, is) <- runIdentSupply $ toSat_ f [] let addDecls (BlockStat ss) = - BlockStat $ map DeclStat is ++ ss + BlockStat $ map decl is ++ ss addDecls x = x return $ addDecls block @@ -278,14 +278,14 @@ jForIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat jForIn e f = UnsatBlock . IS $ do (block, is) <- runIdentSupply $ toSat_ f [] let i = List.head is - return $ DeclStat i `mappend` ForInStat False i e block + return $ decl i `mappend` ForInStat False i e block -- | As with "jForIn" but creating a \"for each in\" statement. jForEachIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat jForEachIn e f = UnsatBlock . IS $ do (block, is) <- runIdentSupply $ toSat_ f [] let i = List.head is - return $ DeclStat i `mappend` ForInStat True i e block + return $ decl i `mappend` ForInStat True i e block -- | As with "jForIn" but creating a \"for each in\" statement. jTryCatchFinally :: (ToSat a) => JStat -> a -> JStat -> JStat @@ -311,7 +311,7 @@ jFor before p after b = BlockStat [before, WhileStat False (toJExpr p) b'] -- | construct a js declaration with the given identifier decl :: Ident -> JStat -decl i = DeclStat i +decl i = DeclStat i Nothing -- | The empty JS HashMap jhEmpty :: M.Map k JExpr @@ -508,7 +508,7 @@ infixl 8 .^ -- -- > foo |= expr ==> var foo; foo = expr; (||=) :: Ident -> JExpr -> JStat -i ||= ex = DeclStat i `mappend` (toJExpr i |= ex) +i ||= ex = DeclStat i (Just ex) infixl 2 ||=, |= ===================================== compiler/GHC/JS/Ppr.hs ===================================== @@ -112,7 +112,8 @@ defRenderJsS r = \case $$ mbElse where mbElse | y == BlockStat [] = PP.empty | otherwise = hangBrace (text "else") (jsToDocR r y) - DeclStat x -> text "var" <+> jsToDocR r x + DeclStat x Nothing -> text "var" <+> jsToDocR r x + DeclStat x (Just e) -> text "var" <+> jsToDocR r x <+> char '=' <+> jsToDocR r e WhileStat False p b -> hangBrace (text "while" <> parens (jsToDocR r p)) (jsToDocR r b) WhileStat True p b -> (hangBrace (text "do") (jsToDocR r b)) $+$ text "while" <+> parens (jsToDocR r p) UnsatBlock e -> jsToDocR r $ pseudoSaturate e ===================================== compiler/GHC/JS/Syntax.hs ===================================== @@ -85,8 +85,6 @@ module GHC.JS.Syntax , pseudoSaturate -- * Utility , SaneDouble(..) - -- * Keywords - , isJsKeyword ) where import GHC.Prelude @@ -94,7 +92,6 @@ import GHC.Prelude import Control.DeepSeq import Data.Function -import qualified Data.Set as Set import Data.Data import Data.Word import qualified Data.Semigroup as Semigroup @@ -144,7 +141,7 @@ instance Show a => Show (IdentSupply a) where -- Reference](https://tc39.es/ecma262/#sec-ecmascript-language-statements-and-declarations) -- for details data JStat - = DeclStat Ident -- ^ Variable declarations: var foo + = DeclStat !Ident !(Maybe JExpr) -- ^ Variable declarations: var foo [= e] | ReturnStat JExpr -- ^ Return | IfStat JExpr JStat JStat -- ^ If | WhileStat Bool JExpr JStat -- ^ While, bool is "do" when True @@ -391,26 +388,3 @@ newtype Ident = TxtI { itxt :: FastString } instance Ord Ident where compare (TxtI fs1) (TxtI fs2) = lexicalCompareFS fs1 fs2 - --------------------------------------------------------------------------------- --- JS Keywords --------------------------------------------------------------------------------- --- | The set of Javascript keywords -jsKeywords :: Set.Set Ident -jsKeywords = Set.fromList $ TxtI <$> - [ "break", "case", "catch", "continue", "debugger" - , "default", "delete", "do", "else", "finally", "for" - , "function", "if", "in", "instanceof", "new", "return" - , "switch", "this", "throw", "try", "typeof", "var", "void" - , "while", "with" - , "class", "enum", "export", "extends", "import", "super" - , "const" - , "implements", "interface", "let", "package", "private" - , "protected" - , "public", "static", "yield" - , "null", "true", "false" - ] - --- | Predicate which checks if input 'Ident' is a JS keyword or not. -isJsKeyword :: Ident -> Bool -isJsKeyword = flip Set.member jsKeywords ===================================== compiler/GHC/JS/Transform.hs ===================================== @@ -25,9 +25,6 @@ module GHC.JS.Transform , composOpM , composOpM_ , composOpFold - -- * Hygienic transformation - , withHygiene - , scopify ) where @@ -35,15 +32,12 @@ import GHC.Prelude import GHC.JS.Syntax -import qualified Data.Map as M -import Text.Read (readMaybe) import Data.Functor.Identity import Control.Monad import Data.Bifunctor import GHC.Data.FastString import GHC.Utils.Monad.State.Strict -import GHC.Utils.Panic import GHC.Types.Unique.FM import GHC.Types.Unique.Map import GHC.Types.Unique.DSet @@ -80,7 +74,7 @@ mapIdent f = (map_expr, map_stat) UnsatVal v2 -> ValExpr $ UnsatVal v2 map_stat s = case s of - DeclStat{} -> s + DeclStat i e -> DeclStat i (fmap map_expr e) ReturnStat e -> ReturnStat (map_expr e) IfStat e s1 s2 -> IfStat (map_expr e) (map_stat s1) (map_stat s2) WhileStat b e s2 -> WhileStat b (map_expr e) (map_stat s2) @@ -99,7 +93,7 @@ mapIdent f = (map_expr, map_stat) {-# INLINE identsS #-} identsS :: JStat -> UniqDSet Ident identsS = \case - DeclStat i -> unitUniqDSet i + DeclStat i e -> unitUniqDSet i `unionUniqDSets` maybe emptyUniqDSet identsE e ReturnStat e -> identsE e IfStat e s1 s2 -> identsE e `unionUniqDSets` identsS s1 `unionUniqDSets` identsS s2 WhileStat _ e s -> identsE e `unionUniqDSets` identsS s @@ -206,7 +200,7 @@ jmcompos ret app f' v = case v of JMGId _ -> ret v JMGStat v' -> ret JMGStat `app` case v' of - DeclStat i -> ret DeclStat `app` f i + DeclStat i e -> ret DeclStat `app` f i `app` mapMaybeM' f e ReturnStat i -> ret ReturnStat `app` f i IfStat e s s' -> ret IfStat `app` f e `app` f s `app` f s' WhileStat b e s -> ret (WhileStat b) `app` f e `app` f s @@ -249,6 +243,10 @@ jmcompos ret app f' v = where mapM' :: forall a. (a -> m a) -> [a] -> m [a] mapM' g = foldr (app . app (ret (:)) . g) (ret []) + mapMaybeM' :: forall a. (a -> m a) -> Maybe a -> m (Maybe a) + mapMaybeM' g = \case + Nothing -> ret Nothing + Just a -> app (ret Just) (g a) f :: forall b. JMacro b => b -> m b f x = ret jfromGADT `app` f' (jtoGADT x) @@ -270,104 +268,3 @@ jsSaturate_ e = IS $ jfromGADT <$> go (jtoGADT e) JMGExpr (UnsatExpr us) -> go =<< (JMGExpr <$> runIdentSupply us) JMGVal (UnsatVal us) -> go =<< (JMGVal <$> runIdentSupply us) _ -> composOpM go v - -{-------------------------------------------------------------------- - Transformation ---------------------------------------------------------------------} - --- doesn't apply to unsaturated bits -jsReplace_ :: JMacro a => [(Ident, Ident)] -> a -> a -jsReplace_ xs e = jfromGADT $ go (jtoGADT e) - where - go :: forall a. JMGadt a -> JMGadt a - go v = case v of - JMGId i -> maybe v JMGId (M.lookup i mp) - _ -> composOp go v - mp = M.fromList xs - --- only works on fully saturated things -jsUnsat_ :: JMacro a => [Ident] -> a -> IdentSupply a -jsUnsat_ xs e = IS $ do - (idents,is') <- splitAt (length xs) <$> get - put is' - return $ jsReplace_ (zip xs idents) e - --- | Apply a transformation to a fully saturated syntax tree, --- taking care to return any free variables back to their free state --- following the transformation. As the transformation preserves --- free variables, it is hygienic. -withHygiene :: JMacro a => (a -> a) -> a -> a -withHygiene f x = jfromGADT $ case jtoGADT x of - JMGExpr z -> JMGExpr $ UnsatExpr $ inScope z - JMGStat z -> JMGStat $ UnsatBlock $ inScope z - JMGVal z -> JMGVal $ UnsatVal $ inScope z - JMGId _ -> jtoGADT $ f x - where - inScope z = IS $ do - ti <- get - case ti of - ((TxtI a):b) -> do - put b - return $ withHygiene_ a f z - _ -> error "withHygiene: empty list" - -withHygiene_ :: JMacro a => FastString -> (a -> a) -> a -> a -withHygiene_ un f x = jfromGADT $ case jtoGADT x of - JMGStat _ -> jtoGADT $ UnsatBlock (jsUnsat_ is' x'') - JMGExpr _ -> jtoGADT $ UnsatExpr (jsUnsat_ is' x'') - JMGVal _ -> jtoGADT $ UnsatVal (jsUnsat_ is' x'') - JMGId _ -> jtoGADT $ f x - where - (x',l) = case runState (runIdentSupply $ jsSaturate_ x) is of - (_ , []) -> panic "withHygiene: empty ident list" - (x', TxtI l : _) -> (x',l) - is' = take lastVal is - x'' = f x' - lastVal = case readMaybe (reverse . takeWhile (/= '_') . reverse . unpackFS $ l) of - Nothing -> panic ("inSat" ++ unpackFS un) - Just r -> r :: Int - is = newIdentSupply $ Just (mkFastString "inSat" `mappend` un) - --- | Takes a fully saturated expression and transforms it to use unique --- variables that respect scope. -scopify :: JStat -> JStat -scopify x = evalState (jfromGADT <$> go (jtoGADT x)) (newIdentSupply Nothing) - where - go :: forall a. JMGadt a -> State [Ident] (JMGadt a) - go = \case - JMGStat (BlockStat ss) -> JMGStat . BlockStat <$> - blocks ss - where blocks [] = return [] - blocks (DeclStat (TxtI i) : xs) - | ('!':'!':rs) <- unpackFS i - = (DeclStat (TxtI (mkFastString rs)):) <$> blocks xs - | ('!':rs) <- unpackFS i - = (DeclStat (TxtI $ mkFastString rs):) <$> blocks xs - | otherwise = do - xx <- get - case xx of - (newI:st) -> do - put st - rest <- blocks xs - return $ [DeclStat newI `mappend` jsReplace_ [(TxtI i, newI)] (BlockStat rest)] - _ -> error "scopify: empty list" - blocks (x':xs) = (jfromGADT <$> go (jtoGADT x')) <:> blocks xs - (<:>) = liftM2 (:) - JMGStat (TryStat s (TxtI i) s1 s2) -> do - xx <- get - case xx of - (newI:st) -> do - put st - t <- jfromGADT <$> go (jtoGADT s) - c <- jfromGADT <$> go (jtoGADT s1) - f <- jfromGADT <$> go (jtoGADT s2) - return . JMGStat . TryStat t newI (jsReplace_ [(TxtI i, newI)] c) $ f - _ -> error "scopify: empty list" - JMGExpr (ValExpr (JFunc is s)) -> do - st <- get - let (newIs,newSt) = splitAt (length is) st - put newSt - rest <- jfromGADT <$> go (jtoGADT s) - return . JMGExpr . ValExpr $ JFunc newIs $ (jsReplace_ $ zip is newIs) rest - v -> composOpM go v - ===================================== compiler/GHC/StgToJS/DataCon.hs ===================================== @@ -117,8 +117,8 @@ allocDynamicE inline_alloc entry free cc -- | Allocate a dynamic object allocDynamic :: StgToJSConfig -> Bool -> Ident -> JExpr -> [JExpr] -> Maybe JExpr -> JStat -allocDynamic s haveDecl to entry free cc = - dec to `mappend` (toJExpr to |= allocDynamicE (csInlineAlloc s) entry free cc) +allocDynamic s need_decl to entry free cc + | need_decl = DeclStat to (Just value) + | otherwise = toJExpr to |= value where - dec i | haveDecl = DeclStat i - | otherwise = mempty + value = allocDynamicE (csInlineAlloc s) entry free cc ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -259,7 +259,7 @@ genEntryLne ctx i (StgRhsCon cc con _mu _ticks args) = resetSlots $ do args' <- concatMapM genArg args ac <- allocCon ii con cc args' emitToplevel (ei ||= toJExpr (JFunc [] - (mconcat [DeclStat ii, p, ac, r1 |= toJExpr ii, returnStack]))) + (mconcat [decl ii, p, ac, r1 |= toJExpr ii, returnStack]))) -- | Generate the entry function for a local closure genEntry :: HasDebugCallStack => ExprCtx -> Id -> CgStgRhs -> G () @@ -427,7 +427,7 @@ loadLiveFun l = do ] where loadLiveVar d n v = let ident = TxtI (dataFieldName n) - in DeclStat v `mappend` (toJExpr v |= SelExpr d ident) + in v ||= SelExpr d ident -- | Pop a let-no-escape frame off the stack popLneFrame :: Bool -> Int -> ExprCtx -> G JStat @@ -541,7 +541,7 @@ allocCls dynMiddle xs = do toCl (i, StgRhsCon cc con _mui _ticjs [a]) | isUnboxableCon con = do ii <- identForId i ac <- allocCon ii con cc =<< genArg a - pure (Left (DeclStat ii <> ac)) + pure (Left (decl ii <> ac)) -- dynamics toCl (i, StgRhsCon cc con _mu _ticks ar) = @@ -581,15 +581,13 @@ genCase ctx bnd e at alts l (pprStgExpr panicStgPprOpts e) (aj, ar) <- genAlts (ctxAssertEvaluated bnd ctx) bnd at d alts - (declCCS,saveCCS,restoreCCS) <- ifProfilingM $ do + (saveCCS,restoreCCS) <- ifProfilingM $ do ccsVar <- freshIdent - pure ( DeclStat ccsVar - , toJExpr ccsVar |= toJExpr jCurrentCCS + pure ( ccsVar ||= toJExpr jCurrentCCS , toJExpr jCurrentCCS |= toJExpr ccsVar ) return ( mconcat - [ declCCS - , mconcat (map DeclStat bndi) + [ mconcat (map decl bndi) , saveCCS , ej , restoreCCS @@ -977,13 +975,16 @@ allocDynAll haveDecl middle cls = do let middle' = fromMaybe mempty middle + decl_maybe i e + | haveDecl = toJExpr i |= e + | otherwise = i ||= e + makeObjs :: G JStat makeObjs = fmap mconcat $ forM cls $ \(i,f,_,cc) -> do ccs <- maybeToList <$> costCentreStackLbl cc pure $ mconcat - [ dec i - , toJExpr i |= if csInlineAlloc settings + [ decl_maybe i $ if csInlineAlloc settings then ValExpr (jhFromList $ [ (closureEntry_ , f) , (closureField1_, null_) , (closureField2_, null_) @@ -1022,8 +1023,6 @@ allocDynAll haveDecl middle cls = do fillFun [] = null_ fillFun es = ApplExpr (allocData (length es)) es - dec i | haveDecl = DeclStat i - | otherwise = mempty checkObjs | csAssertRts settings = mconcat $ map (\(i,_,_,_) -> ApplStat (ValExpr (JVar (TxtI "h$checkObj"))) [toJExpr i]) cls | otherwise = mempty ===================================== compiler/GHC/StgToJS/FFI.hs ===================================== @@ -117,8 +117,7 @@ parseFFIPatternA True True pat t es as = do , ReturnStat $ ApplExpr (var "h$takeMVar") [toJExpr x .^ "mv"] ]) (mconcat - [ DeclStat d - , toJExpr d |= toJExpr x .^ "mv" + [ d ||= toJExpr x .^ "mv" , copyResult (toJExpr d) ]) ] ===================================== compiler/GHC/StgToJS/Ids.hs ===================================== @@ -225,6 +225,6 @@ varForDataConWorker d = varForDataConEntryId (dataConWorkId d) declVarsForId :: Id -> G JStat declVarsForId i = case typeSize (idType i) of 0 -> return mempty - 1 -> DeclStat <$> identForId i - s -> mconcat <$> mapM (\n -> DeclStat <$> identForIdN i n) [1..s] + 1 -> decl <$> identForId i + s -> mconcat <$> mapM (\n -> decl <$> identForIdN i n) [1..s] ===================================== compiler/GHC/StgToJS/Linker/Compactor.hs ===================================== @@ -156,7 +156,7 @@ staticDeclStat :: StaticInfo -> JStat staticDeclStat (StaticInfo global_name static_value _) = decl where global_ident = TxtI global_name - decl_init v = DeclStat global_ident `mappend` (toJExpr global_ident |= v) + decl_init v = global_ident ||= v decl_no_init = appS "h$di" [toJExpr global_ident] decl = case static_value of @@ -299,9 +299,7 @@ renderBuildFunctions normalBfs cycleBreakerBfs = body = ReturnStat $ ApplExpr (ValExpr (JVar (TxtI $ cbName n))) (map (ValExpr . JVar) args) bfn = bfName bf - in DeclStat (TxtI bfn) <> - AssignStat (ValExpr (JVar (TxtI bfn))) - (ValExpr (JFunc args body)) + in (TxtI bfn) ||= (ValExpr (JFunc args body)) cycleBr2 = renderCbr $ \bf n -> renderBuildFunction (bf { bfName = cbName n }) data BuildFunction = BuildFunction @@ -369,7 +367,7 @@ rewriteBodies globals idx1 idx2 input = (bfsNormal, bfsCycleBreaker, input') removeDecls :: UniqSet FastString -> JStat -> JStat removeDecls t (BlockStat ss) = BlockStat (map (removeDecls t) ss) - removeDecls t (DeclStat (TxtI i)) + removeDecls t (DeclStat (TxtI i) _) | elementOfUniqSet i t = mempty removeDecls _ s = s @@ -408,9 +406,7 @@ rewriteBodies globals idx1 idx2 input = (bfsNormal, bfsCycleBreaker, input') -> JStat -> JStat createFunction _i idx g args body = - DeclStat bi <> - AssignStat (ValExpr (JVar bi)) - (ValExpr (JFunc bargs bbody)) + bi ||= ValExpr (JFunc bargs bbody) where ng = length g bi = buildFunId idx @@ -425,9 +421,7 @@ rewriteBodies globals idx1 idx2 input = (bfsNormal, bfsCycleBreaker, input') renderBuildFunction :: BuildFunction -> JStat renderBuildFunction (BuildFunction i bfid deps _nargs) = - DeclStat (TxtI i) <> - AssignStat (ValExpr (JVar (TxtI i))) - (ApplExpr (ValExpr (JVar bfid)) (map (ValExpr . JVar . TxtI) deps)) + (TxtI i) ||= (ApplExpr (ValExpr (JVar bfid)) (map (ValExpr . JVar . TxtI) deps)) dedupeBody :: Int -> Int -> Bool dedupeBody n size @@ -447,9 +441,9 @@ findGlobals globals stat = filter isGlobal . map itxt . uniqDSetToList $ identsS isGlobal i = elementOfUniqSet i globals && not (elementOfUniqSet i locals) findLocals :: JStat -> [FastString] -findLocals (BlockStat ss) = concatMap findLocals ss -findLocals (DeclStat (TxtI i)) = [i] -findLocals _ = [] +findLocals (BlockStat ss) = concatMap findLocals ss +findLocals (DeclStat (TxtI i) _) = [i] +findLocals _ = [] data HashIdx = HashIdx (UniqMap FastString Hash) (Map Hash FastString) @@ -492,12 +486,12 @@ dedupeStat :: HashIdx -> JStat -> JStat dedupeStat hi = go where go (BlockStat ss) = BlockStat (map go ss) - go s@(DeclStat (TxtI i)) + go s@(DeclStat (TxtI i) _) | not (isCanon hi i) = mempty - | otherwise = s + | otherwise = s go (AssignStat v@(ValExpr (JVar (TxtI i))) e) | not (isCanon hi i) = mempty - | otherwise = AssignStat v (identsE' (toCanonI hi) e) + | otherwise = AssignStat v (identsE' (toCanonI hi) e) -- rewrite identifiers in e go s = identsS' (toCanonI hi) s @@ -806,7 +800,7 @@ identsV' f (JFunc args s) = JFunc (fmap f args) (identsS' f s) identsV' _ UnsatVal{} = error "identsV': UnsatVal" identsS' :: (Ident -> Ident) -> JStat -> JStat -identsS' f (DeclStat i) = DeclStat $! f i +identsS' f (DeclStat i e) = DeclStat (f i) e identsS' f (ReturnStat e) = ReturnStat $! identsE' f e identsS' f (IfStat e s1 s2) = IfStat (identsE' f e) (identsS' f s1) (identsS' f s2) identsS' f (WhileStat b e s) = WhileStat b (identsE' f e) (identsS' f s) ===================================== compiler/GHC/StgToJS/Linker/Types.hs ===================================== @@ -43,28 +43,22 @@ import System.IO import Prelude --- | return a list of fresh @Ident@ +-- | Return a list of fresh local @Ident@ +-- +-- Prefix them with 'h$$' such that these will be compacted by the compactor. newLocals :: [Ident] -newLocals = filter (not . isJsKeyword) $ - map (TxtI . mkFastString) $ - map (:[]) chars0 ++ concatMap mkIdents [1..] +newLocals = mkIdents 0 where - mkIdents n = [c0:cs | c0 <- chars0, cs <- replicateM n chars] - chars0 = ['a'..'z']++['A'..'Z'] - chars = chars0++['0'..'9'] - --- | Rename @newLocals@ to 'h$$' such that these will be compacted by the --- compactor. -renamedVars :: [Ident] -renamedVars = map (\(TxtI xs) -> TxtI ("h$$"<>xs)) newLocals - + mkIdent s = TxtI (mkFastString ("h$$" <> s)) + mkIdents n = [mkIdent (c0:cs) | c0 <- chars, cs <- replicateM n chars] ++ mkIdents (n+1) + chars = ['0'..'9'] ++ ['a'..'z'] ++ ['A'..'Z'] -------------------------------------------------------------------------------- -- CompactorState -------------------------------------------------------------------------------- data CompactorState = CompactorState - { csIdentSupply :: [Ident] -- ^ ident supply for new names + { csIdentSupply :: ![Ident] -- ^ ident supply for new names , csNameMap :: !(UniqMap FastString Ident) -- ^ renaming mapping for internal names , csEntries :: !(UniqMap FastString Int) -- ^ entry functions (these get listed in the metadata init -- array) @@ -91,7 +85,7 @@ data StringTable = StringTable -- | The empty @CompactorState@ emptyCompactorState :: CompactorState -emptyCompactorState = CompactorState renamedVars +emptyCompactorState = CompactorState newLocals mempty mempty 0 @@ -121,14 +115,6 @@ entries :: Functor f entries f cs = fmap (\x -> cs { csEntries = x }) (f $ csEntries cs) {-# INLINE entries #-} --- | Update @csIdentSupply@ in @CompactorState@ -identSupply :: Functor f - => ([Ident] -> f [Ident]) - -> CompactorState - -> f CompactorState -identSupply f cs = fmap (\x -> cs { csIdentSupply = x }) (f $ csIdentSupply cs) -{-# INLINE identSupply #-} - -- | Update @csLabels@ in @CompactorState@ labels :: Functor f => (UniqMap FastString Int -> f (UniqMap FastString Int)) ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -32,7 +32,6 @@ import qualified Data.ByteString.Char8 as Char8 import Data.ByteString (ByteString) import GHC.Driver.Session -import GHC.Settings.Config (cProjectVersion) import GHC.Data.ShortText import GHC.Unit.State @@ -43,25 +42,10 @@ import GHC.StgToJS.Types import Prelude import GHC.Platform import Data.List (isPrefixOf) -import System.Directory (createDirectoryIfMissing) import System.IO import Data.Char (isSpace) -import qualified Data.ByteString as B import qualified Control.Exception as Exception --- | Given a FilePath and payload, write a file to disk creating any directories --- along the way if needed. -writeBinaryFile :: FilePath -> ByteString -> IO () -writeBinaryFile file bs = do - createDirectoryIfMissing True (takeDirectory file) - withBinaryFile file WriteMode $ \h -> mapM_ (B.hPut h) (chunks bs) - where - -- split the ByteString into a nonempty list of chunks of at most 1GiB - chunks :: ByteString -> [ByteString] - chunks b = - let (b1, b2) = B.splitAt 1073741824 b - in b1 : if B.null b1 then [] else chunks b2 - -- | Retrieve library directories provided by the @UnitId@ in @UnitState@ getInstalledPackageLibDirs :: UnitState -> UnitId -> [FilePath] getInstalledPackageLibDirs us = fmap unpack . maybe mempty unitLibraryDirs . lookupUnitId us @@ -70,10 +54,6 @@ getInstalledPackageLibDirs us = fmap unpack . maybe mempty unitLibraryDirs . loo getInstalledPackageHsLibs :: UnitState -> UnitId -> [String] getInstalledPackageHsLibs us = fmap unpack . maybe mempty unitLibraries . lookupUnitId us --- | A constant holding the compiler version -getCompilerVersion :: String -getCompilerVersion = cProjectVersion - -- | A constant holding the JavaScript executable Filename extension jsexeExtension :: String jsexeExtension = "jsexe" ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -404,7 +404,7 @@ instance Binary ExpFun where get bh = ExpFun <$> get bh <*> get bh <*> get bh instance Binary JStat where - put_ bh (DeclStat i) = putByte bh 1 >> put_ bh i + put_ bh (DeclStat i e) = putByte bh 1 >> put_ bh i >> put_ bh e put_ bh (ReturnStat e) = putByte bh 2 >> put_ bh e put_ bh (IfStat e s1 s2) = putByte bh 3 >> put_ bh e >> put_ bh s1 >> put_ bh s2 put_ bh (WhileStat b e s) = putByte bh 4 >> put_ bh b >> put_ bh e >> put_ bh s @@ -420,7 +420,7 @@ instance Binary JStat where put_ bh (BreakStat ml) = putByte bh 13 >> put_ bh ml put_ bh (ContinueStat ml) = putByte bh 14 >> put_ bh ml get bh = getByte bh >>= \case - 1 -> DeclStat <$> get bh + 1 -> DeclStat <$> get bh <*> get bh 2 -> ReturnStat <$> get bh 3 -> IfStat <$> get bh <*> get bh <*> get bh 4 -> WhileStat <$> get bh <*> get bh <*> get bh ===================================== compiler/GHC/StgToJS/Printer.hs ===================================== @@ -81,13 +81,26 @@ prettyBlock r xs = vcat $ map addSemi (prettyBlock' r xs) -- recognize common patterns in a block and convert them to more idiomatic/concise javascript prettyBlock' :: RenderJs -> [JStat] -> [Doc] +-- return/... +prettyBlock' r ( x@(ReturnStat _) + : xs + ) + | not (null xs) + = prettyBlock' r [x] +-- declare/assign +prettyBlock' r ( (DeclStat i Nothing) + : (AssignStat (ValExpr (JVar i')) v) + : xs + ) + | i == i' + = prettyBlock' r (DeclStat i (Just v) : xs) + -- resugar for loops with/without var declaration -prettyBlock' r ( (DeclStat i) - : (AssignStat (ValExpr (JVar i')) v0) - : (WhileStat False p (BlockStat bs)) - : xs - ) - | i == i' && not (null flat) && isForUpdStat (last flat) +prettyBlock' r ( (DeclStat i (Just v0)) + : (WhileStat False p (BlockStat bs)) + : xs + ) + | not (null flat) && isForUpdStat (last flat) = mkFor r True i v0 p (last flat) (init flat) : prettyBlock' r xs where flat = flattenBlocks bs @@ -101,20 +114,12 @@ prettyBlock' r ( (AssignStat (ValExpr (JVar i)) v0) flat = flattenBlocks bs -- global function (does not preserve semantics but works for GHCJS) -prettyBlock' r ( (DeclStat i) - : (AssignStat (ValExpr (JVar i')) (ValExpr (JFunc is b))) +prettyBlock' r ( (DeclStat i (Just (ValExpr (JFunc is b)))) : xs ) - | i == i' = (hangBrace (text "function" <+> jsToDocR r i <> parens (fsep . punctuate comma . map (jsToDocR r) $ is)) + = (hangBrace (text "function" <+> jsToDocR r i <> parens (fsep . punctuate comma . map (jsToDocR r) $ is)) (jsToDocR r b) ) : prettyBlock' r xs --- declare/assign -prettyBlock' r ( (DeclStat i) - : (AssignStat (ValExpr (JVar i')) v) - : xs - ) - | i == i' = (text "var" <+> jsToDocR r i <+> char '=' <+> jsToDocR r v) : prettyBlock' r xs - -- modify/assign operators prettyBlock' r ( (AssignStat (ValExpr (JVar i)) (InfixExpr AddOp (ValExpr (JVar i')) (ValExpr (JInt 1)))) : xs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0015d2d96866b09142cf58fcc27ef4ffbfcda9bc...21ef7cfbc466fbd92a80390ef2b575e8a713f12f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0015d2d96866b09142cf58fcc27ef4ffbfcda9bc...21ef7cfbc466fbd92a80390ef2b575e8a713f12f You're receiving 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 Oct 12 18:12:29 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 14:12:29 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: remove name shadowing Message-ID: <6347038d129b8_2c5d7351478219297@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4925cf1d by Curran McConnell at 2022-10-12T14:12:02-04:00 remove name shadowing - - - - - 59cc893b by Tamar Christina at 2022-10-12T14:12:07-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5327ef91 by Charles Taylor at 2022-10-12T14:12:09-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 7 changed files: - compiler/GHC/Parser/Lexer.x - docs/users_guide/9.6.1-notes.rst - ghc/GHCi/UI/Monad.hs - libraries/base/GHC/IO/Windows/Handle.hsc - + testsuite/tests/overloadedrecflds/should_run/T11671_run.hs - + testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout - testsuite/tests/overloadedrecflds/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -163,6 +163,7 @@ $small = [$ascsmall $unismall \_] $uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $idchar = [$small $large $digit $uniidchar \'] +$labelchar = [$small $large $digit $uniidchar \' \.] $unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] @@ -451,7 +452,8 @@ $tab { warnTab } } <0> { - "#" @varid / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" $labelchar+ / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" \" / { ifExtension OverloadedLabelsBit } { lex_quoted_label } } <0> { @@ -2023,46 +2025,64 @@ lex_string_prag_comment mkTok span _buf _len _buf2 lex_string_tok :: Action lex_string_tok span buf _len _buf2 = do - tok <- lex_string "" + lexed <- lex_string (AI end bufEnd) <- getInput let - tok' = case tok of - ITprimstring _ bs -> ITprimstring (SourceText src) bs - ITstring _ s -> ITstring (SourceText src) s - _ -> panic "lex_string_tok" + tok = case lexed of + LexedPrimString s -> ITprimstring (SourceText src) (unsafeMkByteString s) + LexedRegularString s -> ITstring (SourceText src) (mkFastString s) src = lexemeToString buf (cur bufEnd - cur buf) - return (L (mkPsSpan (psSpanStart span) end) tok') + return $ L (mkPsSpan (psSpanStart span) end) tok -lex_string :: String -> P Token -lex_string s = do + +lex_quoted_label :: Action +lex_quoted_label span _buf _len _buf2 = do + s <- lex_string_helper "" + (AI end _) <- getInput + let + token = ITlabelvarid (mkFastString s) + start = psSpanStart span + + return $ L (mkPsSpan start end) token + + +data LexedString = LexedRegularString String | LexedPrimString String + +lex_string :: P LexedString +lex_string = do + s <- lex_string_helper "" + magicHash <- getBit MagicHashBit + if magicHash + then do + i <- getInput + case alexGetChar' i of + Just ('#',i) -> do + setInput i + when (any (> '\xFF') s) $ do + pState <- getPState + let msg = PsErrPrimStringInvalidChar + let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg + addError err + return $ LexedPrimString s + _other -> + return $ LexedRegularString s + else + return $ LexedRegularString s + + +lex_string_helper :: String -> P String +lex_string_helper s = do i <- getInput case alexGetChar' i of Nothing -> lit_error i Just ('"',i) -> do - setInput i - let s' = reverse s - magicHash <- getBit MagicHashBit - if magicHash - then do - i <- getInput - case alexGetChar' i of - Just ('#',i) -> do - setInput i - when (any (> '\xFF') s') $ do - pState <- getPState - let msg = PsErrPrimStringInvalidChar - let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg - addError err - return (ITprimstring (SourceText s') (unsafeMkByteString s')) - _other -> - return (ITstring (SourceText s') (mkFastString s')) - else - return (ITstring (SourceText s') (mkFastString s')) + setInput i + return (reverse s) Just ('\\',i) | Just ('&',i) <- next -> do - setInput i; lex_string s + setInput i; lex_string_helper s | Just (c,i) <- next, c <= '\x7f' && is_space c -> do -- is_space only works for <= '\x7f' (#3751, #5425) setInput i; lex_stringgap s @@ -2070,16 +2090,17 @@ lex_string s = do Just (c, i1) -> do case c of - '\\' -> do setInput i1; c' <- lex_escape; lex_string (c':s) - c | isAny c -> do setInput i1; lex_string (c:s) + '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s) + c | isAny c -> do setInput i1; lex_string_helper (c:s) _other -> lit_error i -lex_stringgap :: String -> P Token + +lex_stringgap :: String -> P String lex_stringgap s = do i <- getInput c <- getCharOrFail i case c of - '\\' -> lex_string s + '\\' -> lex_string_helper s c | c <= '\x7f' && is_space c -> lex_stringgap s -- is_space only works for <= '\x7f' (#3751, #5425) _other -> lit_error i ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -78,6 +78,15 @@ Language Then GHC will use the second quantified constraint to solve ``C a b Int``, as it has a strictly weaker precondition. +- GHC proposal `#170 Unrestricted OverloadedLabels + `_ + has been implemented. + This extends the variety syntax for constructing labels under :extension:`OverloadedLabels`. + Examples of newly allowed syntax: + - Leading capital letters: `#Foo` equivalant to `getLabel @"Foo"` + - Numeric characters: `#3.14` equivalent to `getLabel @"3.14"` + - Arbitrary strings: `#"Hello, World!"` equivalent to `getLabel @"Hello, World!"` + Compiler ~~~~~~~~ ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleInstances, DeriveFunctor, DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# OPTIONS -fno-warn-name-shadowing #-} ----------------------------------------------------------------------------- -- @@ -474,10 +473,10 @@ printStats dflags ActionStats{actionAllocs = mallocs, actionElapsedTime = secs} Just allocs -> text (separateThousands allocs) <+> text "bytes"))) where - separateThousands n = reverse . sep . reverse . show $ n - where sep n' + separateThousands n = reverse . separate . reverse . show $ n + where separate n' | n' `lengthAtMost` 3 = n' - | otherwise = take 3 n' ++ "," ++ sep (drop 3 n') + | otherwise = take 3 n' ++ "," ++ separate (drop 3 n') ----------------------------------------------------------------------------- -- reverting CAFs @@ -526,13 +525,13 @@ turnOffBuffering_ fhv = do liftIO $ evalIO interp fhv mkEvalWrapper :: GhcMonad m => String -> [String] -> m ForeignHValue -mkEvalWrapper progname args = +mkEvalWrapper progname' args' = runInternal $ GHC.compileParsedExprRemote - $ evalWrapper `GHC.mkHsApp` nlHsString progname - `GHC.mkHsApp` nlList (map nlHsString args) + $ evalWrapper' `GHC.mkHsApp` nlHsString progname' + `GHC.mkHsApp` nlList (map nlHsString args') where nlHsString = nlHsLit . mkHsString - evalWrapper = + evalWrapper' = GHC.nlHsVar $ RdrName.mkOrig gHC_GHCI_HELPERS (mkVarOcc "evalWrapper") -- | Run a 'GhcMonad' action to compile an expression for internal usage. ===================================== libraries/base/GHC/IO/Windows/Handle.hsc ===================================== @@ -576,24 +576,23 @@ consoleWriteNonBlocking hwnd ptr _offset bytes consoleRead :: Bool -> Io ConsoleHandle -> Ptr Word8 -> Word64 -> Int -> IO Int consoleRead blocking hwnd ptr _offset bytes - = withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> - alloca $ \res -> do - cooked <- isCooked hwnd - -- Cooked input must be handled differently when the STD handles are - -- attached to a real console handle. For File based handles we can't do - -- proper cooked inputs, but since the actions are async you would get - -- results as soon as available. - -- - -- For console handles We have to use a lower level API then ReadConsole, - -- namely we must use ReadConsoleInput which requires us to process - -- all console message manually. - -- - -- Do note that MSYS2 shells such as bash don't attach to a real handle, - -- and instead have by default a pipe/file based std handles. Which - -- means the cooked behaviour is best when used in a native Windows - -- terminal such as cmd, powershell or ConEmu. - case cooked || not blocking of - False -> do + = alloca $ \res -> do + cooked <- isCooked hwnd + -- Cooked input must be handled differently when the STD handles are + -- attached to a real console handle. For File based handles we can't do + -- proper cooked inputs, but since the actions are async you would get + -- results as soon as available. + -- + -- For console handles We have to use a lower level API then ReadConsole, + -- namely we must use ReadConsoleInput which requires us to process + -- all console message manually. + -- + -- Do note that MSYS2 shells such as bash don't attach to a real handle, + -- and instead have by default a pipe/file based std handles. Which + -- means the cooked behaviour is best when used in a native Windows + -- terminal such as cmd, powershell or ConEmu. + case cooked || not blocking of + False -> withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> do debugIO "consoleRead :: un-cooked I/O read." -- eotControl allows us to handle control characters like EOL -- without needing a newline, which would sort of defeat the point @@ -628,9 +627,9 @@ consoleRead blocking hwnd ptr _offset bytes -- characters as they are. Technically this function can handle any -- console event. Including mouse, window and virtual key events -- but for now I'm only interested in key presses. - let entries = fromIntegral $ reqBytes `div` (#size INPUT_RECORD) + let entries = fromIntegral $ bytes `div` (#size INPUT_RECORD) allocaBytes entries $ \p_inputs -> - maybeReadEvent p_inputs entries res w_ptr + maybeReadEvent p_inputs entries res ptr -- Check to see if we have been explicitly asked to do a non-blocking -- I/O, and if we were, make sure that if we didn't have any console @@ -657,6 +656,7 @@ consoleRead blocking hwnd ptr _offset bytes b_read <- fromIntegral <$> peek res read <- cobble b_read w_ptr p_inputs + debugIO $ "readEvent: =" ++ show read if read > 0 then return $ fromIntegral read else maybeReadEvent p_inputs entries res w_ptr @@ -665,7 +665,7 @@ consoleRead blocking hwnd ptr _offset bytes -- minimum required to know which key/sequences were pressed. To do -- this and prevent having to fully port the PINPUT_RECORD structure -- in Haskell we use some GCC builtins to find the correct offsets. - cobble :: Int -> Ptr Word16 -> PINPUT_RECORD -> IO Int + cobble :: Int -> Ptr Word8 -> PINPUT_RECORD -> IO Int cobble 0 _ _ = do debugIO "cobble: done." return 0 cobble n w_ptr p_inputs = @@ -690,8 +690,18 @@ consoleRead blocking hwnd ptr _offset bytes debugIO $ "cobble: offset - " ++ show char_offset debugIO $ "cobble: show > " ++ show char debugIO $ "cobble: repeat: " ++ show repeated + -- The documentation here is rather subtle, but + -- according to MSDN the uWChar being provided here + -- has been "translated". What this actually means + -- is that the surrogate pairs have already been + -- translated into byte sequences. That is, despite + -- the Word16 storage type, it's actually a byte + -- stream. This means we shouldn't try to decode + -- to UTF-8 again since we'd end up incorrectly + -- interpreting two bytes as an extended unicode + -- character. pokeArray w_ptr $ replicate repeated char - (+1) <$> cobble n' w_ptr' p_inputs' + (+repeated) <$> cobble n' w_ptr' p_inputs' else do debugIO $ "cobble: skip event." cobble n' w_ptr p_inputs' ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE MagicHash #-} + +import Data.Foldable (traverse_) +import Data.Proxy (Proxy(..)) +import GHC.OverloadedLabels (IsLabel(..)) +import GHC.TypeLits (KnownSymbol, symbolVal) +import GHC.Prim (Addr#) + +instance KnownSymbol symbol => IsLabel symbol String where + fromLabel = symbolVal (Proxy :: Proxy symbol) + +(#) :: String -> Int -> String +(#) _ i = show i + +f :: Addr# -> Int -> String +f _ i = show i + +main :: IO () +main = traverse_ putStrLn + [ #a + , #number17 + , #do + , #type + , #Foo + , #3 + , #199.4 + , #17a23b + , #f'a' + , #'a' + , #' + , #''notTHSplice + , #... + , #привет + , #こんにちは + , #"3" + , #":" + , #"Foo" + , #"The quick brown fox" + , #"\"" + , (++) #hello#world + , (++) #"hello"#"world" + , #"hello"# 1 -- equivalent to `(fromLabel @"hello") # 1` + , f "hello"#2 -- equivalent to `f ("hello"# :: Addr#) 2` + ] ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout ===================================== @@ -0,0 +1,24 @@ +a +number17 +do +type +Foo +3 +199.4 +17a23b +f'a' +'a' +' +''notTHSplice +... +привет +こんにちは +3 +: +Foo +The quick brown fox +" +helloworld +helloworld +1 +2 ===================================== testsuite/tests/overloadedrecflds/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('hasfieldrun01', normal, compile_and_run, ['']) test('hasfieldrun02', normal, compile_and_run, ['']) test('T12243', normal, compile_and_run, ['']) test('T11228', normal, compile_and_run, ['']) +test('T11671_run', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f3799362d9a5582ea433f7be582efe6d04d2369e...5327ef918c1f6bc9cadbb7bf900efa80bd1efdbe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f3799362d9a5582ea433f7be582efe6d04d2369e...5327ef918c1f6bc9cadbb7bf900efa80bd1efdbe You're receiving 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 Oct 12 19:08:24 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 15:08:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22282-tests Message-ID: <634710a839e27_2c5d7351464235567@gitlab.mail> Ben Gamari pushed new branch wip/T22282-tests at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22282-tests You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Oct 12 19:08:57 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 15:08:57 -0400 Subject: [Git][ghc/ghc][wip/T22282-tests] ncg/aarch64: Fix sub-word sign extension yet again Message-ID: <634710c980844_2c5d73513c4235756@gitlab.mail> Ben Gamari pushed to branch wip/T22282-tests at Glasgow Haskell Compiler / GHC Commits: aa7fb68b by Ben Gamari at 2022-10-12T15:08:38-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 1 changed file: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `appOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt w w' reg_x + (reg_y_sx, code_y_sx) <- signExt w w' reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' w') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aa7fb68b3e6e4bd20da5ff97d9e889dacd71214b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aa7fb68b3e6e4bd20da5ff97d9e889dacd71214b You're receiving 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 Oct 12 20:02:38 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:02:38 -0400 Subject: [Git][ghc/ghc][wip/foundation-tests] Use better random gen Message-ID: <63471d5e332dc_2c5d7351428243489@gitlab.mail> Matthew Pickering pushed to branch wip/foundation-tests at Glasgow Haskell Compiler / GHC Commits: b291f60f by Matthew Pickering at 2022-10-12T21:02:30+01:00 Use better random gen - - - - - 1 changed file: - testsuite/tests/numeric/should_run/foundation.hs Changes: ===================================== testsuite/tests/numeric/should_run/foundation.hs ===================================== @@ -5,6 +5,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE MagicHash #-} +{-# LANGUAGE RecordWildCards #-} module Main ( main ) where @@ -24,13 +25,14 @@ import Foreign.Marshal.Alloc import Foreign.Storable import Foreign.Ptr import Data.List (intercalate) +import Data.IORef +import Unsafe.Coerce #include "MachDeps.h" -newtype Gen a = Gen { runGen :: (ReaderT Handle IO a) } +newtype Gen a = Gen { runGen :: (ReaderT LCGGen IO a) } deriving newtype (Functor, Applicative, Monad) --- | A version of "Arbitrary" but which just runs on numbers up to a certain bound. class Arbitrary a where arbitrary :: Gen a @@ -82,6 +84,129 @@ data Test where Property :: IsProperty prop => String -> prop -> Test +arbitraryInt64 :: Gen Int64 +arbitraryInt64 = Gen $ do + h <- ask + W64# w <- liftIO (randomWord64 h) + return (I64# (unsafeCoerce# w)) + +integralDownsize :: (Integral a) => Int64 -> a +integralDownsize = fromIntegral + +wordDownsize :: (Integral a) => Word64 -> a +wordDownsize = fromIntegral + +arbitraryWord64 :: Gen Word64 +arbitraryWord64 = Gen $ do + h <- ask + liftIO (randomWord64 h) + +instance Arbitrary Natural where + arbitrary = integralDownsize . (`mod` 10000) . abs <$> arbitraryInt64 + +-- Bounded by Int64 +instance Arbitrary Integer where + arbitrary = fromIntegral <$> arbitraryInt64 + +instance Arbitrary Int where + arbitrary = int64ToInt <$> arbitraryInt64 +instance Arbitrary Word where + arbitrary = word64ToWord <$> arbitraryWord64 +instance Arbitrary Word64 where + arbitrary = arbitraryWord64 +instance Arbitrary Word32 where + arbitrary = wordDownsize <$> arbitraryWord64 +instance Arbitrary Word16 where + arbitrary = wordDownsize <$> arbitraryWord64 +instance Arbitrary Word8 where + arbitrary = wordDownsize <$> arbitraryWord64 +instance Arbitrary Int64 where + arbitrary = arbitraryInt64 +instance Arbitrary Int32 where + arbitrary = integralDownsize <$> arbitraryInt64 +instance Arbitrary Int16 where + arbitrary = integralDownsize <$> arbitraryInt64 +instance Arbitrary Int8 where + arbitrary = integralDownsize <$> arbitraryInt64 + +int64ToInt :: Int64 -> Int +#if WORD_SIZE_IN_BITS == 64 +#if __GLASGOW_HASKELL__ >= 904 +int64ToInt (I64# i) = I# (int64ToInt# i) +#else +int64ToInt (I64# i) = I# i +#endif +#else +int64ToInt (I64# i) = I# (int64ToInt# i) +#endif + + +word64ToWord :: Word64 -> Word +#if WORD_SIZE_IN_BITS == 64 +#if __GLASGOW_HASKELL__ >= 904 +word64ToWord (W64# i) = W# (GHC.Prim.word64ToWord# i) +#else +word64ToWord (W64# i) = W# i +#endif +#else +word64ToWord (W64# i) = W# (word64ToWord# i) +#endif + + +data RunS = RunS { depth :: Int, rg :: LCGGen } + +newtype LCGGen = LCGGen { randomWord64 :: IO Word64 } + +data LCGParams = LCGParams { seed :: Word64, a :: Word64, c :: Word64, m :: Word64 } + +newLCGGen :: LCGParams -> IO LCGGen +newLCGGen LCGParams{..} = do + var <- newIORef (fromIntegral seed) + return $ LCGGen $ do + atomicModifyIORef' var (\old_v -> let new_val = (old_v * a + c) `mod` m in (new_val, new_val)) + + +runPropertyCheck (PropertyBinaryOp res desc s1 s2) = + if res then return True else (putMsg ("Failure: " ++ s1 ++ desc ++ s2) >> return False) +runPropertyCheck (PropertyAnd a1 a2) = (&&) <$> runPropertyCheck a1 <*> runPropertyCheck a2 + +runProperty :: Property -> ReaderT RunS IO () +runProperty (Prop p) = do + let iterations = 100 + loop iterations iterations + where + loop iterations 0 = putMsg ("Passed " ++ show iterations ++ " iterations") + loop iterations n = do + h <- rg <$> ask + p <- liftIO (runReaderT (runGen p) h) + let (ss, pc) = getCheck p + res <- runPropertyCheck pc + if res then loop iterations (n-1) + else putMsg ("With arguments " ++ intercalate ", " ss) + +putMsg s = do + n <- depth <$> ask + liftIO . putStrLn $ replicate (n * 2) ' ' ++ s + +nest = local (\s -> s { depth = depth s + 1 }) + +runTestInternal :: Test -> ReaderT RunS IO () +runTestInternal (Group name tests) = do + putMsg ("Group " ++ name) + nest (mapM_ runTestInternal tests) +runTestInternal (Property name p) = do + putMsg ("Running " ++ name) + nest $ runProperty (property p) + + +runTests :: Test -> IO () +runTests t = do + -- These params are the same ones as glibc uses. + h <- newLCGGen (LCGParams { seed = 1238123213, m = 2^31, a = 1103515245, c = 12345 }) + runReaderT (runTestInternal t) (RunS 0 h) + +------------------------------------------------------------------------------- + testIntegral :: forall a . (Arbitrary a, Show a, Integral a, Typeable a) => Proxy a -> Test testIntegral _ = Group "Integral" @@ -168,119 +293,5 @@ testNumberRefs = Group "ALL" ] - -arbitraryInt64 :: Gen Int64 -arbitraryInt64 = Gen $ do - h <- ask - liftIO $ - allocaBytes 8 $ \buf -> do - 8 <- hGetBuf h buf 8 - peek (castPtr buf) - -integralDownsize :: (Integral a) => Int64 -> a -integralDownsize = fromIntegral - -wordDownsize :: (Integral a) => Word64 -> a -wordDownsize = fromIntegral - -arbitraryWord64 :: Gen Word64 -arbitraryWord64 = Gen $ do - h <- ask - liftIO $ - allocaBytes 8 $ \buf -> do - 8 <- hGetBuf h buf 8 - peek (castPtr buf) - -instance Arbitrary Natural where - arbitrary = integralDownsize . (`mod` 10000) . abs <$> arbitraryInt64 - --- Bounded by Int64 -instance Arbitrary Integer where - arbitrary = fromIntegral <$> arbitraryInt64 - -instance Arbitrary Int where - arbitrary = int64ToInt <$> arbitraryInt64 -instance Arbitrary Word where - arbitrary = word64ToWord <$> arbitraryWord64 -instance Arbitrary Word64 where - arbitrary = arbitraryWord64 -instance Arbitrary Word32 where - arbitrary = wordDownsize <$> arbitraryWord64 -instance Arbitrary Word16 where - arbitrary = wordDownsize <$> arbitraryWord64 -instance Arbitrary Word8 where - arbitrary = wordDownsize <$> arbitraryWord64 -instance Arbitrary Int64 where - arbitrary = arbitraryInt64 -instance Arbitrary Int32 where - arbitrary = integralDownsize <$> arbitraryInt64 -instance Arbitrary Int16 where - arbitrary = integralDownsize <$> arbitraryInt64 -instance Arbitrary Int8 where - arbitrary = integralDownsize <$> arbitraryInt64 - -data RunS = RunS { depth :: Int, rg :: Handle } - - -runPropertyCheck (PropertyBinaryOp res desc s1 s2) = - if res then return True else (putMsg ("Failure: " ++ s1 ++ desc ++ s2) >> return False) -runPropertyCheck (PropertyAnd a1 a2) = (&&) <$> runPropertyCheck a1 <*> runPropertyCheck a2 - -runProperty :: Property -> ReaderT RunS IO () -runProperty (Prop p) = do - let iterations = 100 - loop iterations iterations - where - loop iterations 0 = putMsg ("Passed " ++ show iterations ++ " iterations") - loop iterations n = do - h <- rg <$> ask - p <- liftIO (runReaderT (runGen p) h) - let (ss, pc) = getCheck p - res <- runPropertyCheck pc - if res then loop iterations (n-1) - else putMsg ("With arguments " ++ intercalate ", " ss) - -putMsg s = do - n <- depth <$> ask - liftIO . putStrLn $ replicate (n * 2) ' ' ++ s - - -nest = local (\s -> s { depth = depth s + 1 }) - -runTestInternal :: Test -> ReaderT RunS IO () -runTestInternal (Group name tests) = do - putMsg ("Group " ++ name) - nest (mapM_ runTestInternal tests) -runTestInternal (Property name p) = do - putMsg ("Running " ++ name) - nest $ runProperty (property p) - -runTests :: Test -> IO () -runTests t = do - h <- openFile ("/dev/urandom") ReadMode - runReaderT (runTestInternal t) (RunS 0 h) - main = runTests testNumberRefs -int64ToInt :: Int64 -> Int -#if WORD_SIZE_IN_BITS == 64 -#if __GLASGOW_HASKELL__ >= 904 -int64ToInt (I64# i) = I# (int64ToInt# i) -#else -int64ToInt (I64# i) = I# i -#endif -#else -int64ToInt (I64# i) = I# (int64ToInt# i) -#endif - - -word64ToWord :: Word64 -> Word -#if WORD_SIZE_IN_BITS == 64 -#if __GLASGOW_HASKELL__ >= 904 -word64ToWord (W64# i) = W# (GHC.Prim.word64ToWord# i) -#else -word64ToWord (W64# i) = W# i -#endif -#else -word64ToWord (W64# i) = W# (word64ToWord# i) -#endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b291f60fd9c22e23b560202ab20546b50330d148 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b291f60fd9c22e23b560202ab20546b50330d148 You're receiving 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 Oct 12 20:11:05 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:11:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/splice-types Message-ID: <63471f5922949_2c5d73513ec25033d@gitlab.mail> Matthew Pickering pushed new branch wip/splice-types at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/splice-types You're receiving 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 Oct 12 20:15:21 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:15:21 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/configure-9.0-check Message-ID: <63472059c3fe_2c5d73514502541e9@gitlab.mail> Matthew Pickering pushed new branch wip/configure-9.0-check at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/configure-9.0-check You're receiving 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 Oct 12 20:15:50 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:15:50 -0400 Subject: [Git][ghc/ghc][wip/configure-9.0-check] configure: Bump minimum bootstrap GHC version Message-ID: <634720765a754_2c5d735143c254379@gitlab.mail> Matthew Pickering pushed to branch wip/configure-9.0-check at Glasgow Haskell Compiler / GHC Commits: 94584671 by Ben Gamari at 2022-10-12T21:15:22+01:00 configure: Bump minimum bootstrap GHC version Fixes #22245 - - - - - 1 changed file: - configure.ac Changes: ===================================== configure.ac ===================================== @@ -224,8 +224,9 @@ if test "$WithGhc" = "" then AC_MSG_ERROR([GHC is required.]) fi -FP_COMPARE_VERSIONS([$GhcVersion],[-lt],[8.10], - [AC_MSG_ERROR([GHC version 8.10 or later is required to compile GHC.])]) +MinBootGhcVersion="9.0" +FP_COMPARE_VERSIONS([$GhcVersion],[-lt],[$MinBootGhcVersion], + [AC_MSG_ERROR([GHC version $MinBootGhcVersion or later is required to compile GHC.])]) if test `expr $GhcMinVersion % 2` = "1" then View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94584671e69a170cc3121d16a5fa1a693be143af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94584671e69a170cc3121d16a5fa1a693be143af You're receiving 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 Oct 12 20:18:36 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 16:18:36 -0400 Subject: [Git][ghc/ghc][wip/T22282-tests] ncg/aarch64: Fix sub-word sign extension yet again Message-ID: <6347211c834f_2c5d735148c25641c@gitlab.mail> Ben Gamari pushed to branch wip/T22282-tests at Glasgow Haskell Compiler / GHC Commits: 5ebdbf07 by Ben Gamari at 2022-10-12T16:18:30-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 1 changed file: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ebdbf0716663278be16bed5425e193b8563cb64 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ebdbf0716663278be16bed5425e193b8563cb64 You're receiving 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 Oct 12 20:19:00 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:19:00 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/22253 Message-ID: <6347213494f33_2c5d73514282569ac@gitlab.mail> Matthew Pickering pushed new branch wip/22253 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/22253 You're receiving 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 Oct 12 20:19:11 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 12 Oct 2022 16:19:11 -0400 Subject: [Git][ghc/ghc][wip/22253] Build System: Remove out-of-date comment about make build system Message-ID: <6347213f2dccb_2c5d73515042571d8@gitlab.mail> Matthew Pickering pushed to branch wip/22253 at Glasgow Haskell Compiler / GHC Commits: 69151443 by Matthew Pickering at 2022-10-12T21:19:03+01:00 Build System: Remove out-of-date comment about make build system Both make and hadrian interleave compilation of modules of different modules and don't respect the package boundaries. Therefore I just remove this comment which points out this "difference". Fixes #22253 - - - - - 1 changed file: - libraries/base/GHC/Base.hs Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -162,10 +162,6 @@ resulting in: Failed to load interface for ‘GHC.Num.Integer’ There are files missing in the ‘ghc-bignum’ package, -Note that this is only a problem with the make-based build system. Hadrian -doesn't interleave compilation of modules from separate packages and respects -the dependency between `base` and `ghc-bignum`. - To ensure that GHC.Num.Integer is there, we must ensure that there is a visible dependency on GHC.Num.Integer from every module in base. We make GHC.Base depend on GHC.Num.Integer; and everything else either depends on GHC.Base, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6915144397ef17a21dd38a762af945ec5d5cc385 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6915144397ef17a21dd38a762af945ec5d5cc385 You're receiving 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 Oct 12 20:32:44 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 16:32:44 -0400 Subject: [Git][ghc/ghc][master] remove name shadowing Message-ID: <6347246cd1535_2c5d73514502631ae@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 1 changed file: - ghc/GHCi/UI/Monad.hs Changes: ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleInstances, DeriveFunctor, DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# OPTIONS -fno-warn-name-shadowing #-} ----------------------------------------------------------------------------- -- @@ -474,10 +473,10 @@ printStats dflags ActionStats{actionAllocs = mallocs, actionElapsedTime = secs} Just allocs -> text (separateThousands allocs) <+> text "bytes"))) where - separateThousands n = reverse . sep . reverse . show $ n - where sep n' + separateThousands n = reverse . separate . reverse . show $ n + where separate n' | n' `lengthAtMost` 3 = n' - | otherwise = take 3 n' ++ "," ++ sep (drop 3 n') + | otherwise = take 3 n' ++ "," ++ separate (drop 3 n') ----------------------------------------------------------------------------- -- reverting CAFs @@ -526,13 +525,13 @@ turnOffBuffering_ fhv = do liftIO $ evalIO interp fhv mkEvalWrapper :: GhcMonad m => String -> [String] -> m ForeignHValue -mkEvalWrapper progname args = +mkEvalWrapper progname' args' = runInternal $ GHC.compileParsedExprRemote - $ evalWrapper `GHC.mkHsApp` nlHsString progname - `GHC.mkHsApp` nlList (map nlHsString args) + $ evalWrapper' `GHC.mkHsApp` nlHsString progname' + `GHC.mkHsApp` nlList (map nlHsString args') where nlHsString = nlHsLit . mkHsString - evalWrapper = + evalWrapper' = GHC.nlHsVar $ RdrName.mkOrig gHC_GHCI_HELPERS (mkVarOcc "evalWrapper") -- | Run a 'GhcMonad' action to compile an expression for internal usage. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/819150893a9af7ee0770aba64b140bf1bc54957b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/819150893a9af7ee0770aba64b140bf1bc54957b You're receiving 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 Oct 12 20:33:29 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 16:33:29 -0400 Subject: [Git][ghc/ghc][master] winio: do not re-translate input when handle is uncooked Message-ID: <634724994f5ae_2c5d7351450266852@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 1 changed file: - libraries/base/GHC/IO/Windows/Handle.hsc Changes: ===================================== libraries/base/GHC/IO/Windows/Handle.hsc ===================================== @@ -576,24 +576,23 @@ consoleWriteNonBlocking hwnd ptr _offset bytes consoleRead :: Bool -> Io ConsoleHandle -> Ptr Word8 -> Word64 -> Int -> IO Int consoleRead blocking hwnd ptr _offset bytes - = withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> - alloca $ \res -> do - cooked <- isCooked hwnd - -- Cooked input must be handled differently when the STD handles are - -- attached to a real console handle. For File based handles we can't do - -- proper cooked inputs, but since the actions are async you would get - -- results as soon as available. - -- - -- For console handles We have to use a lower level API then ReadConsole, - -- namely we must use ReadConsoleInput which requires us to process - -- all console message manually. - -- - -- Do note that MSYS2 shells such as bash don't attach to a real handle, - -- and instead have by default a pipe/file based std handles. Which - -- means the cooked behaviour is best when used in a native Windows - -- terminal such as cmd, powershell or ConEmu. - case cooked || not blocking of - False -> do + = alloca $ \res -> do + cooked <- isCooked hwnd + -- Cooked input must be handled differently when the STD handles are + -- attached to a real console handle. For File based handles we can't do + -- proper cooked inputs, but since the actions are async you would get + -- results as soon as available. + -- + -- For console handles We have to use a lower level API then ReadConsole, + -- namely we must use ReadConsoleInput which requires us to process + -- all console message manually. + -- + -- Do note that MSYS2 shells such as bash don't attach to a real handle, + -- and instead have by default a pipe/file based std handles. Which + -- means the cooked behaviour is best when used in a native Windows + -- terminal such as cmd, powershell or ConEmu. + case cooked || not blocking of + False -> withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> do debugIO "consoleRead :: un-cooked I/O read." -- eotControl allows us to handle control characters like EOL -- without needing a newline, which would sort of defeat the point @@ -628,9 +627,9 @@ consoleRead blocking hwnd ptr _offset bytes -- characters as they are. Technically this function can handle any -- console event. Including mouse, window and virtual key events -- but for now I'm only interested in key presses. - let entries = fromIntegral $ reqBytes `div` (#size INPUT_RECORD) + let entries = fromIntegral $ bytes `div` (#size INPUT_RECORD) allocaBytes entries $ \p_inputs -> - maybeReadEvent p_inputs entries res w_ptr + maybeReadEvent p_inputs entries res ptr -- Check to see if we have been explicitly asked to do a non-blocking -- I/O, and if we were, make sure that if we didn't have any console @@ -657,6 +656,7 @@ consoleRead blocking hwnd ptr _offset bytes b_read <- fromIntegral <$> peek res read <- cobble b_read w_ptr p_inputs + debugIO $ "readEvent: =" ++ show read if read > 0 then return $ fromIntegral read else maybeReadEvent p_inputs entries res w_ptr @@ -665,7 +665,7 @@ consoleRead blocking hwnd ptr _offset bytes -- minimum required to know which key/sequences were pressed. To do -- this and prevent having to fully port the PINPUT_RECORD structure -- in Haskell we use some GCC builtins to find the correct offsets. - cobble :: Int -> Ptr Word16 -> PINPUT_RECORD -> IO Int + cobble :: Int -> Ptr Word8 -> PINPUT_RECORD -> IO Int cobble 0 _ _ = do debugIO "cobble: done." return 0 cobble n w_ptr p_inputs = @@ -690,8 +690,18 @@ consoleRead blocking hwnd ptr _offset bytes debugIO $ "cobble: offset - " ++ show char_offset debugIO $ "cobble: show > " ++ show char debugIO $ "cobble: repeat: " ++ show repeated + -- The documentation here is rather subtle, but + -- according to MSDN the uWChar being provided here + -- has been "translated". What this actually means + -- is that the surrogate pairs have already been + -- translated into byte sequences. That is, despite + -- the Word16 storage type, it's actually a byte + -- stream. This means we shouldn't try to decode + -- to UTF-8 again since we'd end up incorrectly + -- interpreting two bytes as an extended unicode + -- character. pokeArray w_ptr $ replicate repeated char - (+1) <$> cobble n' w_ptr' p_inputs' + (+repeated) <$> cobble n' w_ptr' p_inputs' else do debugIO $ "cobble: skip event." cobble n' w_ptr p_inputs' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/626652f7c172f307bd87afaee59c7f0e2825c55d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/626652f7c172f307bd87afaee59c7f0e2825c55d You're receiving 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 Oct 12 20:34:17 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 16:34:17 -0400 Subject: [Git][ghc/ghc][master] Unrestricted OverloadedLabels (#11671) Message-ID: <634724c9d3d30_2c5d7351464273348@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 5 changed files: - compiler/GHC/Parser/Lexer.x - docs/users_guide/9.6.1-notes.rst - + testsuite/tests/overloadedrecflds/should_run/T11671_run.hs - + testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout - testsuite/tests/overloadedrecflds/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -163,6 +163,7 @@ $small = [$ascsmall $unismall \_] $uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $idchar = [$small $large $digit $uniidchar \'] +$labelchar = [$small $large $digit $uniidchar \' \.] $unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] @@ -451,7 +452,8 @@ $tab { warnTab } } <0> { - "#" @varid / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" $labelchar+ / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" \" / { ifExtension OverloadedLabelsBit } { lex_quoted_label } } <0> { @@ -2023,46 +2025,64 @@ lex_string_prag_comment mkTok span _buf _len _buf2 lex_string_tok :: Action lex_string_tok span buf _len _buf2 = do - tok <- lex_string "" + lexed <- lex_string (AI end bufEnd) <- getInput let - tok' = case tok of - ITprimstring _ bs -> ITprimstring (SourceText src) bs - ITstring _ s -> ITstring (SourceText src) s - _ -> panic "lex_string_tok" + tok = case lexed of + LexedPrimString s -> ITprimstring (SourceText src) (unsafeMkByteString s) + LexedRegularString s -> ITstring (SourceText src) (mkFastString s) src = lexemeToString buf (cur bufEnd - cur buf) - return (L (mkPsSpan (psSpanStart span) end) tok') + return $ L (mkPsSpan (psSpanStart span) end) tok -lex_string :: String -> P Token -lex_string s = do + +lex_quoted_label :: Action +lex_quoted_label span _buf _len _buf2 = do + s <- lex_string_helper "" + (AI end _) <- getInput + let + token = ITlabelvarid (mkFastString s) + start = psSpanStart span + + return $ L (mkPsSpan start end) token + + +data LexedString = LexedRegularString String | LexedPrimString String + +lex_string :: P LexedString +lex_string = do + s <- lex_string_helper "" + magicHash <- getBit MagicHashBit + if magicHash + then do + i <- getInput + case alexGetChar' i of + Just ('#',i) -> do + setInput i + when (any (> '\xFF') s) $ do + pState <- getPState + let msg = PsErrPrimStringInvalidChar + let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg + addError err + return $ LexedPrimString s + _other -> + return $ LexedRegularString s + else + return $ LexedRegularString s + + +lex_string_helper :: String -> P String +lex_string_helper s = do i <- getInput case alexGetChar' i of Nothing -> lit_error i Just ('"',i) -> do - setInput i - let s' = reverse s - magicHash <- getBit MagicHashBit - if magicHash - then do - i <- getInput - case alexGetChar' i of - Just ('#',i) -> do - setInput i - when (any (> '\xFF') s') $ do - pState <- getPState - let msg = PsErrPrimStringInvalidChar - let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg - addError err - return (ITprimstring (SourceText s') (unsafeMkByteString s')) - _other -> - return (ITstring (SourceText s') (mkFastString s')) - else - return (ITstring (SourceText s') (mkFastString s')) + setInput i + return (reverse s) Just ('\\',i) | Just ('&',i) <- next -> do - setInput i; lex_string s + setInput i; lex_string_helper s | Just (c,i) <- next, c <= '\x7f' && is_space c -> do -- is_space only works for <= '\x7f' (#3751, #5425) setInput i; lex_stringgap s @@ -2070,16 +2090,17 @@ lex_string s = do Just (c, i1) -> do case c of - '\\' -> do setInput i1; c' <- lex_escape; lex_string (c':s) - c | isAny c -> do setInput i1; lex_string (c:s) + '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s) + c | isAny c -> do setInput i1; lex_string_helper (c:s) _other -> lit_error i -lex_stringgap :: String -> P Token + +lex_stringgap :: String -> P String lex_stringgap s = do i <- getInput c <- getCharOrFail i case c of - '\\' -> lex_string s + '\\' -> lex_string_helper s c | c <= '\x7f' && is_space c -> lex_stringgap s -- is_space only works for <= '\x7f' (#3751, #5425) _other -> lit_error i ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -78,6 +78,15 @@ Language Then GHC will use the second quantified constraint to solve ``C a b Int``, as it has a strictly weaker precondition. +- GHC proposal `#170 Unrestricted OverloadedLabels + `_ + has been implemented. + This extends the variety syntax for constructing labels under :extension:`OverloadedLabels`. + Examples of newly allowed syntax: + - Leading capital letters: `#Foo` equivalant to `getLabel @"Foo"` + - Numeric characters: `#3.14` equivalent to `getLabel @"3.14"` + - Arbitrary strings: `#"Hello, World!"` equivalent to `getLabel @"Hello, World!"` + Compiler ~~~~~~~~ ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE MagicHash #-} + +import Data.Foldable (traverse_) +import Data.Proxy (Proxy(..)) +import GHC.OverloadedLabels (IsLabel(..)) +import GHC.TypeLits (KnownSymbol, symbolVal) +import GHC.Prim (Addr#) + +instance KnownSymbol symbol => IsLabel symbol String where + fromLabel = symbolVal (Proxy :: Proxy symbol) + +(#) :: String -> Int -> String +(#) _ i = show i + +f :: Addr# -> Int -> String +f _ i = show i + +main :: IO () +main = traverse_ putStrLn + [ #a + , #number17 + , #do + , #type + , #Foo + , #3 + , #199.4 + , #17a23b + , #f'a' + , #'a' + , #' + , #''notTHSplice + , #... + , #привет + , #こんにちは + , #"3" + , #":" + , #"Foo" + , #"The quick brown fox" + , #"\"" + , (++) #hello#world + , (++) #"hello"#"world" + , #"hello"# 1 -- equivalent to `(fromLabel @"hello") # 1` + , f "hello"#2 -- equivalent to `f ("hello"# :: Addr#) 2` + ] ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout ===================================== @@ -0,0 +1,24 @@ +a +number17 +do +type +Foo +3 +199.4 +17a23b +f'a' +'a' +' +''notTHSplice +... +привет +こんにちは +3 +: +Foo +The quick brown fox +" +helloworld +helloworld +1 +2 ===================================== testsuite/tests/overloadedrecflds/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('hasfieldrun01', normal, compile_and_run, ['']) test('hasfieldrun02', normal, compile_and_run, ['']) test('T12243', normal, compile_and_run, ['']) test('T11228', normal, compile_and_run, ['']) +test('T11671_run', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5172789a12dcca65574dc608364a7cbfdec2fe58 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5172789a12dcca65574dc608364a7cbfdec2fe58 You're receiving 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 Oct 12 21:25:38 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 17:25:38 -0400 Subject: [Git][ghc/ghc][wip/T22282-tests] 2 commits: testsuite: Add test for #22282 Message-ID: <634730d21e57c_2c5d7351464282693@gitlab.mail> Ben Gamari pushed to branch wip/T22282-tests at Glasgow Haskell Compiler / GHC Commits: 1004bff7 by Ben Gamari at 2022-10-12T17:25:32-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 0ae6d8b5 by Ben Gamari at 2022-10-12T17:25:32-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 5 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. ===================================== testsuite/tests/numeric/should_run/T22282.hs ===================================== @@ -0,0 +1,3 @@ +import T22282A + +main = print $ testF 217 161 ===================================== testsuite/tests/numeric/should_run/T22282.stdout ===================================== @@ -0,0 +1,2 @@ +217 + ===================================== testsuite/tests/numeric/should_run/T22282A.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE MagicHash #-} +module T22282A where + +import Data.Word +import GHC.Prim +import GHC.Word + +wtestF :: GHC.Prim.Word8# -> GHC.Prim.Word8# -> GHC.Prim.Word8# +wtestF a b = case word8ToWord# b of + 0## -> a + _ -> plusWord8# (timesWord8# (quotWord8# a b) b) (remWord8# a b) +{-# NOINLINE wtestF #-} + +testF :: Word8 -> Word8 -> Word8 +testF (W8# a) (W8# b) = W8# (wtestF a b) +{-# INLINE testF #-} + ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,3 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) +test('T22282', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5ebdbf0716663278be16bed5425e193b8563cb64...0ae6d8b5c798dfcdb0444ad69fd62124beb51b76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5ebdbf0716663278be16bed5425e193b8563cb64...0ae6d8b5c798dfcdb0444ad69fd62124beb51b76 You're receiving 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 Oct 12 21:56:56 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 17:56:56 -0400 Subject: [Git][ghc/ghc][wip/T22206] 27 commits: Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) Message-ID: <63473828b3641_2c5d73514782903b5@gitlab.mail> Ben Gamari pushed to branch wip/T22206 at Glasgow Haskell Compiler / GHC Commits: aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 8fcca7a5 by Ben Gamari at 2022-10-12T17:56:50-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/Stats.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Tidy.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/96c758af60299b38bc7cf2db2746c72598b12e92...8fcca7a555776b4d4d837024d58d300893a3233c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96c758af60299b38bc7cf2db2746c72598b12e92...8fcca7a555776b4d4d837024d58d300893a3233c You're receiving 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 Oct 12 22:29:13 2022 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 12 Oct 2022 18:29:13 -0400 Subject: [Git][ghc/ghc][wip/az/T21355-exactprint-update] 212 commits: typo Message-ID: <63473fb9301e4_2c5d735147829672@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T21355-exactprint-update at Glasgow Haskell Compiler / GHC Commits: ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 34adbd93 by Alan Zimmerman at 2022-10-12T23:28:50+01:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 30 changed files: - − .appveyor.sh - .editorconfig - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Liveness.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/05e0b475d779208b114981c7fa3b3fa33d2db1df...34adbd93b71d70f91f74e287977230a463ef61ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/05e0b475d779208b114981c7fa3b3fa33d2db1df...34adbd93b71d70f91f74e287977230a463ef61ce You're receiving 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 Oct 12 22:49:05 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 12 Oct 2022 18:49:05 -0400 Subject: [Git][ghc/ghc][wip/T21847] 68 commits: Document :unadd GHCi command in user guide Message-ID: <6347446155fc1_2c5d7351504297114@gitlab.mail> Andreas Klebinger pushed to branch wip/T21847 at Glasgow Haskell Compiler / GHC Commits: 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 5c50b521 by Ben Gamari at 2022-10-12T22:49:00+00:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - bfc95d1f by Ben Gamari at 2022-10-12T22:49:00+00:00 rts/linker: Add support for .fini sections - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3f7041493458f9c7e07f211fa6b2e9e0e84d4f2...bfc95d1feb0f91cbcd32f8c71e5dd32bec5a1e8e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3f7041493458f9c7e07f211fa6b2e9e0e84d4f2...bfc95d1feb0f91cbcd32f8c71e5dd32bec5a1e8e You're receiving 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 Oct 13 01:21:58 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Oct 2022 21:21:58 -0400 Subject: [Git][ghc/ghc][wip/T20155] 4 commits: Rip out hacks surrounding GHC.Prim and primops Message-ID: <63476836a7e2b_2c5d73513ec3188e4@gitlab.mail> Ben Gamari pushed to branch wip/T20155 at Glasgow Haskell Compiler / GHC Commits: 040736b3 by Ben Gamari at 2022-09-16T08:44:15-04:00 Rip out hacks surrounding GHC.Prim and primops - - - - - caaf4eac by Ben Gamari at 2022-09-26T19:41:57-04:00 primops Add missing primtype declaration for TYPE - - - - - 36311ed2 by Ben Gamari at 2022-10-12T19:40:21-04:00 IsInteresting - - - - - 81b78b19 by Ben Gamari at 2022-10-12T21:19:53-04:00 testsuite - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps/Ids.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Instance/Typeable.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/TyThing.hs-boot - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - ghc.mk The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45def1c4cd79ff649d637e16b823d01e59f77490...81b78b1969c4bc862ead14327973c070cc011520 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45def1c4cd79ff649d637e16b823d01e59f77490...81b78b1969c4bc862ead14327973c070cc011520 You're receiving 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 Oct 13 02:20:29 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Wed, 12 Oct 2022 22:20:29 -0400 Subject: [Git][ghc/ghc][wip/js-staging] JS: Note on JS .o file order, fix .o files Message-ID: <634775ed6eb0e_2c5d7351428324575@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 1913cd1d by doyougnu at 2022-10-12T22:18:49-04:00 JS: Note on JS .o file order, fix .o files To be specific: 1. add Note [JS Backend .o file procedure] 2. ensure that .o files are touch'd in JS backend postHsc phase. This fixes "missing object file" errors produced by 'GHC.Driver.Main.checkObjects'. - - - - - 2 changed files: - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/StgToJS/Linker/Linker.hs Changes: ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -346,7 +346,34 @@ runAsPhase with_cpp pipe_env hsc_env location input_fn = do return output_fn --- | Embed .js files into .o files +-- Note [JS Backend .o file procedure ] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- The JS backend breaks some of the assumptions on file generation order +-- because it directly produces .o files. This violation breaks some of the +-- assumptions on file timestamps, particularly in the postHsc phase. The +-- postHsc phase for the JS backend is performed in 'runJsPhase'. Consider +-- what the NCG does: +-- +-- With other NCG backends we have the following order: +-- 1. The backend produces a .s file +-- 2. Then we write the interface file, .hi +-- 3. Then we generate a .o file in a postHsc phase (calling the asm phase etc.) +-- +-- For the JS Backend this order is different +-- 1. The JS Backend _directly_ produces .o files (via +-- 'GHC.StgToJS.Linker.Linker.embedJsFile') +-- 2. Then we write the interface file. Notice that this breaks the ordering +-- of .hi > .o (step 2 and step 3 in the NCG above). +-- +-- This violation results in timestamp checks which pass on the NCG but fail +-- in the JS backend. In particular, checks that compare 'ms_obj_date', and +-- 'ms_iface_date' in 'GHC.Unit.Module.ModSummary'. +-- +-- Thus to fix this ordering we touch the object files we generated earlier +-- to ensure these timestamps abide by the proper ordering. + +-- | Run the JS Backend postHsc phase. runJsPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath runJsPhase pipe_env hsc_env input_fn = do let dflags = hsc_dflags hsc_env @@ -355,7 +382,16 @@ runJsPhase pipe_env hsc_env input_fn = do let unit_env = hsc_unit_env hsc_env output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env Nothing - embedJsFile logger dflags tmpfs unit_env input_fn output_fn + + -- if the input filename is the same as the output, then we've probably + -- generated the object ourselves. In this case, we touch the object file to + -- ensure the timestamp is refreshed, see Note [ JS Backend .o Files ]. If + -- they are not the same then we embed the .js file into a .o file with the + -- addition of a header + if (input_fn /= output_fn) + then embedJsFile logger dflags tmpfs unit_env input_fn output_fn + else touchObjectFile logger dflags output_fn + return output_fn ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -811,54 +811,50 @@ embedJsFile :: Logger -> DynFlags -> TmpFs -> UnitEnv -> FilePath -> FilePath -> embedJsFile logger dflags tmpfs unit_env input_fn output_fn = do let profiling = False -- FIXME: add support for profiling way - -- if the input filename is the same as the output, then we've probably - -- generated the object ourselves, we leave the file alone - when (input_fn /= output_fn) $ do - - -- the header lets the linker recognize processed JavaScript files - -- But don't add JavaScript header to object files! - - is_js_obj <- if True - then pure False - else isJsObjectFile input_fn - -- FIXME (Sylvain 2022-09): this call makes the - -- testsuite go into a loop, I don't know why yet! - -- Disabling it for now. - - if is_js_obj - then copyWithHeader "" input_fn output_fn - else do - -- header appended to JS files stored as .o to recognize them. - let header = "//JavaScript\n" - jsFileNeedsCpp input_fn >>= \case - False -> copyWithHeader header input_fn output_fn - True -> do - - -- append common CPP definitions to the .js file. - -- They define macros that avoid directly wiring zencoded names - -- in RTS JS files - pp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" - payload <- B.readFile input_fn - B.writeFile pp_fn (commonCppDefs profiling <> payload) - - -- run CPP on the input JS file - js_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" - let - cpp_opts = CppOpts - { cppUseCc = True - , cppLinePragmas = False -- LINE pragmas aren't JS compatible - } - extra_opts = [] - doCpp logger - tmpfs - dflags - unit_env - cpp_opts - extra_opts - pp_fn - js_fn - -- add header to recognize the object as a JS file - copyWithHeader header js_fn output_fn + -- the header lets the linker recognize processed JavaScript files + -- But don't add JavaScript header to object files! + + is_js_obj <- if True + then pure False + else isJsObjectFile input_fn + -- FIXME (Sylvain 2022-09): this call makes the + -- testsuite go into a loop, I don't know why yet! + -- Disabling it for now. + + if is_js_obj + then copyWithHeader "" input_fn output_fn + else do + -- header appended to JS files stored as .o to recognize them. + let header = "//JavaScript\n" + jsFileNeedsCpp input_fn >>= \case + False -> copyWithHeader header input_fn output_fn + True -> do + + -- append common CPP definitions to the .js file. + -- They define macros that avoid directly wiring zencoded names + -- in RTS JS files + pp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" + payload <- B.readFile input_fn + B.writeFile pp_fn (commonCppDefs profiling <> payload) + + -- run CPP on the input JS file + js_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js" + let + cpp_opts = CppOpts + { cppUseCc = True + , cppLinePragmas = False -- LINE pragmas aren't JS compatible + } + extra_opts = [] + doCpp logger + tmpfs + dflags + unit_env + cpp_opts + extra_opts + pp_fn + js_fn + -- add header to recognize the object as a JS file + copyWithHeader header js_fn output_fn jsFileNeedsCpp :: FilePath -> IO Bool jsFileNeedsCpp fn = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1913cd1da770c7258178f1e71b8de81fa7383a04 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1913cd1da770c7258178f1e71b8de81fa7383a04 You're receiving 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 Oct 13 02:38:01 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Oct 2022 22:38:01 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: remove name shadowing Message-ID: <63477a09da199_2c5d73513ec327070@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - 77be3115 by Andreas Klebinger at 2022-10-12T22:37:33-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 4838827c by Simon Hengel at 2022-10-12T22:37:38-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - 14 changed files: - compiler/GHC/Parser/Lexer.x - docs/users_guide/9.6.1-notes.rst - docs/users_guide/phases.rst - ghc/GHCi/UI/Monad.hs - libraries/base/GHC/IO/Windows/Handle.hsc - + testsuite/tests/overloadedrecflds/should_run/T11671_run.hs - + testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout - testsuite/tests/overloadedrecflds/should_run/all.T - + testsuite/tests/perf/compiler/T21839c.hs - + testsuite/tests/perf/compiler/T21839c.stdout - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/should_run/T21839r.hs - + testsuite/tests/perf/should_run/T21839r.stdout - testsuite/tests/perf/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -163,6 +163,7 @@ $small = [$ascsmall $unismall \_] $uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $idchar = [$small $large $digit $uniidchar \'] +$labelchar = [$small $large $digit $uniidchar \' \.] $unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. $graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] @@ -451,7 +452,8 @@ $tab { warnTab } } <0> { - "#" @varid / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" $labelchar+ / { ifExtension OverloadedLabelsBit } { skip_one_varid ITlabelvarid } + "#" \" / { ifExtension OverloadedLabelsBit } { lex_quoted_label } } <0> { @@ -2023,46 +2025,64 @@ lex_string_prag_comment mkTok span _buf _len _buf2 lex_string_tok :: Action lex_string_tok span buf _len _buf2 = do - tok <- lex_string "" + lexed <- lex_string (AI end bufEnd) <- getInput let - tok' = case tok of - ITprimstring _ bs -> ITprimstring (SourceText src) bs - ITstring _ s -> ITstring (SourceText src) s - _ -> panic "lex_string_tok" + tok = case lexed of + LexedPrimString s -> ITprimstring (SourceText src) (unsafeMkByteString s) + LexedRegularString s -> ITstring (SourceText src) (mkFastString s) src = lexemeToString buf (cur bufEnd - cur buf) - return (L (mkPsSpan (psSpanStart span) end) tok') + return $ L (mkPsSpan (psSpanStart span) end) tok -lex_string :: String -> P Token -lex_string s = do + +lex_quoted_label :: Action +lex_quoted_label span _buf _len _buf2 = do + s <- lex_string_helper "" + (AI end _) <- getInput + let + token = ITlabelvarid (mkFastString s) + start = psSpanStart span + + return $ L (mkPsSpan start end) token + + +data LexedString = LexedRegularString String | LexedPrimString String + +lex_string :: P LexedString +lex_string = do + s <- lex_string_helper "" + magicHash <- getBit MagicHashBit + if magicHash + then do + i <- getInput + case alexGetChar' i of + Just ('#',i) -> do + setInput i + when (any (> '\xFF') s) $ do + pState <- getPState + let msg = PsErrPrimStringInvalidChar + let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg + addError err + return $ LexedPrimString s + _other -> + return $ LexedRegularString s + else + return $ LexedRegularString s + + +lex_string_helper :: String -> P String +lex_string_helper s = do i <- getInput case alexGetChar' i of Nothing -> lit_error i Just ('"',i) -> do - setInput i - let s' = reverse s - magicHash <- getBit MagicHashBit - if magicHash - then do - i <- getInput - case alexGetChar' i of - Just ('#',i) -> do - setInput i - when (any (> '\xFF') s') $ do - pState <- getPState - let msg = PsErrPrimStringInvalidChar - let err = mkPlainErrorMsgEnvelope (mkSrcSpanPs (last_loc pState)) msg - addError err - return (ITprimstring (SourceText s') (unsafeMkByteString s')) - _other -> - return (ITstring (SourceText s') (mkFastString s')) - else - return (ITstring (SourceText s') (mkFastString s')) + setInput i + return (reverse s) Just ('\\',i) | Just ('&',i) <- next -> do - setInput i; lex_string s + setInput i; lex_string_helper s | Just (c,i) <- next, c <= '\x7f' && is_space c -> do -- is_space only works for <= '\x7f' (#3751, #5425) setInput i; lex_stringgap s @@ -2070,16 +2090,17 @@ lex_string s = do Just (c, i1) -> do case c of - '\\' -> do setInput i1; c' <- lex_escape; lex_string (c':s) - c | isAny c -> do setInput i1; lex_string (c:s) + '\\' -> do setInput i1; c' <- lex_escape; lex_string_helper (c':s) + c | isAny c -> do setInput i1; lex_string_helper (c:s) _other -> lit_error i -lex_stringgap :: String -> P Token + +lex_stringgap :: String -> P String lex_stringgap s = do i <- getInput c <- getCharOrFail i case c of - '\\' -> lex_string s + '\\' -> lex_string_helper s c | c <= '\x7f' && is_space c -> lex_stringgap s -- is_space only works for <= '\x7f' (#3751, #5425) _other -> lit_error i ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -78,6 +78,15 @@ Language Then GHC will use the second quantified constraint to solve ``C a b Int``, as it has a strictly weaker precondition. +- GHC proposal `#170 Unrestricted OverloadedLabels + `_ + has been implemented. + This extends the variety syntax for constructing labels under :extension:`OverloadedLabels`. + Examples of newly allowed syntax: + - Leading capital letters: `#Foo` equivalant to `getLabel @"Foo"` + - Numeric characters: `#3.14` equivalent to `getLabel @"3.14"` + - Arbitrary strings: `#"Hello, World!"` equivalent to `getLabel @"Hello, World!"` + Compiler ~~~~~~~~ ===================================== docs/users_guide/phases.rst ===================================== @@ -576,13 +576,13 @@ Options affecting a Haskell pre-processor .. code-block:: sh #!/bin/sh - ( echo "{-# LINE 1 \"$2\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3 + ( echo "{-# LINE 1 \"$1\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3 and pass ``-F -pgmF convert.sh`` to GHC. The ``-f l1`` option tells iconv to convert your Latin-1 file, supplied in argument ``$2``, while the "-t utf-8" options tell iconv to return a UTF-8 encoded file. The result is redirected into argument ``$3``. The - ``echo "{-# LINE 1 \"$2\" #-}"`` just makes sure that your error + ``echo "{-# LINE 1 \"$1\" #-}"`` just makes sure that your error positions are reported as in the original source file. .. _options-codegen: ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleInstances, DeriveFunctor, DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -{-# OPTIONS -fno-warn-name-shadowing #-} ----------------------------------------------------------------------------- -- @@ -474,10 +473,10 @@ printStats dflags ActionStats{actionAllocs = mallocs, actionElapsedTime = secs} Just allocs -> text (separateThousands allocs) <+> text "bytes"))) where - separateThousands n = reverse . sep . reverse . show $ n - where sep n' + separateThousands n = reverse . separate . reverse . show $ n + where separate n' | n' `lengthAtMost` 3 = n' - | otherwise = take 3 n' ++ "," ++ sep (drop 3 n') + | otherwise = take 3 n' ++ "," ++ separate (drop 3 n') ----------------------------------------------------------------------------- -- reverting CAFs @@ -526,13 +525,13 @@ turnOffBuffering_ fhv = do liftIO $ evalIO interp fhv mkEvalWrapper :: GhcMonad m => String -> [String] -> m ForeignHValue -mkEvalWrapper progname args = +mkEvalWrapper progname' args' = runInternal $ GHC.compileParsedExprRemote - $ evalWrapper `GHC.mkHsApp` nlHsString progname - `GHC.mkHsApp` nlList (map nlHsString args) + $ evalWrapper' `GHC.mkHsApp` nlHsString progname' + `GHC.mkHsApp` nlList (map nlHsString args') where nlHsString = nlHsLit . mkHsString - evalWrapper = + evalWrapper' = GHC.nlHsVar $ RdrName.mkOrig gHC_GHCI_HELPERS (mkVarOcc "evalWrapper") -- | Run a 'GhcMonad' action to compile an expression for internal usage. ===================================== libraries/base/GHC/IO/Windows/Handle.hsc ===================================== @@ -576,24 +576,23 @@ consoleWriteNonBlocking hwnd ptr _offset bytes consoleRead :: Bool -> Io ConsoleHandle -> Ptr Word8 -> Word64 -> Int -> IO Int consoleRead blocking hwnd ptr _offset bytes - = withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> - alloca $ \res -> do - cooked <- isCooked hwnd - -- Cooked input must be handled differently when the STD handles are - -- attached to a real console handle. For File based handles we can't do - -- proper cooked inputs, but since the actions are async you would get - -- results as soon as available. - -- - -- For console handles We have to use a lower level API then ReadConsole, - -- namely we must use ReadConsoleInput which requires us to process - -- all console message manually. - -- - -- Do note that MSYS2 shells such as bash don't attach to a real handle, - -- and instead have by default a pipe/file based std handles. Which - -- means the cooked behaviour is best when used in a native Windows - -- terminal such as cmd, powershell or ConEmu. - case cooked || not blocking of - False -> do + = alloca $ \res -> do + cooked <- isCooked hwnd + -- Cooked input must be handled differently when the STD handles are + -- attached to a real console handle. For File based handles we can't do + -- proper cooked inputs, but since the actions are async you would get + -- results as soon as available. + -- + -- For console handles We have to use a lower level API then ReadConsole, + -- namely we must use ReadConsoleInput which requires us to process + -- all console message manually. + -- + -- Do note that MSYS2 shells such as bash don't attach to a real handle, + -- and instead have by default a pipe/file based std handles. Which + -- means the cooked behaviour is best when used in a native Windows + -- terminal such as cmd, powershell or ConEmu. + case cooked || not blocking of + False -> withUTF16ToGhcInternal ptr bytes $ \reqBytes w_ptr -> do debugIO "consoleRead :: un-cooked I/O read." -- eotControl allows us to handle control characters like EOL -- without needing a newline, which would sort of defeat the point @@ -628,9 +627,9 @@ consoleRead blocking hwnd ptr _offset bytes -- characters as they are. Technically this function can handle any -- console event. Including mouse, window and virtual key events -- but for now I'm only interested in key presses. - let entries = fromIntegral $ reqBytes `div` (#size INPUT_RECORD) + let entries = fromIntegral $ bytes `div` (#size INPUT_RECORD) allocaBytes entries $ \p_inputs -> - maybeReadEvent p_inputs entries res w_ptr + maybeReadEvent p_inputs entries res ptr -- Check to see if we have been explicitly asked to do a non-blocking -- I/O, and if we were, make sure that if we didn't have any console @@ -657,6 +656,7 @@ consoleRead blocking hwnd ptr _offset bytes b_read <- fromIntegral <$> peek res read <- cobble b_read w_ptr p_inputs + debugIO $ "readEvent: =" ++ show read if read > 0 then return $ fromIntegral read else maybeReadEvent p_inputs entries res w_ptr @@ -665,7 +665,7 @@ consoleRead blocking hwnd ptr _offset bytes -- minimum required to know which key/sequences were pressed. To do -- this and prevent having to fully port the PINPUT_RECORD structure -- in Haskell we use some GCC builtins to find the correct offsets. - cobble :: Int -> Ptr Word16 -> PINPUT_RECORD -> IO Int + cobble :: Int -> Ptr Word8 -> PINPUT_RECORD -> IO Int cobble 0 _ _ = do debugIO "cobble: done." return 0 cobble n w_ptr p_inputs = @@ -690,8 +690,18 @@ consoleRead blocking hwnd ptr _offset bytes debugIO $ "cobble: offset - " ++ show char_offset debugIO $ "cobble: show > " ++ show char debugIO $ "cobble: repeat: " ++ show repeated + -- The documentation here is rather subtle, but + -- according to MSDN the uWChar being provided here + -- has been "translated". What this actually means + -- is that the surrogate pairs have already been + -- translated into byte sequences. That is, despite + -- the Word16 storage type, it's actually a byte + -- stream. This means we shouldn't try to decode + -- to UTF-8 again since we'd end up incorrectly + -- interpreting two bytes as an extended unicode + -- character. pokeArray w_ptr $ replicate repeated char - (+1) <$> cobble n' w_ptr' p_inputs' + (+repeated) <$> cobble n' w_ptr' p_inputs' else do debugIO $ "cobble: skip event." cobble n' w_ptr p_inputs' ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.hs ===================================== @@ -0,0 +1,47 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedLabels #-} +{-# LANGUAGE MagicHash #-} + +import Data.Foldable (traverse_) +import Data.Proxy (Proxy(..)) +import GHC.OverloadedLabels (IsLabel(..)) +import GHC.TypeLits (KnownSymbol, symbolVal) +import GHC.Prim (Addr#) + +instance KnownSymbol symbol => IsLabel symbol String where + fromLabel = symbolVal (Proxy :: Proxy symbol) + +(#) :: String -> Int -> String +(#) _ i = show i + +f :: Addr# -> Int -> String +f _ i = show i + +main :: IO () +main = traverse_ putStrLn + [ #a + , #number17 + , #do + , #type + , #Foo + , #3 + , #199.4 + , #17a23b + , #f'a' + , #'a' + , #' + , #''notTHSplice + , #... + , #привет + , #こんにちは + , #"3" + , #":" + , #"Foo" + , #"The quick brown fox" + , #"\"" + , (++) #hello#world + , (++) #"hello"#"world" + , #"hello"# 1 -- equivalent to `(fromLabel @"hello") # 1` + , f "hello"#2 -- equivalent to `f ("hello"# :: Addr#) 2` + ] ===================================== testsuite/tests/overloadedrecflds/should_run/T11671_run.stdout ===================================== @@ -0,0 +1,24 @@ +a +number17 +do +type +Foo +3 +199.4 +17a23b +f'a' +'a' +' +''notTHSplice +... +привет +こんにちは +3 +: +Foo +The quick brown fox +" +helloworld +helloworld +1 +2 ===================================== testsuite/tests/overloadedrecflds/should_run/all.T ===================================== @@ -17,3 +17,4 @@ test('hasfieldrun01', normal, compile_and_run, ['']) test('hasfieldrun02', normal, compile_and_run, ['']) test('T12243', normal, compile_and_run, ['']) test('T11228', normal, compile_and_run, ['']) +test('T11671_run', normal, compile_and_run, ['']) ===================================== testsuite/tests/perf/compiler/T21839c.hs ===================================== @@ -0,0 +1,46 @@ +-- For in depth details see the ticket #21839. The short version: + +-- We noticed that GHC got slower compiling Cabal the libary. +-- Eventually I narrowed it down to the pattern below of deriving Generics +-- for a Enum, and then deriving a Binary instance for that Enum via Generics. +-- A pattern very frequently used in Cabal. +-- However this turned out to be a classic compile vs runtime tradeoff. +-- In benchmarks I found the resulting code for the Binary instance was running +-- more than twice as fast! +-- So we decided to merely document this change and add a test representing this behaviour +-- rather than trying to coax ghc back into its old behaviour. + +{-# LANGUAGE DeriveGeneric #-} + +{-# OPTIONS_GHC #-} +module Main + ( main + ) where + +import GHC.Generics +import Data.Typeable +import Data.Binary +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString as BS + +data PathTemplateVariable = + + Var0 + | Var1 + | Var2 + | Var3 + | Var4 + | Var5 + | Var6 + | Var7 + | Var8 + | Var9 + deriving (Generic,Enum) + +instance Binary PathTemplateVariable + +main :: IO () +main = do + let lists = replicate 10000 Var0 + lbs = encode lists + print $ BS.length $ BS.toStrict lbs ===================================== testsuite/tests/perf/compiler/T21839c.stdout ===================================== @@ -0,0 +1 @@ +10008 ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -643,3 +643,10 @@ test ('T20261', [collect_compiler_stats('all')], compile, ['']) + +# Track perf of generics based binary instances +test('T21839c', + [ collect_compiler_stats('all', 1), + only_ways(['normal'])], + compile, + ['-O']) \ No newline at end of file ===================================== testsuite/tests/perf/should_run/T21839r.hs ===================================== @@ -0,0 +1,46 @@ +-- For in depth details see the ticket #21839. The short version: + +-- We noticed that GHC got slower compiling Cabal the libary. +-- Eventually I narrowed it down to the pattern below of deriving Generics +-- for a Enum, and then deriving a Binary instance for that Enum via Generics. +-- A pattern very frequently used in Cabal. +-- However this turned out to be a classic compile vs runtime tradeoff. +-- In benchmarks I found the resulting code for the Binary instance was running +-- more than twice as fast! +-- So we decided to merely document this change and add a test representing this behaviour +-- rather than trying to coax ghc back into its old behaviour. + +{-# LANGUAGE DeriveGeneric #-} + +{-# OPTIONS_GHC #-} +module Main + ( main + ) where + +import GHC.Generics +import Data.Typeable +import Data.Binary +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString as BS + +data PathTemplateVariable = + + Var0 + | Var1 + | Var2 + | Var3 + | Var4 + | Var5 + | Var6 + | Var7 + | Var8 + | Var9 + deriving (Generic,Enum) + +instance Binary PathTemplateVariable + +main :: IO () +main = do + let lists = replicate 10000 Var0 + lbs = encode lists + print $ BS.length $ BS.toStrict lbs ===================================== testsuite/tests/perf/should_run/T21839r.stdout ===================================== @@ -0,0 +1 @@ +10008 ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -395,3 +395,11 @@ test('T19347', compile_and_run, ['-O']) +# Track perf of generics based binary instances +test('T21839r', + [ collect_stats('bytes allocated', 10), + collect_runtime_residency(10), + collect_compiler_stats('bytes allocated', 1), + only_ways(['normal'])], + compile_and_run, + ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5327ef918c1f6bc9cadbb7bf900efa80bd1efdbe...4838827cbb4c42a3d0a9879d38f1fbaf4960d578 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5327ef918c1f6bc9cadbb7bf900efa80bd1efdbe...4838827cbb4c42a3d0a9879d38f1fbaf4960d578 You're receiving 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 Oct 13 07:48:21 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 03:48:21 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add a perf test for the generics code pattern from #21839. Message-ID: <6347c2c599a9c_2c5d73514783961fe@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4ee45cec by Andreas Klebinger at 2022-10-13T03:48:04-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 1fbab209 by Ben Gamari at 2022-10-13T03:48:05-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - ff441015 by Ben Gamari at 2022-10-13T03:48:05-04:00 rts/linker: Add support for .fini sections - - - - - 8d313d63 by Simon Hengel at 2022-10-13T03:48:10-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - db525d07 by Finley McIlwaine at 2022-10-13T03:48:12-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 30 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/phases.rst - rts/linker/Elf.c - rts/linker/ElfTypes.h - + rts/linker/InitFini.c - + rts/linker/InitFini.h - rts/linker/PEi386.c - rts/linker/PEi386Types.h - rts/rts.cabal.in - testsuite/tests/gadt/T14719.stderr - testsuite/tests/indexed-types/should_fail/T14033.stderr - testsuite/tests/indexed-types/should_fail/T2334A.stderr - testsuite/tests/linear/should_fail/LinearGADTNewtype.stderr - testsuite/tests/parser/should_fail/readFail008.stderr - + testsuite/tests/perf/compiler/T21839c.hs - + testsuite/tests/perf/compiler/T21839c.stdout - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/should_run/T21839r.hs - + testsuite/tests/perf/should_run/T21839r.stdout - testsuite/tests/perf/should_run/all.T - testsuite/tests/polykinds/T11459.stderr - testsuite/tests/typecheck/should_fail/T15523.stderr - testsuite/tests/typecheck/should_fail/T15796.stderr - testsuite/tests/typecheck/should_fail/T17955.stderr - testsuite/tests/typecheck/should_fail/T18891a.stderr - + testsuite/tests/typecheck/should_fail/T21447.hs - + testsuite/tests/typecheck/should_fail/T21447.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4838827cbb4c42a3d0a9879d38f1fbaf4960d578...db525d07c1f73044f11cf343c5122f2efe87ba7b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4838827cbb4c42a3d0a9879d38f1fbaf4960d578...db525d07c1f73044f11cf343c5122f2efe87ba7b You're receiving 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 Oct 13 09:58:35 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 05:58:35 -0400 Subject: [Git][ghc/ghc][master] Add a perf test for the generics code pattern from #21839. Message-ID: <6347e14bf2e65_2c5d73514504726d8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 6 changed files: - + testsuite/tests/perf/compiler/T21839c.hs - + testsuite/tests/perf/compiler/T21839c.stdout - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/should_run/T21839r.hs - + testsuite/tests/perf/should_run/T21839r.stdout - testsuite/tests/perf/should_run/all.T Changes: ===================================== testsuite/tests/perf/compiler/T21839c.hs ===================================== @@ -0,0 +1,46 @@ +-- For in depth details see the ticket #21839. The short version: + +-- We noticed that GHC got slower compiling Cabal the libary. +-- Eventually I narrowed it down to the pattern below of deriving Generics +-- for a Enum, and then deriving a Binary instance for that Enum via Generics. +-- A pattern very frequently used in Cabal. +-- However this turned out to be a classic compile vs runtime tradeoff. +-- In benchmarks I found the resulting code for the Binary instance was running +-- more than twice as fast! +-- So we decided to merely document this change and add a test representing this behaviour +-- rather than trying to coax ghc back into its old behaviour. + +{-# LANGUAGE DeriveGeneric #-} + +{-# OPTIONS_GHC #-} +module Main + ( main + ) where + +import GHC.Generics +import Data.Typeable +import Data.Binary +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString as BS + +data PathTemplateVariable = + + Var0 + | Var1 + | Var2 + | Var3 + | Var4 + | Var5 + | Var6 + | Var7 + | Var8 + | Var9 + deriving (Generic,Enum) + +instance Binary PathTemplateVariable + +main :: IO () +main = do + let lists = replicate 10000 Var0 + lbs = encode lists + print $ BS.length $ BS.toStrict lbs ===================================== testsuite/tests/perf/compiler/T21839c.stdout ===================================== @@ -0,0 +1 @@ +10008 ===================================== testsuite/tests/perf/compiler/all.T ===================================== @@ -643,3 +643,10 @@ test ('T20261', [collect_compiler_stats('all')], compile, ['']) + +# Track perf of generics based binary instances +test('T21839c', + [ collect_compiler_stats('all', 1), + only_ways(['normal'])], + compile, + ['-O']) \ No newline at end of file ===================================== testsuite/tests/perf/should_run/T21839r.hs ===================================== @@ -0,0 +1,46 @@ +-- For in depth details see the ticket #21839. The short version: + +-- We noticed that GHC got slower compiling Cabal the libary. +-- Eventually I narrowed it down to the pattern below of deriving Generics +-- for a Enum, and then deriving a Binary instance for that Enum via Generics. +-- A pattern very frequently used in Cabal. +-- However this turned out to be a classic compile vs runtime tradeoff. +-- In benchmarks I found the resulting code for the Binary instance was running +-- more than twice as fast! +-- So we decided to merely document this change and add a test representing this behaviour +-- rather than trying to coax ghc back into its old behaviour. + +{-# LANGUAGE DeriveGeneric #-} + +{-# OPTIONS_GHC #-} +module Main + ( main + ) where + +import GHC.Generics +import Data.Typeable +import Data.Binary +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString as BS + +data PathTemplateVariable = + + Var0 + | Var1 + | Var2 + | Var3 + | Var4 + | Var5 + | Var6 + | Var7 + | Var8 + | Var9 + deriving (Generic,Enum) + +instance Binary PathTemplateVariable + +main :: IO () +main = do + let lists = replicate 10000 Var0 + lbs = encode lists + print $ BS.length $ BS.toStrict lbs ===================================== testsuite/tests/perf/should_run/T21839r.stdout ===================================== @@ -0,0 +1 @@ +10008 ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -395,3 +395,11 @@ test('T19347', compile_and_run, ['-O']) +# Track perf of generics based binary instances +test('T21839r', + [ collect_stats('bytes allocated', 10), + collect_runtime_residency(10), + collect_compiler_stats('bytes allocated', 1), + only_ways(['normal'])], + compile_and_run, + ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce2939085e5b59513748ff73bc66161c09d69468 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce2939085e5b59513748ff73bc66161c09d69468 You're receiving 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 Oct 13 09:59:19 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 05:59:19 -0400 Subject: [Git][ghc/ghc][master] 2 commits: rts/linker: Consolidate initializer/finalizer handling Message-ID: <6347e177ed1a3_2c5d73514504784f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - 7 changed files: - rts/linker/Elf.c - rts/linker/ElfTypes.h - + rts/linker/InitFini.c - + rts/linker/InitFini.h - rts/linker/PEi386.c - rts/linker/PEi386Types.h - rts/rts.cabal.in Changes: ===================================== rts/linker/Elf.c ===================================== @@ -25,7 +25,6 @@ #include "ForeignExports.h" #include "Profiling.h" #include "sm/OSMem.h" -#include "GetEnv.h" #include "linker/util.h" #include "linker/elf_util.h" @@ -710,6 +709,66 @@ ocGetNames_ELF ( ObjectCode* oc ) StgWord size = shdr[i].sh_size; StgWord offset = shdr[i].sh_offset; StgWord align = shdr[i].sh_addralign; + const char *sh_name = oc->info->sectionHeaderStrtab + shdr[i].sh_name; + + /* + * Identify initializer and finalizer lists + * + * See Note [Initializers and finalizers (ELF)]. + */ + if (kind == SECTIONKIND_CODE_OR_RODATA + && 0 == memcmp(".init", sh_name, 5)) { + addInitFini(&oc->info->init, &oc->sections[i], INITFINI_INIT, 0); + } else if (kind == SECTIONKIND_CODE_OR_RODATA + && 0 == memcmp(".fini", sh_name, 5)) { + addInitFini(&oc->info->fini, &oc->sections[i], INITFINI_FINI, 0); + } else if (kind == SECTIONKIND_INIT_ARRAY + || 0 == memcmp(".init_array", sh_name, 11)) { + uint32_t prio; + if (sscanf(sh_name, ".init_array.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; + } + prio += 0x10000; // .init_arrays run after .ctors + addInitFini(&oc->info->init, &oc->sections[i], INITFINI_INIT_ARRAY, prio); + kind = SECTIONKIND_INIT_ARRAY; + } else if (kind == SECTIONKIND_FINI_ARRAY + || 0 == memcmp(".fini_array", sh_name, 11)) { + uint32_t prio; + if (sscanf(sh_name, ".fini_array.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; + } + prio += 0x10000; // .fini_arrays run before .dtors + addInitFini(&oc->info->fini, &oc->sections[i], INITFINI_FINI_ARRAY, prio); + kind = SECTIONKIND_FINI_ARRAY; + + /* N.B. a compilation unit may have more than one .ctor section; we + * must run them all. See #21618 for a case where this happened */ + } else if (0 == memcmp(".ctors", sh_name, 6)) { + uint32_t prio; + if (sscanf(sh_name, ".ctors.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; + } + // .ctors/.dtors are executed in reverse order: higher numbers are + // executed first + prio = 0xffff - prio; + addInitFini(&oc->info->init, &oc->sections[i], INITFINI_CTORS, prio); + kind = SECTIONKIND_INIT_ARRAY; + } else if (0 == memcmp(".dtors", sh_name, 6)) { + uint32_t prio; + if (sscanf(sh_name, ".dtors.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; + } + // .ctors/.dtors are executed in reverse order: higher numbers are + // executed first + prio = 0xffff - prio; + addInitFini(&oc->info->fini, &oc->sections[i], INITFINI_DTORS, prio); + kind = SECTIONKIND_FINI_ARRAY; + } + if (is_bss && size > 0) { /* This is a non-empty .bss section. Allocate zeroed space for @@ -848,13 +907,9 @@ ocGetNames_ELF ( ObjectCode* oc ) oc->sections[i].info->stub_size = 0; oc->sections[i].info->stubs = NULL; } - oc->sections[i].info->name = oc->info->sectionHeaderStrtab - + shdr[i].sh_name; + oc->sections[i].info->name = sh_name; oc->sections[i].info->sectionHeader = &shdr[i]; - - - if (shdr[i].sh_type != SHT_SYMTAB) continue; /* copy stuff into this module's object symbol table */ @@ -1971,62 +2026,10 @@ ocResolve_ELF ( ObjectCode* oc ) // See Note [Initializers and finalizers (ELF)]. int ocRunInit_ELF( ObjectCode *oc ) { - Elf_Word i; - char* ehdrC = (char*)(oc->image); - Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC; - Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); - char* sh_strtab = ehdrC + shdr[elf_shstrndx(ehdr)].sh_offset; - int argc, envc; - char **argv, **envv; - - getProgArgv(&argc, &argv); - getProgEnvv(&envc, &envv); - - // XXX Apparently in some archs .init may be something - // special! See DL_DT_INIT_ADDRESS macro in glibc - // as well as ELF_FUNCTION_PTR_IS_SPECIAL. We've not handled - // it here, please file a bug report if it affects you. - for (i = 0; i < elf_shnum(ehdr); i++) { - init_t *init_start, *init_end, *init; - char *sh_name = sh_strtab + shdr[i].sh_name; - int is_bss = false; - SectionKind kind = getSectionKind_ELF(&shdr[i], &is_bss); - - if (kind == SECTIONKIND_CODE_OR_RODATA - && 0 == memcmp(".init", sh_name, 5)) { - init_t init_f = (init_t)(oc->sections[i].start); - init_f(argc, argv, envv); - } - - // Note [GCC 6 init/fini section workaround] - if (kind == SECTIONKIND_INIT_ARRAY - || 0 == memcmp(".init_array", sh_name, 11)) { - char *init_startC = oc->sections[i].start; - init_start = (init_t*)init_startC; - init_end = (init_t*)(init_startC + shdr[i].sh_size); - for (init = init_start; init < init_end; init++) { - CHECK(0x0 != *init); - (*init)(argc, argv, envv); - } - } - - // XXX could be more strict and assert that it's - // SECTIONKIND_RWDATA; but allowing RODATA seems harmless enough. - if ((kind == SECTIONKIND_RWDATA || kind == SECTIONKIND_CODE_OR_RODATA) - && 0 == memcmp(".ctors", sh_strtab + shdr[i].sh_name, 6)) { - char *init_startC = oc->sections[i].start; - init_start = (init_t*)init_startC; - init_end = (init_t*)(init_startC + shdr[i].sh_size); - // ctors run in reverse - for (init = init_end - 1; init >= init_start; init--) { - CHECK(0x0 != *init); - (*init)(argc, argv, envv); - } - } - } - - freeProgEnvv(envc, envv); - return 1; + if (oc && oc->info && oc->info->init) { + return runInit(&oc->info->init); + } + return true; } // Run the finalizers of an ObjectCode. @@ -2034,46 +2037,10 @@ int ocRunInit_ELF( ObjectCode *oc ) // See Note [Initializers and finalizers (ELF)]. int ocRunFini_ELF( ObjectCode *oc ) { - char* ehdrC = (char*)(oc->image); - Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC; - Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff); - char* sh_strtab = ehdrC + shdr[elf_shstrndx(ehdr)].sh_offset; - - for (Elf_Word i = 0; i < elf_shnum(ehdr); i++) { - char *sh_name = sh_strtab + shdr[i].sh_name; - int is_bss = false; - SectionKind kind = getSectionKind_ELF(&shdr[i], &is_bss); - - if (kind == SECTIONKIND_CODE_OR_RODATA && 0 == memcmp(".fini", sh_strtab + shdr[i].sh_name, 5)) { - fini_t fini_f = (fini_t)(oc->sections[i].start); - fini_f(); - } - - // Note [GCC 6 init/fini section workaround] - if (kind == SECTIONKIND_FINI_ARRAY - || 0 == memcmp(".fini_array", sh_name, 11)) { - fini_t *fini_start, *fini_end, *fini; - char *fini_startC = oc->sections[i].start; - fini_start = (fini_t*)fini_startC; - fini_end = (fini_t*)(fini_startC + shdr[i].sh_size); - for (fini = fini_start; fini < fini_end; fini++) { - CHECK(0x0 != *fini); - (*fini)(); - } - } - - if (kind == SECTIONKIND_CODE_OR_RODATA && 0 == memcmp(".dtors", sh_strtab + shdr[i].sh_name, 6)) { - char *fini_startC = oc->sections[i].start; - fini_t *fini_start = (fini_t*)fini_startC; - fini_t *fini_end = (fini_t*)(fini_startC + shdr[i].sh_size); - for (fini_t *fini = fini_start; fini < fini_end; fini++) { - CHECK(0x0 != *fini); - (*fini)(); - } - } - } - - return 1; + if (oc && oc->info && oc->info->fini) { + return runFini(&oc->info->fini); + } + return true; } /* ===================================== rts/linker/ElfTypes.h ===================================== @@ -6,6 +6,7 @@ #include "ghcplatform.h" #include +#include "linker/InitFini.h" /* * Define a set of types which can be used for both ELF32 and ELF64 @@ -137,6 +138,8 @@ struct ObjectCodeFormatInfo { ElfRelocationTable *relTable; ElfRelocationATable *relaTable; + struct InitFiniList* init; // Freed by ocRunInit_PEi386 + struct InitFiniList* fini; // Freed by ocRunFini_PEi386 /* pointer to the global offset table */ void * got_start; @@ -164,7 +167,7 @@ struct SectionFormatInfo { size_t nstubs; Stub * stubs; - char * name; + const char * name; Elf_Shdr *sectionHeader; }; ===================================== rts/linker/InitFini.c ===================================== @@ -0,0 +1,201 @@ +#include "Rts.h" +#include "RtsUtils.h" +#include "LinkerInternals.h" +#include "GetEnv.h" +#include "InitFini.h" + +/* + * Note [Initializers and finalizers (PEi386/ELF)] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Most ABIs allow an object to define initializers and finalizers to be run + * at load/unload time, respectively. These are represented in two ways: + * + * - a `.init`/`.fini` section which contains a function of type init_t which + * is to be executed during initialization/finalization. + * + * - `.ctors`/`.dtors` sections; these contain an array of pointers to + * `init_t`/`fini_t` functions, all of which should be executed at + * initialization/finalization time. The `.ctors` entries are run in reverse + * order. The list may end in a 0 or -1 sentinel value. + * + * - `.init_array`/`.fini_array` sections; these contain an array + * of pointers to `init_t`/`fini_t` functions. + * + * Objects may contain multiple `.ctors`/`.dtors` and + * `.init_array`/`.fini_array` sections, each optionally suffixed with an + * 16-bit integer priority (e.g. `.init_array.1234`). Confusingly, `.ctors` + * priorities and `.init_array` priorities have different orderings: `.ctors` + * sections are run from high to low priority whereas `.init_array` sections + * are run from low-to-high. + * + * Sections without a priority (e.g. `.ctors`) are assumed to run last (that + * is, are given a priority of 0xffff). + * + * In general, we run finalizers in the reverse order of the associated + * initializers. That is to say, e.g., .init_array entries are run from first + * to last entry and therefore .fini_array entries are run from last-to-first. + * + * To determine the ordering among the various section types, we follow glibc's + * model: + * + * - first run .ctors (last entry to first entry) + * - then run .init_arrays (first-to-last) + * + * and on unload we run in opposite order: + * + * - first run fini_arrays (first-to-last) + * - then run .dtors (last-to-first) + * + * For more about how the code generator emits initializers and finalizers see + * Note [Initializers and finalizers in Cmm] in GHC.Cmm.InitFini. + */ + +// Priority follows the init_array definition: initializers are run +// lowest-to-highest, finalizers run highest-to-lowest. +void addInitFini(struct InitFiniList **head, Section *section, enum InitFiniKind kind, uint32_t priority) +{ + struct InitFiniList *slist = stgMallocBytes(sizeof(struct InitFiniList), "addInitFini"); + slist->section = section; + slist->kind = kind; + slist->priority = priority; + slist->next = *head; + *head = slist; +} + +enum SortOrder { INCREASING, DECREASING }; + +// Sort a InitFiniList by priority. +static void sortInitFiniList(struct InitFiniList **slist, enum SortOrder order) +{ + // Bubble sort + bool done = false; + while (!done) { + struct InitFiniList **last = slist; + done = true; + while (*last != NULL && (*last)->next != NULL) { + struct InitFiniList *s0 = *last; + struct InitFiniList *s1 = s0->next; + bool flip; + switch (order) { + case INCREASING: flip = s0->priority > s1->priority; break; + case DECREASING: flip = s0->priority < s1->priority; break; + } + if (flip) { + s0->next = s1->next; + s1->next = s0; + *last = s1; + done = false; + } else { + last = &s0->next; + } + } + } +} + +void freeInitFiniList(struct InitFiniList *slist) +{ + while (slist != NULL) { + struct InitFiniList *next = slist->next; + stgFree(slist); + slist = next; + } +} + +static bool runInitFini(struct InitFiniList **head) +{ + int argc, envc; + char **argv, **envv; + + getProgArgv(&argc, &argv); + getProgEnvv(&envc, &envv); + + for (struct InitFiniList *slist = *head; + slist != NULL; + slist = slist->next) + { + Section *section = slist->section; + switch (slist->kind) { + case INITFINI_INIT: { + init_t *init = (init_t*)section->start; + (*init)(argc, argv, envv); + break; + } + case INITFINI_FINI: { + fini_t *fini = (fini_t*)section->start; + (*fini)(); + break; + } + case INITFINI_CTORS: { + uint8_t *init_startC = section->start; + init_t *init_start = (init_t*)init_startC; + init_t *init_end = (init_t*)(init_startC + section->size); + + // ctors are run *backwards*! + for (init_t *init = init_end - 1; init >= init_start; init--) { + if ((intptr_t) *init == 0x0 || (intptr_t)*init == -1) { + continue; + } + (*init)(argc, argv, envv); + } + break; + } + case INITFINI_DTORS: { + char *fini_startC = section->start; + fini_t *fini_start = (fini_t*)fini_startC; + fini_t *fini_end = (fini_t*)(fini_startC + section->size); + for (fini_t *fini = fini_start; fini < fini_end; fini++) { + if ((intptr_t) *fini == 0x0 || (intptr_t) *fini == -1) { + continue; + } + (*fini)(); + } + break; + } + case INITFINI_INIT_ARRAY: { + char *init_startC = section->start; + init_t *init_start = (init_t*)init_startC; + init_t *init_end = (init_t*)(init_startC + section->size); + for (init_t *init = init_start; init < init_end; init++) { + CHECK(0x0 != *init); + (*init)(argc, argv, envv); + } + break; + } + case INITFINI_FINI_ARRAY: { + char *fini_startC = section->start; + fini_t *fini_start = (fini_t*)fini_startC; + fini_t *fini_end = (fini_t*)(fini_startC + section->size); + // .fini_array finalizers are run backwards + for (fini_t *fini = fini_end - 1; fini >= fini_start; fini--) { + CHECK(0x0 != *fini); + (*fini)(); + } + break; + } + default: barf("unknown InitFiniKind"); + } + } + freeInitFiniList(*head); + *head = NULL; + + freeProgEnvv(envc, envv); + return true; +} + +// Run the constructors/initializers of an ObjectCode. +// Returns 1 on success. +// See Note [Initializers and finalizers (PEi386/ELF)]. +bool runInit(struct InitFiniList **head) +{ + sortInitFiniList(head, INCREASING); + return runInitFini(head); +} + +// Run the finalizers of an ObjectCode. +// Returns 1 on success. +// See Note [Initializers and finalizers (PEi386/ELF)]. +bool runFini(struct InitFiniList **head) +{ + sortInitFiniList(head, DECREASING); + return runInitFini(head); +} ===================================== rts/linker/InitFini.h ===================================== @@ -0,0 +1,23 @@ +#pragma once + +enum InitFiniKind { + INITFINI_INIT, // .init section + INITFINI_FINI, // .fini section + INITFINI_CTORS, // .ctors section + INITFINI_DTORS, // .dtors section + INITFINI_INIT_ARRAY, // .init_array section + INITFINI_FINI_ARRAY, // .fini_array section +}; + +// A linked-list of initializer or finalizer sections. +struct InitFiniList { + Section *section; + uint32_t priority; + enum InitFiniKind kind; + struct InitFiniList *next; +}; + +void addInitFini(struct InitFiniList **slist, Section *section, enum InitFiniKind kind, uint32_t priority); +void freeInitFiniList(struct InitFiniList *slist); +bool runInit(struct InitFiniList **slist); +bool runFini(struct InitFiniList **slist); ===================================== rts/linker/PEi386.c ===================================== @@ -308,7 +308,6 @@ #include "RtsUtils.h" #include "RtsSymbolInfo.h" -#include "GetEnv.h" #include "CheckUnload.h" #include "LinkerInternals.h" #include "linker/PEi386.h" @@ -386,45 +385,6 @@ const int default_alignment = 8; the pointer as a redirect. Essentially it's a DATA DLL reference. */ const void* __rts_iob_func = (void*)&__acrt_iob_func; -enum SortOrder { INCREASING, DECREASING }; - -// Sort a SectionList by priority. -static void sortSectionList(struct SectionList **slist, enum SortOrder order) -{ - // Bubble sort - bool done = false; - while (!done) { - struct SectionList **last = slist; - done = true; - while (*last != NULL && (*last)->next != NULL) { - struct SectionList *s0 = *last; - struct SectionList *s1 = s0->next; - bool flip; - switch (order) { - case INCREASING: flip = s0->priority > s1->priority; break; - case DECREASING: flip = s0->priority < s1->priority; break; - } - if (flip) { - s0->next = s1->next; - s1->next = s0; - *last = s1; - done = false; - } else { - last = &s0->next; - } - } - } -} - -static void freeSectionList(struct SectionList *slist) -{ - while (slist != NULL) { - struct SectionList *next = slist->next; - stgFree(slist); - slist = next; - } -} - void initLinker_PEi386() { if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"), @@ -553,8 +513,8 @@ static void releaseOcInfo(ObjectCode* oc) { if (!oc) return; if (oc->info) { - freeSectionList(oc->info->init); - freeSectionList(oc->info->fini); + freeInitFiniList(oc->info->init); + freeInitFiniList(oc->info->fini); stgFree (oc->info->ch_info); stgFree (oc->info->symbols); stgFree (oc->info->str_tab); @@ -1513,26 +1473,28 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if (0==strncmp(".ctors", section->info->name, 6)) { /* N.B. a compilation unit may have more than one .ctor section; we * must run them all. See #21618 for a case where this happened */ - struct SectionList *slist = stgMallocBytes(sizeof(struct SectionList), "ocGetNames_PEi386"); - slist->section = &oc->sections[i]; - slist->next = oc->info->init; - if (sscanf(section->info->name, ".ctors.%d", &slist->priority) != 1) { - // Sections without an explicit priority must be run last - slist->priority = 0; + uint32_t prio; + if (sscanf(section->info->name, ".ctors.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; } - oc->info->init = slist; + // .ctors/.dtors are executed in reverse order: higher numbers are + // executed first + prio = 0xffff - prio; + addInitFini(&oc->info->init, &oc->sections[i], INITFINI_CTORS, prio); kind = SECTIONKIND_INIT_ARRAY; } if (0==strncmp(".dtors", section->info->name, 6)) { - struct SectionList *slist = stgMallocBytes(sizeof(struct SectionList), "ocGetNames_PEi386"); - slist->section = &oc->sections[i]; - slist->next = oc->info->fini; - if (sscanf(section->info->name, ".dtors.%d", &slist->priority) != 1) { - // Sections without an explicit priority must be run last - slist->priority = INT_MAX; + uint32_t prio; + if (sscanf(section->info->name, ".dtors.%d", &prio) != 1) { + // Sections without an explicit priority are run last + prio = 0; } - oc->info->fini = slist; + // .ctors/.dtors are executed in reverse order: higher numbers are + // executed first + prio = 0xffff - prio; + addInitFini(&oc->info->fini, &oc->sections[i], INITFINI_DTORS, prio); kind = SECTIONKIND_FINI_ARRAY; } @@ -1632,10 +1594,6 @@ ocGetNames_PEi386 ( ObjectCode* oc ) addProddableBlock(oc, oc->sections[i].start, sz); } - /* Sort the constructors and finalizers by priority */ - sortSectionList(&oc->info->init, DECREASING); - sortSectionList(&oc->info->fini, INCREASING); - /* Copy exported symbols into the ObjectCode. */ oc->n_symbols = info->numberOfSymbols; @@ -2170,95 +2128,23 @@ ocResolve_PEi386 ( ObjectCode* oc ) content of .pdata on to RtlAddFunctionTable and the OS will do the rest. When we're unloading the object we have to unregister them using RtlDeleteFunctionTable. - */ -/* - * Note [Initializers and finalizers (PEi386)] - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * COFF/PE allows an object to define initializers and finalizers to be run - * at load/unload time, respectively. These are listed in the `.ctors` and - * `.dtors` sections. Moreover, these section names may be suffixed with an - * integer priority (e.g. `.ctors.1234`). Sections are run in order of - * high-to-low priority. Sections without a priority (e.g. `.ctors`) are run - * last. - * - * A `.ctors`/`.dtors` section contains an array of pointers to - * `init_t`/`fini_t` functions, respectively. Note that `.ctors` must be run in - * reverse order. - * - * For more about how the code generator emits initializers and finalizers see - * Note [Initializers and finalizers in Cmm] in GHC.Cmm.InitFini. - */ - - -// Run the constructors/initializers of an ObjectCode. -// Returns 1 on success. -// See Note [Initializers and finalizers (PEi386)]. bool ocRunInit_PEi386 ( ObjectCode *oc ) { - if (!oc || !oc->info || !oc->info->init) { - return true; - } - - int argc, envc; - char **argv, **envv; - - getProgArgv(&argc, &argv); - getProgEnvv(&envc, &envv); - - for (struct SectionList *slist = oc->info->init; - slist != NULL; - slist = slist->next) { - Section *section = slist->section; - CHECK(SECTIONKIND_INIT_ARRAY == section->kind); - uint8_t *init_startC = section->start; - init_t *init_start = (init_t*)init_startC; - init_t *init_end = (init_t*)(init_startC + section->size); - - // ctors are run *backwards*! - for (init_t *init = init_end - 1; init >= init_start; init--) { - (*init)(argc, argv, envv); + if (oc && oc->info && oc->info->init) { + return runInit(&oc->info->init); } - } - - freeSectionList(oc->info->init); - oc->info->init = NULL; - - freeProgEnvv(envc, envv); - return true; + return true; } -// Run the finalizers of an ObjectCode. -// Returns 1 on success. -// See Note [Initializers and finalizers (PEi386)]. bool ocRunFini_PEi386( ObjectCode *oc ) { - if (!oc || !oc->info || !oc->info->fini) { - return true; - } - - for (struct SectionList *slist = oc->info->fini; - slist != NULL; - slist = slist->next) { - Section section = *slist->section; - CHECK(SECTIONKIND_FINI_ARRAY == section.kind); - - uint8_t *fini_startC = section.start; - fini_t *fini_start = (fini_t*)fini_startC; - fini_t *fini_end = (fini_t*)(fini_startC + section.size); - - // dtors are run in forward order. - for (fini_t *fini = fini_end - 1; fini >= fini_start; fini--) { - (*fini)(); + if (oc && oc->info && oc->info->fini) { + return runFini(&oc->info->fini); } - } - - freeSectionList(oc->info->fini); - oc->info->fini = NULL; - - return true; + return true; } SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType *type) ===================================== rts/linker/PEi386Types.h ===================================== @@ -4,6 +4,7 @@ #include "ghcplatform.h" #include "PEi386.h" +#include "linker/InitFini.h" #include #include @@ -17,17 +18,9 @@ struct SectionFormatInfo { uint64_t virtualAddr; }; -// A linked-list of Sections; used to represent the set of initializer/finalizer -// list sections. -struct SectionList { - Section *section; - int priority; - struct SectionList *next; -}; - struct ObjectCodeFormatInfo { - struct SectionList* init; // Freed by ocRunInit_PEi386 - struct SectionList* fini; // Freed by ocRunFini_PEi386 + struct InitFiniList* init; // Freed by ocRunInit_PEi386 + struct InitFiniList* fini; // Freed by ocRunFini_PEi386 Section* pdata; Section* xdata; COFF_HEADER_INFO* ch_info; // Freed by ocResolve_PEi386 ===================================== rts/rts.cabal.in ===================================== @@ -554,6 +554,7 @@ library hooks/StackOverflow.c linker/CacheFlush.c linker/Elf.c + linker/InitFini.c linker/LoadArchive.c linker/M32Alloc.c linker/MMap.c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce2939085e5b59513748ff73bc66161c09d69468...44692713c6fdfb1bf50a2480ca304e6498a0f3a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce2939085e5b59513748ff73bc66161c09d69468...44692713c6fdfb1bf50a2480ca304e6498a0f3a3 You're receiving 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 Oct 13 09:59:51 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 05:59:51 -0400 Subject: [Git][ghc/ghc][master] Update phases.rst Message-ID: <6347e19793a6b_2c5d73513ec48222f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - 1 changed file: - docs/users_guide/phases.rst Changes: ===================================== docs/users_guide/phases.rst ===================================== @@ -576,13 +576,13 @@ Options affecting a Haskell pre-processor .. code-block:: sh #!/bin/sh - ( echo "{-# LINE 1 \"$2\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3 + ( echo "{-# LINE 1 \"$1\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3 and pass ``-F -pgmF convert.sh`` to GHC. The ``-f l1`` option tells iconv to convert your Latin-1 file, supplied in argument ``$2``, while the "-t utf-8" options tell iconv to return a UTF-8 encoded file. The result is redirected into argument ``$3``. The - ``echo "{-# LINE 1 \"$2\" #-}"`` just makes sure that your error + ``echo "{-# LINE 1 \"$1\" #-}"`` just makes sure that your error positions are reported as in the original source file. .. _options-codegen: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/beebf546c9ea818c9d5a61688bfee8f3b7dbeb9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/beebf546c9ea818c9d5a61688bfee8f3b7dbeb9f You're receiving 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 Oct 13 10:00:41 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 06:00:41 -0400 Subject: [Git][ghc/ghc][master] Clearer error msg for newtype GADTs with defaulted kind Message-ID: <6347e1c92c825_2c5d73514504879cc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 18 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/gadt/T14719.stderr - testsuite/tests/indexed-types/should_fail/T14033.stderr - testsuite/tests/indexed-types/should_fail/T2334A.stderr - testsuite/tests/linear/should_fail/LinearGADTNewtype.stderr - testsuite/tests/parser/should_fail/readFail008.stderr - testsuite/tests/polykinds/T11459.stderr - testsuite/tests/typecheck/should_fail/T15523.stderr - testsuite/tests/typecheck/should_fail/T15796.stderr - testsuite/tests/typecheck/should_fail/T17955.stderr - testsuite/tests/typecheck/should_fail/T18891a.stderr - + testsuite/tests/typecheck/should_fail/T21447.hs - + testsuite/tests/typecheck/should_fail/T21447.stderr - testsuite/tests/typecheck/should_fail/all.T - testsuite/tests/typecheck/should_fail/tcfail156.stderr Changes: ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1000,6 +1000,40 @@ instance Diagnostic TcRnMessage where TcRnTypeDataForbids feature -> mkSimpleDecorated $ ppr feature <+> text "are not allowed in type data declarations." + TcRnIllegalNewtype con show_linear_types reason + -> mkSimpleDecorated $ + vcat [msg, additional] + where + (msg,additional) = + case reason of + DoesNotHaveSingleField n_flds -> + (sep [ + text "A newtype constructor must have exactly one field", + nest 2 $ + text "but" <+> quotes (ppr con) <+> text "has" <+> speakN n_flds + ], + ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) + IsNonLinear -> + (text "A newtype constructor must be linear", + ppr con <+> dcolon <+> ppr (dataConDisplayType True con)) + IsGADT -> + (text "A newtype must not be a GADT", + ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec (ppr $ dataConDisplayType show_linear_types con)) + HasConstructorContext -> + (text "A newtype constructor must not have a context in its type", + ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) + HasExistentialTyVar -> + (text "A newtype constructor must not have existential type variables", + ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) + HasStrictnessAnnotation -> + (text "A newtype constructor must not have a strictness annotation", empty) + + -- Is there an EqSpec involving an invisible binder? If so, print the + -- error message with explicit kinds. + invisible_binders = filter isInvisibleTyConBinder (tyConBinders $ dataConTyCon con) + sneaky_eq_spec + = any (\eq -> any (( == eqSpecTyVar eq) . binderVar) invisible_binders) + $ dataConEqSpec con diagnosticReason = \case TcRnUnknownMessage m @@ -1334,6 +1368,8 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnTypeDataForbids{} -> ErrorWithoutFlag + TcRnIllegalNewtype{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -1670,10 +1706,11 @@ instance Diagnostic TcRnMessage where -> [suggestExtension LangExt.TypeData] TcRnTypeDataForbids{} -> noHints + TcRnIllegalNewtype{} + -> noHints diagnosticCode = constructorCode - -- | Change [x] to "x", [x, y] to "x and y", [x, y, z] to "x, y, and z", -- and so on. The `and` stands for any `conjunction`, which is passed in. commafyWith :: SDoc -> [SDoc] -> [SDoc] ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Tc.Errors.Types ( , pprFixedRuntimeRepProvenance , ShadowedNameProvenance(..) , RecordFieldPart(..) + , IllegalNewtypeReason(..) , InjectivityErrReason(..) , HasKinds(..) , hasKinds @@ -2288,6 +2289,34 @@ data TcRnMessage where TcRnNoExplicitAssocTypeOrDefaultDeclaration :: Name -> TcRnMessage + {-| TcRnIllegalNewtype is an error that occurs when a newtype: + + * Does not have exactly one field, or + * is non-linear, or + * is a GADT, or + * has a context in its constructor's type, or + * has existential type variables in its constructor's type, or + * has strictness annotations. + + Test cases: + testsuite/tests/gadt/T14719 + testsuite/tests/indexed-types/should_fail/T14033 + testsuite/tests/indexed-types/should_fail/T2334A + testsuite/tests/linear/should_fail/LinearGADTNewtype + testsuite/tests/parser/should_fail/readFail008 + testsuite/tests/polykinds/T11459 + testsuite/tests/typecheck/should_fail/T15523 + testsuite/tests/typecheck/should_fail/T15796 + testsuite/tests/typecheck/should_fail/T17955 + testsuite/tests/typecheck/should_fail/T18891a + testsuite/tests/typecheck/should_fail/T21447 + testsuite/tests/typecheck/should_fail/tcfail156 + -} + TcRnIllegalNewtype + :: DataCon + -> Bool -- ^ True if linear types enabled + -> IllegalNewtypeReason + -> TcRnMessage {-| TcRnIllegalTypeData is an error that occurs when a @type data@ declaration occurs without the TypeOperators extension. @@ -2333,6 +2362,7 @@ instance Outputable TypeDataForbids where -- | Specifies which back ends can handle a requested foreign import or export type ExpectedBackends = [Backend] + -- | Specifies which calling convention is unsupported on the current platform data UnsupportedCallConvention = StdCallConvUnsupported @@ -2384,6 +2414,17 @@ pprFixedRuntimeRepProvenance FixedRuntimeRepDataConField = text "data constructo pprFixedRuntimeRepProvenance FixedRuntimeRepPatSynSigArg = text "pattern synonym argument" pprFixedRuntimeRepProvenance FixedRuntimeRepPatSynSigRes = text "pattern synonym scrutinee" +-- | Why the particular illegal newtype error arose together with more +-- information, if any. +data IllegalNewtypeReason + = DoesNotHaveSingleField !Int + | IsNonLinear + | IsGADT + | HasConstructorContext + | HasExistentialTyVar + | HasStrictnessAnnotation + deriving Generic + -- | Why the particular injectivity error arose together with more information, -- if any. data InjectivityErrReason ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -35,7 +35,7 @@ import GHC.Driver.Config.HsToCore import GHC.Hs import GHC.Tc.Errors.Types ( TcRnMessage(..), FixedRuntimeRepProvenance(..) - , mkTcRnUnknownMessage ) + , mkTcRnUnknownMessage, IllegalNewtypeReason (..) ) import GHC.Tc.TyCl.Build import GHC.Tc.Solver( pushLevelAndSolveEqualities, pushLevelAndSolveEqualitiesX , reportUnsolvedEqualities ) @@ -4530,40 +4530,30 @@ checkValidDataCon dflags existential_ok tc con ------------------------------- checkNewDataCon :: DataCon -> TcM () -- Further checks for the data constructor of a newtype +-- You might wonder if we need to check for an unlifted newtype +-- without -XUnliftedNewTypes, such as +-- newtype C = MkC Int# +-- But they are caught earlier, by GHC.Tc.Gen.HsType.checkDataKindSig checkNewDataCon con - = do { checkTc (isSingleton arg_tys) (newtypeFieldErr con (length arg_tys)) - -- One argument - - ; unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes - ; let allowedArgType = - unlifted_newtypes || typeLevity_maybe (scaledThing arg_ty1) == Just Lifted - ; checkTc allowedArgType $ mkTcRnUnknownMessage $ mkPlainError noHints $ vcat - [ text "A newtype cannot have an unlifted argument type" - , text "Perhaps you intended to use UnliftedNewtypes" - ] - ; show_linear_types <- xopt LangExt.LinearTypes <$> getDynFlags - - ; let check_con what msg = - checkTc what $ mkTcRnUnknownMessage $ mkPlainError noHints $ - (msg $$ ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) + = do { show_linear_types <- xopt LangExt.LinearTypes <$> getDynFlags + + ; checkTc (isSingleton arg_tys) $ + TcRnIllegalNewtype con show_linear_types (DoesNotHaveSingleField $ length arg_tys) ; checkTc (ok_mult (scaledMult arg_ty1)) $ - mkTcRnUnknownMessage $ mkPlainError noHints $ text "A newtype constructor must be linear" + TcRnIllegalNewtype con show_linear_types IsNonLinear - ; check_con (null eq_spec) $ - text "A newtype constructor must have a return type of form T a1 ... an" - -- Return type is (T a b c) + ; checkTc (null eq_spec) $ + TcRnIllegalNewtype con show_linear_types IsGADT - ; check_con (null theta) $ - text "A newtype constructor cannot have a context in its type" + ; checkTc (null theta) $ + TcRnIllegalNewtype con show_linear_types HasConstructorContext - ; check_con (null ex_tvs) $ - text "A newtype constructor cannot have existential type variables" - -- No existentials + ; checkTc (null ex_tvs) $ + TcRnIllegalNewtype con show_linear_types HasExistentialTyVar - ; checkTc (all ok_bang (dataConSrcBangs con)) - (newtypeStrictError con) - -- No strictness annotations + ; checkTc (all ok_bang (dataConSrcBangs con)) $ + TcRnIllegalNewtype con show_linear_types HasStrictnessAnnotation } where (_univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _res_ty) @@ -5334,18 +5324,6 @@ newtypeConError tycon n sep [text "A newtype must have exactly one constructor,", nest 2 $ text "but" <+> quotes (ppr tycon) <+> text "has" <+> speakN n ] -newtypeStrictError :: DataCon -> TcRnMessage -newtypeStrictError con - = mkTcRnUnknownMessage $ mkPlainError noHints $ - sep [text "A newtype constructor cannot have a strictness annotation,", - nest 2 $ text "but" <+> quotes (ppr con) <+> text "does"] - -newtypeFieldErr :: DataCon -> Int -> TcRnMessage -newtypeFieldErr con_name n_flds - = mkTcRnUnknownMessage $ mkPlainError noHints $ - sep [text "The constructor of a newtype must have exactly one field", - nest 2 $ text "but" <+> quotes (ppr con_name) <+> text "has" <+> speakN n_flds] - badSigTyDecl :: Name -> TcRnMessage badSigTyDecl tc_name = mkTcRnUnknownMessage $ mkPlainError noHints $ ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -468,6 +468,12 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnNoExplicitAssocTypeOrDefaultDeclaration" = 08585 GhcDiagnosticCode "TcRnIllegalTypeData" = 15013 GhcDiagnosticCode "TcRnTypeDataForbids" = 67297 + GhcDiagnosticCode "DoesNotHaveSingleField" = 23517 + GhcDiagnosticCode "IsNonLinear" = 38291 + GhcDiagnosticCode "IsGADT" = 89498 + GhcDiagnosticCode "HasConstructorContext" = 17440 + GhcDiagnosticCode "HasExistentialTyVar" = 07525 + GhcDiagnosticCode "HasStrictnessAnnotation" = 04049 -- TcRnPragmaWarning GhcDiagnosticCode "WarningTxt" = 63394 @@ -587,6 +593,7 @@ type family ConRecursInto con where ConRecursInto "TcRnCannotDeriveInstance" = 'Just DeriveInstanceErrReason ConRecursInto "TcRnPragmaWarning" = 'Just (WarningTxt GhcRn) ConRecursInto "TcRnNotInScope" = 'Just NotInScopeError + ConRecursInto "TcRnIllegalNewtype" = 'Just IllegalNewtypeReason ------------------ -- FFI errors ===================================== testsuite/tests/gadt/T14719.stderr ===================================== @@ -8,9 +8,10 @@ T14719.hs:5:3: error: 5 | MkFoo1 :: Bool | ^^^^^^^^^^^^^^ -T14719.hs:8:3: error: - • The constructor of a newtype must have exactly one field +T14719.hs:8:3: error: [GHC-23517] + • A newtype constructor must have exactly one field but ‘MkFoo2’ has none + MkFoo2 :: Foo2 • In the definition of data constructor ‘MkFoo2’ In the newtype declaration for ‘Foo2’ | ===================================== testsuite/tests/indexed-types/should_fail/T14033.stderr ===================================== @@ -1,6 +1,7 @@ -T14033.hs:5:16: error: - • The constructor of a newtype must have exactly one field +T14033.hs:5:16: error: [GHC-23517] + • A newtype constructor must have exactly one field but ‘Zero’ has none + Zero :: Zero • In the definition of data constructor ‘Zero’ In the newtype declaration for ‘Zero’ ===================================== testsuite/tests/indexed-types/should_fail/T2334A.stderr ===================================== @@ -1,13 +1,14 @@ -T2334A.hs:9:26: error: - • The constructor of a newtype must have exactly one field - but ‘F’ has two +T2334A.hs:9:26: error: [GHC-23517] + • A newtype constructor must have exactly one field but ‘F’ has two + F :: () -> () -> F () • In the definition of data constructor ‘F’ In the newtype instance declaration for ‘F’ -T2334A.hs:10:27: error: - • The constructor of a newtype must have exactly one field +T2334A.hs:10:27: error: [GHC-23517] + • A newtype constructor must have exactly one field but ‘H’ has none + H :: F Int • In the definition of data constructor ‘H’ In the newtype instance declaration for ‘F’ ===================================== testsuite/tests/linear/should_fail/LinearGADTNewtype.stderr ===================================== @@ -1,5 +1,6 @@ -LinearGADTNewtype.hs:3:4: error: +LinearGADTNewtype.hs:3:4: error: [GHC-38291] • A newtype constructor must be linear + A :: Int -> A • In the definition of data constructor ‘A’ In the newtype declaration for ‘A’ ===================================== testsuite/tests/parser/should_fail/readFail008.stderr ===================================== @@ -1,6 +1,5 @@ -readFail008.hs:5:15: - A newtype constructor cannot have a strictness annotation, - but ‘T’ does - In the definition of data constructor ‘T’ - In the newtype declaration for ‘N’ +readFail008.hs:5:15: error: [GHC-04049] + • A newtype constructor must not have a strictness annotation + • In the definition of data constructor ‘T’ + In the newtype declaration for ‘N’ ===================================== testsuite/tests/polykinds/T11459.stderr ===================================== @@ -1,6 +1,6 @@ -T11459.hs:9:20: error: - • A newtype constructor cannot have existential type variables +T11459.hs:9:20: error: [GHC-07525] + • A newtype constructor must not have existential type variables Parser :: forall a {k}. (forall (f :: k -> *) (r :: k). Failure f r -> Success a f r -> f r) ===================================== testsuite/tests/typecheck/should_fail/T15523.stderr ===================================== @@ -1,6 +1,7 @@ -T15523.hs:5:20: error: - • The constructor of a newtype must have exactly one field +T15523.hs:5:20: error: [GHC-23517] + • A newtype constructor must have exactly one field but ‘Foo’ has none + Foo :: Duration • In the definition of data constructor ‘Foo’ In the newtype declaration for ‘Duration’ ===================================== testsuite/tests/typecheck/should_fail/T15796.stderr ===================================== @@ -1,6 +1,6 @@ -T15796.hs:6:3: error: - • A newtype constructor cannot have a context in its type +T15796.hs:6:3: error: [GHC-17440] + • A newtype constructor must not have a context in its type MkN :: forall a. Show a => a -> N a • In the definition of data constructor ‘MkN’ In the newtype declaration for ‘N’ ===================================== testsuite/tests/typecheck/should_fail/T17955.stderr ===================================== @@ -1,6 +1,6 @@ -T17955.hs:6:13: error: - • A newtype constructor cannot have a context in its type +T17955.hs:6:13: error: [GHC-17440] + • A newtype constructor must not have a context in its type T :: Coercible () T => () -> T • In the definition of data constructor ‘T’ In the newtype declaration for ‘T’ ===================================== testsuite/tests/typecheck/should_fail/T18891a.stderr ===================================== @@ -1,12 +1,12 @@ -T18891a.hs:8:4: error: - • A newtype constructor must have a return type of form T a1 ... an - MkN1 :: N1 -> N1 +T18891a.hs:8:4: error: [GHC-89498] + • A newtype must not be a GADT + MkN1 :: N1 @GHC.Types.LiftedRep -> N1 @GHC.Types.LiftedRep • In the definition of data constructor ‘MkN1’ In the newtype declaration for ‘N1’ -T18891a.hs:12:3: error: - • A newtype constructor must have a return type of form T a1 ... an - MkN2 :: N2 -> N2 +T18891a.hs:12:3: error: [GHC-89498] + • A newtype must not be a GADT + MkN2 :: N2 @GHC.Types.LiftedRep -> N2 @GHC.Types.LiftedRep • In the definition of data constructor ‘MkN2’ In the newtype declaration for ‘N2’ ===================================== testsuite/tests/typecheck/should_fail/T21447.hs ===================================== @@ -0,0 +1,8 @@ +module T21447 where + +import Data.Kind (Type) +import GHC.Exts (TYPE) + +type H :: TYPE r -> Type +newtype H a where + H :: a -> H a ===================================== testsuite/tests/typecheck/should_fail/T21447.stderr ===================================== @@ -0,0 +1,6 @@ + +T21447.hs:8:3: error: [GHC-89498] + • A newtype must not be a GADT + H :: forall a. a -> H @GHC.Types.LiftedRep a + • In the definition of data constructor ‘H’ + In the newtype declaration for ‘H’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -659,3 +659,4 @@ test('T21338', normal, compile_fail, ['']) test('T21158', normal, compile_fail, ['']) test('T21583', normal, compile_fail, ['']) test('MissingDefaultMethodBinding', normal, compile_fail, ['']) +test('T21447', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/tcfail156.stderr ===================================== @@ -1,6 +1,6 @@ -tcfail156.hs:7:15: - A newtype constructor cannot have existential type variables - Foo :: forall a. a -> Foo - In the definition of data constructor ‘Foo’ - In the newtype declaration for ‘Foo’ +tcfail156.hs:7:15: error: [GHC-07525] + • A newtype constructor must not have existential type variables + Foo :: forall a. a -> Foo + • In the definition of data constructor ‘Foo’ + In the newtype declaration for ‘Foo’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eda6c05e65144b35de62c33d0fd5d35a417233ac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eda6c05e65144b35de62c33d0fd5d35a417233ac You're receiving 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 Oct 13 13:20:15 2022 From: gitlab at gitlab.haskell.org (Richard Eisenberg (@rae)) Date: Thu, 13 Oct 2022 09:20:15 -0400 Subject: [Git][ghc/ghc][wip/T21623] Fix the equality constraint problem Message-ID: <6348108f4d712_2c5d7351450530782@gitlab.mail> Richard Eisenberg pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: 462dd0df by Richard Eisenberg at 2022-10-13T08:51:30-04:00 Fix the equality constraint problem - - - - - 3 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -58,7 +58,7 @@ module GHC.Core.DataCon ( isUnboxedSumDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, - dataConUserTyVarsArePermuted, checkDataConTyVars, + dataConUserTyVarsNeedWrapper, checkDataConTyVars, isBanged, isMarkedStrict, cbvFromStrictMark, eqHsBang, isSrcStrict, isSrcUnpacked, specialPromotedDc, @@ -438,7 +438,7 @@ data DataCon -- Reason: less confusing, and easier to generate Iface syntax -- The type/coercion vars in the order the user wrote them [c,y,x,b] - -- INVARIANT(dataConTyVars: the set of tyvars in dcUserTyVarBinders is + -- INVARIANT(dataConTyVars): the set of tyvars in dcUserTyVarBinders is -- exactly the set of tyvars (*not* covars) of dcExTyCoVars unioned -- with the set of dcUnivTyVars whose tyvars do not appear in dcEqSpec -- See Note [DataCon user type variable binders] @@ -613,8 +613,8 @@ A DataCon has two different sets of type variables: and as a consequence, they do not come equipped with visibilities (that is, they are TyVars/TyCoVars instead of ForAllTyBinders). -Often (dcUnivTyVars ++ dcExTyCoVars) = dcUserTyVarBinder; but they may differ -for two reasons, coming next: +Often (dcUnivTyVars ++ dcExTyCoVars) = dcUserTyVarBinders; but they may differ +for three reasons, coming next: --- Reason (R1): Order of quantification in GADT syntax --- @@ -660,23 +660,102 @@ according to the rules of TypeApplications, in the absence of `forall` GHC performs a stable topological sort on the type variables in the user-written type signature, which would place `b` before `a`. ---- Reason (R2): GADTs introduce new existentials --- +--- Reason (R2): GADT constructors quantify over different variables --- -GADTs may also introduce extra existentials. Consider +GADT constructors may quantify over different variables than the worker +would. Consider data T a b where MkT :: forall c d. c -> T [c] d -Then we make up a fresh universal, say 'a', to be the first argument to T in -the result, and get this type for the "true underlying" worker data con: +The dcUserTyVarBinders must be [c, d] -- that's what the user quantified over. +But c is actually existential, as it is not equal to either of the two +universal variables. + +Here is what we'll get: + + dcUserTyVarBinders = [c, d] + dcUnivTyVars = [a, d] + dcExTyCoVars = [c] + +Note that dcUnivTyVars contains `a` from the type header (the `data T a b`) +and `d` from the signature for MkT. This is done because d is used in place +of b in the result of MkT, and so we use the name d for the universal, as that +might improve error messages. On the other hand, we need to use a fresh name +for the first universal (recalling that the result of a worker must be the +type constructor applied to a sequence of plain variables), so we use `a`, from +the header. This choice of universals is made in GHC.Tc.TyCl.mkGADTVars. + +Because c is not a universal, it is an existential. Here, we see that (even +ignoring order) dcUserTyVarBinders is not dcUnivTyVars ⋃ dcExTyCoVars, because +the latter has `a` while the former does not. To understand this better, let's +look at this type for the "true underlying" worker data con: MkT :: forall a d. forall c. (a ~# [c]) => c -> T a d -(We don't need to make up a fresh tyvar for the second arg; 'd' will do.) +We see here that the `a` universal is connected with the `c` existential via +an equality constraint. It will always be the case (see the code in mkGADTVars) +that the universals not mentioned in dcUserTyVarBinders will be used in a +GADT equality -- that is, used on the left-hand side of an element of dcEqSpec: + + dcEqSpec = [a ~# [c]] + +Putting this all together, all variables used on the left-hand side of an +equation in the dcEqSpec will be in dcUnivTyVars but *not* in +dcUserTyVarBinders. + +--- Reason (R3): Kind equalities may have been solved --- + +Consider now this case: + + type family F a where + F Type = False + F _ = True + type T :: forall k. (F k ~ True) => k -> k -> Type + data T a b where + MkT :: T Maybe List + +The constraint F k ~ True tells us that T does not want to be indexed by, say, +Int. Now let's consider the Core types involved: + + axiom for F: axF[0] :: F Type ~ False + axF[1] :: forall a. F a ~ True (a must be apart from Type) + tycon: T :: forall k. (F k ~ True) -> k -> k -> Type + wrapper: MkT :: T @(Type -> Type) @(Eq# (axF[1] (Type -> Type)) Maybe List + worker: MkT :: forall k (c :: F k ~ True) (a :: k) (b :: k). + (k ~# (Type -> Type), a ~# Maybe, b ~# List) => + T @k @c a b + +The key observation here is that the worker quantifies over c, while the wrapper +does not. The worker *must* quantify over c, because c is a universal variable, +and the result of the worker must be the type constructor applied to a sequence +of plain type variables. But the wrapper certainly does not need to quantify over +any evidence that F (Type -> Type) ~ True, as no variables are needed there. + +(Aside: the c here is a regular type variable, *not* a coercion variable. This +is because F k ~ True is a *lifted* equality, not the unlifted ~#. This is why +we see Eq# in the type of the wrapper: Eq# boxes the unlifted ~# to become a +lifted ~. See also Note [The equality types story] in GHC.Builtin.Types.Prim about +Eq# and Note [Constraints in kinds] in GHC.Core.TyCo.Rep about having this constraint +in the first place.) + +In this case, we'll have these fields of the DataCon: + + dcUserTyVarBinders = [] -- the wrapper quantifies over nothing + dcUnivTyVars = [k, c, a, b] + dcExTyCoVars = [] -- no existentials here, but a different constructor might have + dcEqSpec = [k ~# (Type -> Type), a ~# Maybe, b ~# List] + +Note that c is in the dcUserTyVars, but mentioned neither in the dcUserTyVarBinders nor +in the dcEqSpec. We thus have Reason (R3): a variable might be missing from the +dcUserTyVarBinders if its type's kind is Constraint. + +(At one point, we thought that the dcEqSpec would have to be non-empty. But that +wouldn't account for silly cases like type T :: (True ~ True) => Type.) --- End of Reasons --- INVARIANT(dataConTyVars): the set of tyvars in dcUserTyVarBinders -consists precisely of: +consists of: * The set of tyvars in dcUnivTyVars whose type variables do not appear in dcEqSpec, unioned with: @@ -684,12 +763,16 @@ consists precisely of: * The set of tyvars (*not* covars) in dcExTyCoVars No covars here because because they're not user-written +When comparing for equality, we ignore differences concerning type variables +whose kinds have kind Constraint. + The word "set" is used above because the order in which the tyvars appear in dcUserTyVarBinders can be completely different from the order in dcUnivTyVars or dcExTyCoVars. That is, the tyvars in dcUserTyVarBinders are a permutation of (tyvars of dcExTyCoVars + a subset of dcUnivTyVars). But aside from the ordering, they in fact share the same type variables (with the same Uniques). We -sometimes refer to this as "the dcUserTyVarBinders invariant". +sometimes refer to this as "the dcUserTyVarBinders invariant". It is checked +in checkDataConTyVars. 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 @@ -1668,7 +1751,7 @@ dataConCannotMatch tys con -- -- This is not a cheap test, so we minimize its use in GHC as much as possible. -- Currently, its only call site in the GHC codebase is in 'mkDataConRep' in --- "MkId", and so 'dataConUserTyVarsArePermuted' is only called at most once +-- "MkId", and so 'dataConUserTyVarsNeedWrapper' is only called at most once -- during a data constructor's lifetime. dataConResRepTyArgs :: DataCon -> [Type] @@ -1696,20 +1779,42 @@ dataConResRepTyArgs dc@(MkData { dcRepTyCon = rep_tc, dcOrigResTy = orig_res_ty checkDataConTyVars :: DataCon -> Bool -- Check that the worker and wrapper have the same set of type variables --- See Note [DataCon user type variable binders], as well as -checkDataConTyVars dc - = mkUnVarSet (dataConUnconstrainedTyVars dc) == mkUnVarSet (dataConUserTyVars dc) - -- Worker tyvars ...should be the same set as...wrapper tyvars +-- See Note [DataCon user type variable binders] +-- Also ensures that no user tyvar is in the eq_spec (the eq_spec should +-- only relate fresh universals from (R2) of the note) +checkDataConTyVars dc@(MkData { dcUnivTyVars = univ_tvs + , dcExTyCoVars = ex_tvs + , dcEqSpec = eq_spec }) + -- use of sets here: (R1) from the Note + = mkUnVarSet depleted_worker_vars == mkUnVarSet depleted_wrapper_vars && + all (not . is_eq_spec_var) wrapper_vars + where + is_constraint_var v = typeTypeOrConstraint (tyVarKind v) == ConstraintLike + -- implements (R3) from the Note + + worker_vars = univ_tvs ++ ex_tvs + eq_spec_tvs = mkUnVarSet (map eqSpecTyVar eq_spec) + is_eq_spec_var = (`elemUnVarSet` eq_spec_tvs) -- (R2) from the Note + depleted_worker_vars = filterOut (is_eq_spec_var <||> is_constraint_var) + worker_vars + + wrapper_vars = dataConUserTyVars dc + depleted_wrapper_vars = filterOut is_constraint_var wrapper_vars -dataConUserTyVarsArePermuted :: DataCon -> Bool --- Check whether the worker and wapper have their tpye variables in --- the same order. If not, we need a wrapper to swizzle them. +dataConUserTyVarsNeedWrapper :: DataCon -> Bool +-- Check whether the worker and wapper have the same type variables +-- in the same order. If not, we need a wrapper to swizzle them. -- See Note [DataCon user type variable binders], as well as -- Note [Data con wrappers and GADT syntax] for an explanation of what -- mkDataConRep is doing with this function. -dataConUserTyVarsArePermuted dc - = dataConUnconstrainedTyVars dc /= dataConUserTyVars dc - -- Worker tyvars Wrapper tyvars +dataConUserTyVarsNeedWrapper dc@(MkData { dcUnivTyVars = univ_tvs + , dcExTyCoVars = ex_tvs + , dcEqSpec = eq_spec }) + = assert (null eq_spec || answer) -- all GADTs should say "yes" here + answer + where + answer = (univ_tvs ++ ex_tvs) /= dataConUserTyVars dc + -- Worker tyvars Wrapper tyvars -- | Return the quantified variables (universal and existential) -- that are unconstrained by dcEqSpec, in the order that the /worker/ expects ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4037,6 +4037,8 @@ mkGADTVars tmpl_tvs dc_tvs subst | not (r_tv `elem` univs) , tyVarKind r_tv `eqType` (substTy t_sub (tyVarKind t_tv)) -> -- simple, well-kinded variable substitution. + -- the name of the universal comes from the result of the ctor + -- see (R2) of Note [DataCon user type variable binders] in GHC.Core.DataCon choose (r_tv:univs) eqs (extendTvSubst t_sub t_tv r_ty') (extendTvSubst r_sub r_tv r_ty') @@ -4046,7 +4048,8 @@ mkGADTVars tmpl_tvs dc_tvs subst r_ty' = mkTyVarTy r_tv1 -- Not a simple substitution: make an equality predicate - + -- the name of the universal comes from the datatype header + -- see (R2) of Note [DataCon user type variable binders] in GHC.Core.DataCon _ -> choose (t_tv':univs) eqs' (extendTvSubst t_sub t_tv (mkTyVarTy t_tv')) -- We've updated the kind of t_tv, ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -784,16 +784,16 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con (not new_tycon -- (Most) newtypes have only a worker, with the exception -- of some newtypes written with GADT syntax. See below. - && (any isBanged (ev_ibangs ++ arg_ibangs) + && (any isBanged (ev_ibangs ++ arg_ibangs))) -- Some forcing/unboxing (includes eq_spec) - || (not $ null eq_spec))) -- GADT || isFamInstTyCon tycon -- Cast result - || dataConUserTyVarsArePermuted data_con + || dataConUserTyVarsNeedWrapper data_con -- If the data type was written with GADT syntax and -- orders the type variables differently from what the -- worker expects, it needs a data con wrapper to reorder -- the type variables. -- See Note [Data con wrappers and GADT syntax]. + -- NB: All GADTs return true from this function || not (null stupid_theta) -- If the data constructor has a datatype context, -- we need a wrapper in order to drop the stupid arguments. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/462dd0df14af81837ee07feedbf9bbc6a18267df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/462dd0df14af81837ee07feedbf9bbc6a18267df You're receiving 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 Oct 13 14:34:22 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 13 Oct 2022 10:34:22 -0400 Subject: [Git][ghc/ghc][wip/andreask/ghci-tag-nullary] 55 commits: Apply some tricks to speed up core lint. Message-ID: <634821ee7ad45_2c5d735148c559063@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/ghci-tag-nullary at Glasgow Haskell Compiler / GHC Commits: c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 2c5ac51f by Andreas Klebinger at 2022-10-13T15:40:04+02:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcbed0096daa44071274ac7784f722feed1fb24b...2c5ac51ffeb84312a8b63f61a9d34f3e443054ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcbed0096daa44071274ac7784f722feed1fb24b...2c5ac51ffeb84312a8b63f61a9d34f3e443054ce You're receiving 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 Oct 13 14:39:39 2022 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Thu, 13 Oct 2022 10:39:39 -0400 Subject: [Git][ghc/ghc][wip/js-staging] start a subtransaction in a catchStm block Message-ID: <6348232b1a3d9_2c5d73513c45597df@gitlab.mail> Luite Stegeman pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: f0d136d5 by Luite Stegeman at 2022-10-13T16:38:52+02:00 start a subtransaction in a catchStm block - - - - - 2 changed files: - compiler/GHC/StgToJS/Rts/Rts.hs - rts/js/stm.js Changes: ===================================== compiler/GHC/StgToJS/Rts/Rts.hs ===================================== @@ -674,7 +674,9 @@ rts' s = <> appS "h$stmCommitTransaction" [] <> returnS (stack .! sp)) , closure (ClosureInfo "h$catchStm_e" (CIRegs 0 [PtrV]) "STM catch" (CILayoutFixed 3 [ObjV,PtrV,ObjV]) CIStackFrame mempty) - (adjSpN' 4 <> returnS (stack .! sp)) + (adjSpN' 4 + <> appS "h$stmCommitTransaction" [] + <> returnS (stack .! sp)) , closure (ClosureInfo "h$stmResumeRetry_e" (CIRegs 0 [PtrV]) "resume retry" (CILayoutFixed 0 []) CIStackFrame mempty) (jVar $ \blocked -> mconcat [ jwhenS (stack .! (sp - 2) .!==. var "h$atomically_e") ===================================== rts/js/stm.js ===================================== @@ -222,6 +222,7 @@ function h$stmCatchRetry(a,b) { function h$catchStm(a,handler) { h$p4(h$currentThread.transaction, h$currentThread.mask, handler, h$catchStm_e); + h$currentThread.transaction = new h$Transaction(handler, h$currentThread.transaction); h$r1 = a; return h$ap_1_0_fast(); } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f0d136d5b49f1263a3cf79cae5799ae772204c6b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f0d136d5b49f1263a3cf79cae5799ae772204c6b You're receiving 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 Oct 13 16:47:24 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 13 Oct 2022 12:47:24 -0400 Subject: [Git][ghc/ghc][wip/T21623] 49 commits: chore: extend `.editorconfig` for C files Message-ID: <6348411c72636_2c5d73513d8568566@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 13825da2 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Start work Not ready for review More progress Wibbles Stage1 compiles More wibbles More wibbles More -- almost working Comments Wibbles Wibbles Wibble inlineId Wibbles Infinite loop somewhere More wibbles. Maybe can build stage2 Make FuNCo a thing by itself Wibble Wibble Wibbles Fix OptCoercion Wibble Wibble to optCoercion Replace SORT with TYPE and CONSTRAINT Wibble Delete unused import Delete TypeOrConstraint from ghc-prim:GHC.Types Move from NthCo to SelCo Wibbles Wibbles in RepType Wibble Add mkWpEta Really add mkWpEta Wibble Typeable binds etc Improve error messages More wibbles, mainly to error messages Wibbles Wibbles to errors Wibbles But especially: treat Constraint as Typeable More wibbles More changes * Move role into SelTyCon * Get rid of mkTcSymCo and friends Unused variable Wibbles Wibble Accept error message changes Refactoring... Remove tc functions like tcKind, tcGetTyVar. Move tyConsOfType, occCheckExpand to TyCo.FVs. Introduce GHC.Core.TyCo.Compare Lots of import changes! Update haddock submodule (I hope) Wibbles (notably: actually add GHC.Core.TyCo.Compare) Wibbles Wibble output of T16575 Wibbles More wibbles Remove infinite loop in T1946 See Note [ForAllTy and type equality] Deal with rejigConRes Needs a Note to be written by Richard Some renaming AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag Update haddock submodule Rename TyCoBinder to ForAllTyBinder Wibbles Update haddock Wibble Update unix submodule I think I accidentally got it out of sync with HEAD; this puts it back. Rename TyCoBinder to PiTyBinder Update Haddock submodule Wrap dictionaries in tuples This fixes the kind bugs in arrow desugaring. Needs some Notes, but I want to try CI. More on boxing data cons Rebase and update GHC.Tc.Errors/GHC.Tc.Errors.Ppr Revert accidental changes in SameOccInfo fixes mod180, tcfail182 Wibbles in error messages ..plus eqType comes from GHC.Core.TyCo.Compare Wibbles More wibbles Reaedy for RAE review Fix fragile rule setup in GHC.Float See Note [realToFrac natural-to-float] Wibbles More wibbles Remove unused import Remove another unused import Wibbles Update haddock submodule Respond to Sam's suggestions Wibbles Wibbles - - - - - b6086325 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Wibbles - - - - - d3699ec5 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Unused import - - - - - 59ce0265 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Better boxingCon_maybe - - - - - e699d4a9 by Richard Eisenberg at 2022-10-13T17:49:07+01:00 Improvements to comments, etc., from Richard - - - - - 955ef70a by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Respond to Richard - - - - - bd8e3133 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Improve boxing-data-con API - - - - - c864a995 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Update error messages - - - - - 285dceba by Richard Eisenberg at 2022-10-13T17:49:07+01:00 Fix the equality constraint problem - - - - - dd92d841 by Simon Peyton Jones at 2022-10-13T17:49:07+01:00 Wibbles - - - - - 19 changed files: - .editorconfig - README.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types.hs-boot - compiler/GHC/Builtin/Types/Literals.hs - compiler/GHC/Builtin/Types/Prim.hs - − compiler/GHC/Builtin/Types/Prim.hs-boot - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - 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/462dd0df14af81837ee07feedbf9bbc6a18267df...dd92d841874124250fdb916525d6db5108eafdf2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/462dd0df14af81837ee07feedbf9bbc6a18267df...dd92d841874124250fdb916525d6db5108eafdf2 You're receiving 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 Oct 13 16:52:37 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 13 Oct 2022 12:52:37 -0400 Subject: [Git][ghc/ghc][wip/fix-ubx-cast] Properly convert values before/after storing them in unboxed sums. Message-ID: <63484255d7ea7_2c5d73514505710f8@gitlab.mail> Andreas Klebinger pushed to branch wip/fix-ubx-cast at Glasgow Haskell Compiler / GHC Commits: 4feb4966 by Andreas Klebinger at 2022-10-13T18:45:24+02:00 Properly convert values before/after storing them in unboxed sums. See Note [Casting slot arguments] for the details. - - - - - 17 changed files: - + compiler/GHC/Builtin/PrimOps/Casts.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/Types/RepType.hs - compiler/GHC/Utils/Outputable.hs - compiler/ghc.cabal.in - docs/users_guide/debugging.rst - testsuite/driver/testlib.py - + testsuite/tests/unboxedsums/GenManyUbxSums.hs - + testsuite/tests/unboxedsums/ManyUbxSums.stdout - + testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs - + testsuite/tests/unboxedsums/T22208.hs - testsuite/tests/unboxedsums/all.T Changes: ===================================== compiler/GHC/Builtin/PrimOps/Casts.hs ===================================== @@ -0,0 +1,213 @@ +{- +This module contains helpers to cast variables +between different Int/WordReps in StgLand. + +-} + +module GHC.Builtin.PrimOps.Casts + ( getCasts ) +where + +import GHC.Prelude + +import GHC.Core.TyCon +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Utils.Panic.Plain +import GHC.Types.RepType +import GHC.Core.Type +import GHC.Builtin.Types.Prim +import GHC.Builtin.Types + +import GHC.Builtin.PrimOps +import GHC.Plugins (HasDebugCallStack) + +{- Note [PrimRep based casting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This module contains a number of utility functions useful when +converting between variables of differing PrimReps. + +The general pattern is: +* We have two primReps `from_rep` and `to_rep`. +* We want a list of PrimOps we can apply to a variable of rep `from_rep`. +Applying the list of primOps in order takes us to `to_rep` from `from_rep` giving +us a variable of the returned type at each step. + +E.g. we call `getCasts from_rep to_rep` and get back [(op1#,ty1),(op2#,ty2)]. +We can use this list of primOps to construct a function of type +`StgExpr -> StgExpr` by construction an expression + + case op1# of (x' :: ty1) -> case op2# x' of x' -> + +Ideally backends will compile the sequence of PrimOps to a no-op. E.g. by reusing +the same register but just relabeling it as another width. +However this is might not always be possible or the required optimizations +simply not implemented in the backend. This means currently many of these casts +will be cheap but not all of them will be completely zero-cost. + +-} + +-- | `getCasts from_rep to_rep` gives us a list of primops which when applied in order convert from_rep to to_rep. +-- See Note [PrimRep based casting] +getCasts :: PrimRep -> PrimRep -> [(PrimOp,Type)] +getCasts from_rep to_rep + -- No-op + | -- pprTrace "getCasts" (ppr (from_rep,to_rep)) $ + to_rep == from_rep + = [] + + -- Float <-> Double + | to_rep == FloatRep = + assertPpr (from_rep == DoubleRep) (ppr from_rep <+> ppr to_rep) $ + [(DoubleToFloatOp,floatPrimTy)] + | to_rep == DoubleRep = + assertPpr (from_rep == FloatRep) (ppr from_rep <+> ppr to_rep) $ + [(FloatToDoubleOp,doublePrimTy)] + + -- Addr <-> Word/Int + | to_rep == AddrRep = wordOrIntToAddrRep from_rep + | from_rep == AddrRep = addrToWordOrIntRep to_rep + + -- Int* -> Int* + | primRepIsInt from_rep + , primRepIsInt to_rep + = sizedIntToSizedInt from_rep to_rep + + -- Word* -> Word* + | primRepIsWord from_rep + , primRepIsWord to_rep + = sizedWordToSizedWord from_rep to_rep + + -- Word* -> Int* + | primRepIsWord from_rep + , primRepIsInt to_rep + = let (op1,r1) = wordToIntRep from_rep + in (op1,primRepToType r1):sizedIntToSizedInt r1 to_rep + + -- Int* -> Word* + | primRepIsInt from_rep + , primRepIsWord to_rep + = let (op1,r1) = intToWordRep from_rep + in (op1,primRepToType r1):sizedWordToSizedWord r1 to_rep + + | otherwise = pprPanic "getCasts:Unexpect rep combination" + (ppr (from_rep,to_rep)) + +wordOrIntToAddrRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)] +wordOrIntToAddrRep AddrRep = [] -- No-op argument is already AddrRep +wordOrIntToAddrRep IntRep = [(IntToAddrOp, addrPrimTy)] +wordOrIntToAddrRep WordRep = [(WordToIntOp,intPrimTy), (IntToAddrOp,addrPrimTy)] +wordOrIntToAddrRep r + | primRepIsInt r = (intToMachineInt r,intPrimTy):[(IntToAddrOp,addrPrimTy)] + | primRepIsWord r = + let (op1,r1) = wordToIntRep r + in (op1, primRepToType r1):[(intToMachineInt r1,intPrimTy), (IntToAddrOp,addrPrimTy)] + | otherwise = pprPanic "Rep not word or int rep" (ppr r) + +addrToWordOrIntRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)] +-- Machine sizes +addrToWordOrIntRep IntRep = [(AddrToIntOp, intPrimTy)] +addrToWordOrIntRep WordRep = [(AddrToIntOp,intPrimTy), (IntToWordOp,wordPrimTy)] +-- Explicitly sized reps +addrToWordOrIntRep r + | primRepIsWord r = (AddrToIntOp,intPrimTy) : (IntToWordOp,wordPrimTy) : sizedWordToSizedWord WordRep r + | primRepIsInt r = (AddrToIntOp,intPrimTy) : sizedIntToSizedInt IntRep r + | otherwise = pprPanic "Target rep not word or int rep" (ppr r) + + +-- WordX# -> IntX# (same size), argument is source rep +wordToIntRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep) +wordToIntRep rep + = case rep of + (WordRep) -> (WordToIntOp, IntRep) + (Word8Rep) -> (Word8ToInt8Op, Int8Rep) + (Word16Rep) -> (Word16ToInt16Op, Int16Rep) + (Word32Rep) -> (Word32ToInt32Op, Int32Rep) + (Word64Rep) -> (Word64ToInt64Op, Int64Rep) + _ -> pprPanic "Rep not a wordRep" (ppr rep) + +-- IntX# -> WordX#, argument is source rep +intToWordRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep) +intToWordRep rep + = case rep of + (IntRep) -> (IntToWordOp, WordRep) + (Int8Rep) -> (Int8ToWord8Op, Word8Rep) + (Int16Rep) -> (Int16ToWord16Op, Word16Rep) + (Int32Rep) -> (Int32ToWord32Op, Word32Rep) + (Int64Rep) -> (Int64ToWord64Op, Word64Rep) + _ -> pprPanic "Rep not a wordRep" (ppr rep) + +-- Casts between any size int to any other size of int +sizedIntToSizedInt :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)] +sizedIntToSizedInt r1 r2 + | r1 == r2 = [] +-- Cast to Int# +sizedIntToSizedInt r IntRep = [(intToMachineInt r,intTy)] +-- Cast from Int# +sizedIntToSizedInt IntRep r = [(intFromMachineInt r,primRepToType r)] +-- Sized to differently sized must go over machine word. +sizedIntToSizedInt r1 r2 = (intToMachineInt r1,intTy) : [(intFromMachineInt r2,primRepToType r2)] + +-- Casts between any size Word to any other size of Word +sizedWordToSizedWord :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)] +sizedWordToSizedWord r1 r2 + | r1 == r2 = [] +-- Cast to Word# +sizedWordToSizedWord r WordRep = [(wordToMachineWord r,wordPrimTy)] +-- Cast from Word# +sizedWordToSizedWord WordRep r = [(wordFromMachineWord r, primRepToType r)] +-- Conversion between different non-machine sizes must go via machine word. +sizedWordToSizedWord r1 r2 = (wordToMachineWord r1,wordPrimTy) : [(wordFromMachineWord r2, primRepToType r2)] + + +-- Prefer the definitions above this line if possible +---------------------- + + +-- Int*# to Int# +{-# INLINE intToMachineInt #-} +intToMachineInt :: HasDebugCallStack => PrimRep -> PrimOp +intToMachineInt r = + assertPpr (primRepIsInt r) (ppr r) $ + case r of + (Int8Rep) -> Int8ToIntOp + (Int16Rep) -> Int16ToIntOp + (Int32Rep) -> Int32ToIntOp + (Int64Rep) -> Int64ToIntOp + _ -> pprPanic "Source rep not int" $ ppr r + +-- Int# to Int*# +{-# INLINE intFromMachineInt #-} +intFromMachineInt :: HasDebugCallStack => PrimRep -> PrimOp +intFromMachineInt r = + assertPpr (primRepIsInt r) (ppr r) $ + case r of + Int8Rep -> IntToInt8Op + Int16Rep -> IntToInt16Op + Int32Rep -> IntToInt32Op + Int64Rep -> IntToInt64Op + _ -> pprPanic "Dest rep not sized int" $ ppr r + +-- Word# to Word*# +{-# INLINE wordFromMachineWord #-} +wordFromMachineWord :: HasDebugCallStack => PrimRep -> PrimOp +wordFromMachineWord r = + assert (primRepIsWord r) $ + case r of + Word8Rep -> WordToWord8Op + Word16Rep -> WordToWord16Op + Word32Rep -> WordToWord32Op + Word64Rep -> WordToWord64Op + _ -> pprPanic "Dest rep not sized word" $ ppr r + +-- Word*# to Word# +{-# INLINE wordToMachineWord #-} +wordToMachineWord :: HasDebugCallStack => PrimRep -> PrimOp +wordToMachineWord r = + assertPpr (primRepIsWord r) (text "Not a word rep:" <> ppr r) $ + case r of + Word8Rep -> Word8ToWordOp + Word16Rep -> Word16ToWordOp + Word32Rep -> Word32ToWordOp + Word64Rep -> Word64ToWordOp + _ -> pprPanic "Dest rep not sized word" $ ppr r \ No newline at end of file ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1399,7 +1399,10 @@ instance OutputableP Platform CLabel where pdoc !platform lbl = getPprStyle $ \pp_sty -> case pp_sty of PprDump{} -> pprCLabel platform CStyle lbl - _ -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl) + -- Workaround for #22218 + _ -> (pprCLabel platform CStyle lbl) + -- _ -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl) + pprCLabel :: Platform -> LabelStyle -> CLabel -> SDoc pprCLabel !platform !sty lbl = -- see Note [Bangs in CLabel] ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -129,6 +129,7 @@ module GHC.Core.TyCon( primRepIsFloat, primRepsCompatible, primRepCompatible, + primRepIsWord, primRepIsInt, ) where @@ -1785,6 +1786,24 @@ primRepIsFloat DoubleRep = Just True primRepIsFloat (VecRep _ _) = Nothing primRepIsFloat _ = Just False +-- Rep is one of the word reps. +primRepIsWord :: PrimRep -> Bool +primRepIsWord WordRep = True +primRepIsWord (Word8Rep) = True +primRepIsWord (Word16Rep) = True +primRepIsWord (Word32Rep) = True +primRepIsWord (Word64Rep) = True +primRepIsWord _ = False + +-- Rep is one of the int reps. +primRepIsInt :: PrimRep -> Bool +primRepIsInt (IntRep) = True +primRepIsInt (Int8Rep) = True +primRepIsInt (Int16Rep) = True +primRepIsInt (Int32Rep) = True +primRepIsInt (Int64Rep) = True +primRepIsInt _ = False + {- ************************************************************************ * * ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -422,6 +422,7 @@ data GeneralFlag -- variables that have otherwise identical names. | Opt_SuppressUniques | Opt_SuppressStgExts + | Opt_SuppressStgReps | Opt_SuppressTicks -- Replaces Opt_PprShowTicks | Opt_SuppressTimestamps -- ^ Suppress timestamps in dumps | Opt_SuppressCoreSizes -- ^ Suppress per binding Core size stats in dumps ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2393,6 +2393,7 @@ dynamic_flags_deps = [ setGeneralFlag Opt_SuppressIdInfo setGeneralFlag Opt_SuppressTicks setGeneralFlag Opt_SuppressStgExts + setGeneralFlag Opt_SuppressStgReps setGeneralFlag Opt_SuppressTypeSignatures setGeneralFlag Opt_SuppressCoreSizes setGeneralFlag Opt_SuppressTimestamps) @@ -3344,6 +3345,7 @@ dFlagsDeps = [ depFlagSpec' "suppress-stg-free-vars" Opt_SuppressStgExts (useInstead "-d" "suppress-stg-exts"), flagSpec "suppress-stg-exts" Opt_SuppressStgExts, + flagSpec "suppress-stg-reps" Opt_SuppressStgReps, flagSpec "suppress-coercions" Opt_SuppressCoercions, flagSpec "suppress-coercion-types" Opt_SuppressCoercionTypes, flagSpec "suppress-idinfo" Opt_SuppressIdInfo, @@ -3796,7 +3798,8 @@ defaultFlags settings Opt_VersionMacros, Opt_RPath, Opt_DumpWithWays, - Opt_CompactUnwind + Opt_CompactUnwind, + Opt_SuppressStgReps ] ++ [f | (ns,f) <- optLevelFlags, 0 `elem` ns] @@ -5020,6 +5023,7 @@ initSDocContext dflags style = SDC , sdocSuppressUniques = gopt Opt_SuppressUniques dflags , sdocSuppressModulePrefixes = gopt Opt_SuppressModulePrefixes dflags , sdocSuppressStgExts = gopt Opt_SuppressStgExts dflags + , sdocSuppressStgReps = gopt Opt_SuppressStgReps dflags , sdocErrorSpans = gopt Opt_ErrorSpans dflags , sdocStarIsType = xopt LangExt.StarIsType dflags , sdocLinearTypes = xopt LangExt.LinearTypes dflags ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -87,7 +87,7 @@ import GHC.Core.Ppr( {- instances -} ) import GHC.Builtin.PrimOps ( PrimOp, PrimCall ) import GHC.Core.TyCon ( PrimRep(..), TyCon ) import GHC.Core.Type ( Type ) -import GHC.Types.RepType ( typePrimRep1 ) +import GHC.Types.RepType ( typePrimRep1, typePrimRep ) import GHC.Utils.Panic.Plain {- @@ -740,12 +740,23 @@ pprStgTopBinding = pprGenStgTopBinding pprStgTopBindings :: OutputablePass pass => StgPprOpts -> [GenStgTopBinding pass] -> SDoc pprStgTopBindings = pprGenStgTopBindings +pprIdWithRep :: Id -> SDoc +pprIdWithRep v = ppr v <> pprTypeRep (idType v) + +pprTypeRep :: Type -> SDoc +pprTypeRep ty = + ppUnlessOption sdocSuppressStgReps $ + char ':' <> case typePrimRep ty of + [r] -> ppr r + r -> ppr r + + instance Outputable StgArg where ppr = pprStgArg pprStgArg :: StgArg -> SDoc -pprStgArg (StgVarArg var) = ppr var -pprStgArg (StgLitArg con) = ppr con +pprStgArg (StgVarArg var) = pprIdWithRep var +pprStgArg (StgLitArg con) = ppr con <> pprTypeRep (literalType con) instance OutputablePass pass => Outputable (GenStgExpr pass) where ppr = pprStgExpr panicStgPprOpts ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -186,6 +186,132 @@ So we pass type arguments of the DataCon's TyCon in StgConApp to decide what layout to use. Note that unlifted values can't be let-bound, so we don't need types in StgRhsCon. +Note [Casting slot arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this function which selects between Float# and Double# from a unboxed sum. + + foo :: (# Float# | Double# #) -> FD + foo x = case x of + (# x1 | #) -> F x1 + (# | x2 #) -> D x2 + +Naturally we would expect x1 to have a PrimRep of FloatRep and x2 of DoubleRep. +However we used to generate this (bogus) code after Unarise giving rise to #22208: + + M.foo :: (# GHC.Prim.Float# | GHC.Prim.Double# #) -> M.FD + [GblId, Arity=1, Unf=OtherCon []] = + {} \r [sum_tag sum_field] + case sum_tag of tag_gsc { + __DEFAULT -> M.F [sum_field]; + 2# -> M.D [sum_field]; + }; + +Where sum_field is used both as Float# and Double# depending on the branch +because they share the same SlotTy. +This usually works out since we put floats/doubles in the same sort of register. +However this caused issues down the road where we would assign between variables +of different reps causing lint errors or in the case of #22208 even compiler panics. +For now our solution is to construct proper casts between the PrimRep of the slot and +the variables we want to store in, or read out of these slots. + +This means when we have a sum (# Float# | Double# #) if we want to store a float +we convert it to a double on construction of the tuple value, and convert it back +to a float once when want to use the field. +Conversion for values coming out of a strict field happen in mapSumIdBinders. While +conversion during the construction of sums happen inside mkUbxSum. + +------------- A full example of casting during sum construction ---------------- + +To give a full example if we *construct* a unboxed sum of +type (# Int32# | Int64# ) in an expression like `let sum = (# | #) x` +Then we will call mkUbxSum to determine which arguments we have to pass in which +order to the unboxed tuple that represents the unboxed sum. + +Int32# and Int# in this case will share the same slot in the unboxed sum. This +means we want to upcast the argument in order to match up the reps of the +variables. To do this mkUbxSum will produce a casting expression with a hole for +the original rhs to go into. That is the call to mkUbxSum and it's result will +look something like: + + >>> mkUbxSum (#|#) [Int32#, Int#] (x::Int32#) us(x') + ([x'::Double#], case int32ToInt# x of x' -> <_hole_> ) + +We will use the returned arguments to construct an application to an unboxed tuple: + + (# #) 1# x' + +Which we will then use to construct an expression that casts `x` to the right type +and places it into x': + + >>> (\_hole_ -> case int32ToInt# x of x' -> _hole_) ((# #) 1# x') + case int32ToInt# x of x' -> (# #) 1# x' + +Which results in the this definition for `sum` after all is said and done: + + let sum = case int32ToInt# x of { x' -> (# #) 1# x' } + +You might wonder why we bother renaming `x` to `x'`. It's quite subtle. Consider +a definition like this: + + let sum_shadow :: (# (# Int32#, Int32# ) | Int64# #) + let sum_shadow = (# |#) (# x, x #) + +We compute the required slots for the tuple and come up with +`[WordSlot, Word64Slot]`. For the first sum constructor we will place `x` both +in a Word and a Word64Slot. If we would not rename the constructor what we would +get would be: + + let sum_shadow = case int32ToInt# x of + { x -> + (# #) 1# x x -- With the unboxed tuple having type (# #) :: (# Int#, Int#, Int64 #) + } + +Clearly this is somewhat bogus, we would end up using the same `x` as a +Int# and a Int64# value! + +------------- A full example of casting during sum matching -------------------- + +When matching on the same unboxed sum constructor as above we start out with +something like this the pre-unarise: + + f sum = case sum of + (# x |#) -> ... x ... -- (# x |#) :: (# Int32, Int#) + ... + +We start desugaring and get: + + f sum_tag sum_slot_arg_1 = case sum_tag of + 1# -> ??? + +Now we need to match the slot arguments to binders in the original case +alternative. This is done by mapSumIdBinders which we we call for our +example alternative like this: + + >>> mapSumIdBinders [x] [sum_slot_arg_1] alt_rhs env + (env', alt_rhs') + +mapSumIdBinders first matches up the list of binders with the slots passed to +the function which is trivial in this case. Then we check if the slot and the +variable residing inside it agree on their Rep. If all binders and slot reps +agree we just extend the environment with a mapping from `x` to `sum_slot_arg_1` +and we return the rhs as is. +If the reps do not agree then we wrap the whole RHS in a case which casts the +bound variable to a type of the correct representation. Here `x` is of Int32Rep +while `sum_slot_arg_1` will be of IntRep. This means instead of retuning the +original alt_rhs we will return: + + case intToInt32# (x :: Int#) of + (x :: Int32#) -> original_alt_rhs + +We then run unarise on this expression, which will replace the first occurence +of `x` with sum_slot_arg_1 giving us post-unarise: + + f sum_tag sum_slot_arg_1 = + case sum_tag of + 1# -> case intToInt32# sum_slot_arg_1 of + x -> ... x ... + ... + Note [UnariseEnv] ~~~~~~~~~~~~~~~~~~ At any variable occurrence 'v', @@ -258,8 +384,8 @@ import GHC.Prelude import GHC.Types.Basic import GHC.Core import GHC.Core.DataCon -import GHC.Core.TyCon ( isVoidRep ) -import GHC.Data.FastString (FastString, mkFastString) +import GHC.Core.TyCon +import GHC.Data.FastString (FastString, mkFastString, fsLit, appendFS) import GHC.Types.Id import GHC.Types.Literal import GHC.Core.Make (aBSENT_SUM_FIELD_ERROR_ID) @@ -281,6 +407,10 @@ import GHC.Types.Var.Env import Data.Bifunctor (second) import Data.Maybe (mapMaybe) import qualified Data.IntMap as IM +import GHC.Builtin.PrimOps +import GHC.Builtin.PrimOps.Casts +import Data.List (mapAccumL) +import GHC.Types.Name -------------------------------------------------------------------------------- @@ -306,8 +436,10 @@ import qualified Data.IntMap as IM -- INVARIANT: OutStgArgs in the range only have NvUnaryTypes -- (i.e. no unboxed tuples, sums or voids) -- -type UnariseEnv = VarEnv UnariseVal +newtype UnariseEnv = UnariseEnv { ue_rho :: (VarEnv UnariseVal) } +initUnariseEnv :: VarEnv UnariseVal -> UnariseEnv +initUnariseEnv = UnariseEnv data UnariseVal = MultiVal [OutStgArg] -- MultiVal to tuple. Can be empty list (void). | UnaryVal OutStgArg -- See Note [Renaming during unarisation]. @@ -320,25 +452,27 @@ instance Outputable UnariseVal where -- The id is mapped to one or more things. -- See Note [UnariseEnv] extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv -extendRho rho x (MultiVal args) +extendRho env x (MultiVal args) = assert (all (isNvUnaryType . stgArgType) args) - extendVarEnv rho x (MultiVal args) -extendRho rho x (UnaryVal val) + env { ue_rho = extendVarEnv (ue_rho env) x (MultiVal args) } +extendRho env x (UnaryVal val) = assert (isNvUnaryType (stgArgType val)) - extendVarEnv rho x (UnaryVal val) + env { ue_rho = extendVarEnv (ue_rho env) x (UnaryVal val) } -- Properly shadow things from an outer scope. -- See Note [UnariseEnv] -- The id stands for itself so we don't record a mapping. -- See Note [UnariseEnv] extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv -extendRhoWithoutValue rho x = delVarEnv rho x +extendRhoWithoutValue env x = env { ue_rho = delVarEnv (ue_rho env) x } +lookupRho :: UnariseEnv -> Id -> Maybe UnariseVal +lookupRho env v = lookupVarEnv (ue_rho env) v -------------------------------------------------------------------------------- unarise :: UniqSupply -> [StgTopBinding] -> [StgTopBinding] -unarise us binds = initUs_ us (mapM (unariseTopBinding emptyVarEnv) binds) +unarise us binds = initUs_ us (mapM (unariseTopBinding (initUnariseEnv emptyVarEnv)) binds) unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding unariseTopBinding rho (StgTopLifted bind) @@ -366,7 +500,7 @@ unariseRhs rho (StgRhsCon ccs con mu ts args) unariseExpr :: UnariseEnv -> StgExpr -> UniqSM StgExpr unariseExpr rho e@(StgApp f []) - = case lookupVarEnv rho f of + = case lookupRho rho f of Just (MultiVal args) -- Including empty tuples -> return (mkTuple args) Just (UnaryVal (StgVarArg f')) @@ -379,7 +513,7 @@ unariseExpr rho e@(StgApp f []) unariseExpr rho e@(StgApp f args) = return (StgApp f' (unariseFunArgs rho args)) where - f' = case lookupVarEnv rho f of + f' = case lookupRho rho f of Just (UnaryVal (StgVarArg f')) -> f' Nothing -> f err -> pprPanic "unariseExpr - app2" (pprStgExpr panicStgPprOpts e $$ ppr err) @@ -390,12 +524,17 @@ unariseExpr _ (StgLit l) = return (StgLit l) unariseExpr rho (StgConApp dc n args ty_args) - | Just args' <- unariseMulti_maybe rho dc args ty_args - = return (mkTuple args') - - | otherwise - , let args' = unariseConArgs rho args - = return (StgConApp dc n args' (map stgArgType args')) + | isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc + = do + us <- getUniqueSupplyM + case unariseUbxSumOrTupleArgs rho us dc args ty_args of + (args', Just cast_wrapper) + -> return $ cast_wrapper (mkTuple args') + (args', Nothing) + -> return $ (mkTuple args') + | otherwise = + let args' = unariseConArgs rho args in + return $ (StgConApp dc n args' (map stgArgType args')) unariseExpr rho (StgOpApp op args ty) = return (StgOpApp op (unariseFunArgs rho args) ty) @@ -403,15 +542,19 @@ unariseExpr rho (StgOpApp op args ty) unariseExpr rho (StgCase scrut bndr alt_ty alts) -- tuple/sum binders in the scrutinee can always be eliminated | StgApp v [] <- scrut - , Just (MultiVal xs) <- lookupVarEnv rho v + , Just (MultiVal xs) <- lookupRho rho v = elimCase rho xs bndr alt_ty alts -- Handle strict lets for tuples and sums: -- case (# a,b #) of r -> rhs -- and analogously for sums | StgConApp dc _n args ty_args <- scrut - , Just args' <- unariseMulti_maybe rho dc args ty_args - = elimCase rho args' bndr alt_ty alts + , isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc + = do + us <- getUniqueSupplyM + case unariseUbxSumOrTupleArgs rho us dc args ty_args of + (args',Just wrapper) -> wrapper <$> elimCase rho args' bndr alt_ty alts + (args',Nothing) -> elimCase rho args' bndr alt_ty alts -- See (3) of Note [Rubbish literals] in GHC.Types.Literal | StgLit lit <- scrut @@ -436,17 +579,21 @@ unariseExpr rho (StgTick tick e) = StgTick tick <$> unariseExpr rho e -- Doesn't return void args. -unariseMulti_maybe :: UnariseEnv -> DataCon -> [InStgArg] -> [Type] -> Maybe [OutStgArg] -unariseMulti_maybe rho dc args ty_args +unariseUbxSumOrTupleArgs :: UnariseEnv -> UniqSupply -> DataCon -> [InStgArg] -> [Type] + -> ( [OutStgArg] -- Arguments representing the unboxed sum + , Maybe (StgExpr -> StgExpr)) -- Transformation to apply to the arguments, to bring them + -- into the right Rep +unariseUbxSumOrTupleArgs rho us dc args ty_args | isUnboxedTupleDataCon dc - = Just (unariseConArgs rho args) + = (unariseConArgs rho args, Nothing) | isUnboxedSumDataCon dc , let args1 = assert (isSingleton args) (unariseConArgs rho args) - = Just (mkUbxSum dc ty_args args1) + = let (args2, cast_wrapper) = mkUbxSum dc ty_args args1 us + in (args2, Just cast_wrapper) | otherwise - = Nothing + = panic "unariseUbxSumOrTupleArgs: Constructor not a unboxed sum or tuple" -- Doesn't return void args. unariseRubbish_maybe :: Literal -> Maybe [OutStgArg] @@ -473,15 +620,15 @@ elimCase rho args bndr (MultiValAlt _) [GenStgAlt{ alt_con = _ , alt_bndrs = bndrs , alt_rhs = rhs}] = do let rho1 = extendRho rho bndr (MultiVal args) - rho2 + (rho2, rhs') | isUnboxedTupleBndr bndr - = mapTupleIdBinders bndrs args rho1 + = (mapTupleIdBinders bndrs args rho1, rhs) | otherwise = assert (isUnboxedSumBndr bndr) $ - if null bndrs then rho1 - else mapSumIdBinders bndrs args rho1 + if null bndrs then (rho1, rhs) + else mapSumIdBinders bndrs args rhs rho1 - unariseExpr rho2 rhs + unariseExpr rho2 rhs' elimCase rho args bndr (MultiValAlt _) alts | isUnboxedSumBndr bndr @@ -576,12 +723,12 @@ unariseSumAlt rho args GenStgAlt{ alt_con = DataAlt sumCon , alt_bndrs = bs , alt_rhs = e } - = do let rho' = mapSumIdBinders bs args rho - lit_case = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon))) - GenStgAlt lit_case mempty <$> unariseExpr rho' e + = do let (rho',e') = mapSumIdBinders bs args e rho + lit_case = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon))) + GenStgAlt lit_case mempty <$> unariseExpr rho' e' unariseSumAlt _ scrt alt - = pprPanic "unariseSumAlt" (ppr scrt $$ pprPanicAlt alt) + = pprPanic "unariseSumAlt3" (ppr scrt $$ pprPanicAlt alt) -------------------------------------------------------------------------------- @@ -623,24 +770,80 @@ mapSumIdBinders -- only have one binder, so this list should be a singleton) -> [OutStgArg] -- Arguments that form the sum (NOT including the tag). -- Can't have void args. + -> InStgExpr -> UnariseEnv - -> UnariseEnv + -> (UnariseEnv, OutStgExpr) -mapSumIdBinders [id] args rho0 +mapSumIdBinders [id] args rhs rho0 = assert (not (any (isZeroBitTy . stgArgType) args)) $ let + -- Slots representing the whole sum arg_slots = map primRepSlot $ concatMap (typePrimRep . stgArgType) args + -- The slots representing the field of the sum we bind. id_slots = map primRepSlot $ typePrimRep (idType id) layout1 = layoutUbxSum arg_slots id_slots + + -- See Note [Casting slot arguments] + -- Arg id's which make up the field. + id_arg_exprs = [ args !! i | i <- layout1 ] + id_vars = [v | StgVarArg v <- id_arg_exprs] + + update_id_type v ty + | (typePrimRep $ idType v) == (typePrimRep ty) = v + | otherwise = setIdType v ty + + -- types for the field binders based on their rep + id_tys = map primRepToType $ typePrimRep (idType id) + -- Arg id's with the typ set to one matching the fields rep. + typed_id_args = zipWithEqual "typed_id_args" (\var t -> StgVarArg (update_id_type var t)) id_vars id_tys + -- We can shadow the original argument id here since the binder for the field will only be used + -- at one specific type in this branch. + (rhs_with_casts) = foldr castArgShadow rhs $ zip id_vars id_tys in + -- pprTrace "mapSumIdBinders" + -- (text "id_tys" <+> ppr id_tys $$ + -- text "id_args" <+> ppr id_arg_exprs $$ + -- text "rhs" <+> ppr rhs $$ + -- text "rhs_with_casts" <+> ppr rhs_with_casts + -- ) $ if isMultiValBndr id - then extendRho rho0 id (MultiVal [ args !! i | i <- layout1 ]) - else assert (layout1 `lengthIs` 1) - extendRho rho0 id (UnaryVal (args !! head layout1)) + then (extendRho rho0 id (MultiVal typed_id_args), rhs_with_casts) + else assert (typed_id_args `lengthIs` 1) + (extendRho rho0 id (UnaryVal (head typed_id_args)), rhs_with_casts) -mapSumIdBinders ids sum_args _ +mapSumIdBinders ids sum_args _rhs _ = pprPanic "mapSumIdBinders" (ppr ids $$ ppr sum_args) +-- Convert the argument to the given type, and wrap the case doing the +-- conversion around the given expression. +castArgShadow :: (Id,Type) -> StgExpr -> StgExpr +castArgShadow (arg, target_ty) (in_rhs) = + let ops = getCasts (typePrimRep1 $ idType arg) (typePrimRep1 target_ty) + in foldr (mkCast (StgVarArg arg) arg) (in_rhs) ops + +-- Convert the argument to the given type, and wrap the conversion +-- around the given expression. Use the given Id as a name for the +-- converted value. +castArgRename :: StgArg -> Id -> StgExpr -> StgExpr +castArgRename in_arg out_id in_rhs = + case ops of + [] -> in_rhs + op1:rest_ops -> + mkCast in_arg out_id op1 $ + foldr (mkCast (StgVarArg out_id) out_id) in_rhs rest_ops + -- pprTrace "castArgRename" (ppr (in_arg,out_id)) $ + where ops = getCasts (typePrimRep1 $ stgArgType in_arg) $ typePrimRep1 (idType out_id) + -- in foldr (mkCast in_arg out_id) (in_rhs) ops + +-- Variable to cast, (type to cast to, result_ty), rhs +mkCast :: StgArg -> OutId -> (PrimOp,Type) -> (StgExpr) -> (StgExpr) +mkCast arg_in out_id (cast_op,ty2) (in_rhs) = + let r2 = typePrimRep1 ty2 + scrut = StgOpApp (StgPrimOp cast_op) [arg_in] ty2 + alt = GenStgAlt { alt_con = DEFAULT, alt_bndrs = [], alt_rhs = in_rhs} + alt_ty = PrimAlt r2 + in (StgCase scrut (setIdType out_id ty2) alt_ty [alt]) + -- | Build a unboxed sum term from arguments of an alternative. -- -- Example, for (# x | #) :: (# (# #) | Int #) we call @@ -655,8 +858,11 @@ mkUbxSum :: DataCon -- Sum data con -> [Type] -- Type arguments of the sum data con -> [OutStgArg] -- Actual arguments of the alternative. - -> [OutStgArg] -- Final tuple arguments -mkUbxSum dc ty_args args0 + -> UniqSupply + -> ([OutStgArg] -- Final tuple arguments + ,(StgExpr->StgExpr) -- We might need to cast the args first + ) +mkUbxSum dc ty_args args0 us = let (_ : sum_slots) = ubxSumRepType (map typePrimRep ty_args) -- drop tag slot @@ -667,16 +873,50 @@ mkUbxSum dc ty_args args0 tag_arg = StgLitArg (LitNumber LitNumInt (fromIntegral tag)) arg_idxs = IM.fromList (zipEqual "mkUbxSum" layout' args0) - mkTupArgs :: Int -> [SlotTy] -> IM.IntMap StgArg -> [StgArg] - mkTupArgs _ [] _ - = [] - mkTupArgs arg_idx (slot : slots_left) arg_map - | Just stg_arg <- IM.lookup arg_idx arg_map - = stg_arg : mkTupArgs (arg_idx + 1) slots_left arg_map - | otherwise - = ubxSumRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map + ((_idx,_idx_map,_us,wrapper),slot_args) + = assert (length arg_idxs <= length sum_slots ) $ + mapAccumL mkTupArg (0,arg_idxs,us,id) sum_slots + + mkTupArg :: (Int, IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr) + -> SlotTy + -> ((Int,IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr), StgArg) + mkTupArg (arg_idx, arg_map, us, wrapper) slot + | Just stg_arg <- IM.lookup arg_idx arg_map + = case castArg us slot stg_arg of + Just (casted_arg,us',wrapper') -> + ( (arg_idx+1, arg_map, us', wrapper') + , casted_arg) + Nothing -> + ( (arg_idx+1, arg_map, us, wrapper) + , stg_arg) + | otherwise + = ( (arg_idx+1, arg_map, us, wrapper) + , ubxSumRubbishArg slot) + + castArg :: UniqSupply -> SlotTy -> StgArg -> Maybe (StgArg,UniqSupply,StgExpr -> StgExpr) + castArg us slot_ty arg + -- Cast the argument to the type of the slot if required + | slotPrimRep slot_ty /= typePrimRep1 (stgArgType arg) + = let (u1,us') = takeUniqFromSupply us + out_ty = primRepToType $ slotPrimRep slot_ty + out_name_fs + | (StgVarArg v_arg) <- arg + = getOccFS v_arg `appendFS` fsLit "_cst" + | otherwise = fsLit "cst_lit" + out_id = mkSysLocal out_name_fs u1 Many out_ty :: Id + casts = castArgRename arg out_id :: StgExpr -> StgExpr + in Just (arg,us',casts) + -- No need for casting + | otherwise = Nothing + + tup_args = tag_arg : slot_args in - tag_arg : mkTupArgs 0 sum_slots arg_idxs + -- pprTrace "mkUbxSum" ( + -- text "ty_args (slots)" <+> ppr ty_args $$ + -- text "args0" <+> ppr args0 $$ + -- text "wrapper" <+> + -- (ppr $ wrapper $ StgLit $ LitChar '_')) + (tup_args, wrapper) -- | Return a rubbish value for the given slot type. @@ -787,7 +1027,7 @@ unariseArgBinder is_con_arg rho x = -- | MultiVal a function argument. Never returns an empty list. unariseFunArg :: UnariseEnv -> StgArg -> [StgArg] unariseFunArg rho (StgVarArg x) = - case lookupVarEnv rho x of + case lookupRho rho x of Just (MultiVal []) -> [voidArg] -- NB: do not remove void args Just (MultiVal as) -> as Just (UnaryVal arg) -> [arg] @@ -809,7 +1049,7 @@ unariseFunArgBinder = unariseArgBinder False -- | MultiVal a DataCon argument. Returns an empty list when argument is void. unariseConArg :: UnariseEnv -> InStgArg -> [OutStgArg] unariseConArg rho (StgVarArg x) = - case lookupVarEnv rho x of + case lookupRho rho x of Just (UnaryVal arg) -> [arg] Just (MultiVal as) -> as -- 'as' can be empty Nothing ===================================== compiler/GHC/Types/RepType.hs ===================================== @@ -245,7 +245,8 @@ ubxSumRepType constrs0 in sumRep -layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag. +layoutUbxSum :: HasDebugCallStack + => SortedSlotTys -- Layout of sum. Does not include tag. -- We assume that they are in increasing order -> [SlotTy] -- Slot types of things we want to map to locations in the -- sum layout @@ -268,7 +269,8 @@ layoutUbxSum sum_slots0 arg_slots0 = | otherwise = findSlot arg (slot_idx + 1) slots useds findSlot _ _ [] _ - = pprPanic "findSlot" (text "Can't find slot" $$ ppr sum_slots0 $$ ppr arg_slots0) + = pprPanic "findSlot" (text "Can't find slot" $$ text "sum_slots:" <> ppr sum_slots0 + $$ text "arg_slots:" <> ppr arg_slots0 ) -------------------------------------------------------------------------------- ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -387,6 +387,7 @@ data SDocContext = SDC , sdocSuppressUniques :: !Bool , sdocSuppressModulePrefixes :: !Bool , sdocSuppressStgExts :: !Bool + , sdocSuppressStgReps :: !Bool , sdocErrorSpans :: !Bool , sdocStarIsType :: !Bool , sdocLinearTypes :: !Bool @@ -447,6 +448,7 @@ defaultSDocContext = SDC , sdocSuppressUniques = False , sdocSuppressModulePrefixes = False , sdocSuppressStgExts = False + , sdocSuppressStgReps = True , sdocErrorSpans = False , sdocStarIsType = False , sdocLinearTypes = False ===================================== compiler/ghc.cabal.in ===================================== @@ -168,6 +168,7 @@ Library GHC.Builtin.Names GHC.Builtin.Names.TH GHC.Builtin.PrimOps + GHC.Builtin.PrimOps.Casts GHC.Builtin.PrimOps.Ids GHC.Builtin.Types GHC.Builtin.Types.Literals ===================================== docs/users_guide/debugging.rst ===================================== @@ -946,6 +946,16 @@ parts that you are not interested in. Suppress the printing of core size stats per binding +.. ghc-flag:: -dsuppress-stg-reps + :shortdesc: Suppress rep annotations on STG args. + :type: dynamic + + :since: 9.6.1 + + default: enabled + + Disabling this will annoate certain stg arguments with their prim rep. + .. _checking-consistency: ===================================== testsuite/driver/testlib.py ===================================== @@ -1447,7 +1447,8 @@ def compile_cmp_asm(name: TestName, ext: str, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile only, extra args = ', extra_hc_opts) result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): @@ -1474,7 +1475,8 @@ def compile_grep_asm(name: TestName, is_substring: bool, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile and grep asm, extra args = ', extra_hc_opts) result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): @@ -1495,7 +1497,8 @@ def compile_grep_core(name: TestName, way: WayName, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile only, extra args = ', extra_hc_opts) result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): ===================================== testsuite/tests/unboxedsums/GenManyUbxSums.hs ===================================== @@ -0,0 +1,102 @@ +#!/usr/bin/env runghc +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnboxedSums #-} + +-- This little piece of code constructs a large set of functions +-- constructing and deconstructing unboxed tuples of various types. +module Main where + +import GHC.Exts +import System.IO + +inputs = ["Int", "Word"] +sizes = ["","8","16","32","64"] + +-- ["Addr#","Int#","Int8#","Int16#","Int32#","Int64#","Word#","Word8#","Word16#","Word32#","Word64#"] +types = "Addr#" : do + r <- inputs + s <- sizes + return $ r++s++"#" + +-- We eventually build two sums, one of type (# t1 | t2 #) and one of (# t1 | t3). +-- So we build all possible combinations of three types here. +combos = do + t1 <- types + t2 <- types + t3 <- types + return (t1,t2,t3) + +mkCon ty = case ty of + "Addr#" -> "Addr" + "Int#" -> "I#" + "Int8#" -> "I8#" + "Int16#" -> "I16#" + "Int32#" -> "I32#" + "Int64#" -> "I64#" + "Word#" -> "W#" + "Word8#" -> "W8#" + "Word16#" -> "W16#" + "Word32#" -> "W32#" + "Word64#" -> "W64#" + +-- Construct a function like the one below: +-- {-# NOINLINE fun0 #-} +-- fun0 :: (# Addr# | Addr# #) -> (# Addr# | Addr# #) +-- fun0 x = case x of +-- (# x1 | #) -> (# x1 | #) :: (# Addr# | Addr# #) +mkFun n (t1,t2,t3) = + "{-# NOINLINE fun" ++ show n ++ " #-}\n" ++ + "fun" ++ show n ++ " :: (# " ++ t1 ++" | " ++ t2 ++ " #) -> (# " ++ t1 ++" | " ++ t3 ++ " #)\n" ++ + "fun" ++ show n ++ " x = case x of\n" ++ + " (# x1 | #) -> (# x1 | #) :: (# " ++ t1 ++ " | " ++ t3 ++ " #)" + +-- Generate functions for all the tuple combinations. +mkFuns _ [] = "" +mkFuns n (combo:combos) = + mkFun n combo ++ "\n" ++ mkFuns (n+1) combos + +-- generate a test that will put a value into a unboxed sum and then retrieve it later on. +-- It generates code like the one below: +-- test0 = +-- let in_val = 0 +-- out_val = case in_val of I# x -> case fun0 (# x | #) of (# y | #) -> I# y +-- in in_val == out_val +mkTest n (t1,_,_)= + "test" ++ show n ++ " =\n" ++ + " let in_val = (maxBound)\n" ++ + " out_val = case in_val of " ++ mkCon t1 ++ " x -> case fun" ++ show n ++ " (# x | #) of (# y | #) -> " ++ mkCon t1 ++ " y\n" ++ + " in in_val == out_val" + +-- Test all the tuples +mkTests n [] = "" +mkTests n (combo:combos) = + mkTest n combo ++ "\n" ++ mkTests (n+1) combos + + +header = + "{-# LANGUAGE MagicHash #-}\n\ + \{-# LANGUAGE UnboxedTuples #-}\n\ + \{-# LANGUAGE UnboxedSums #-}\n\ + \module Main where\n\ + \import GHC.Exts\n\ + \import GHC.Word\n\ + \import GHC.Int\n\ + \import ManyUbxSums_Addr\n" +main = do + out <- openFile "ManyUbxSums.hs" WriteMode + hPutStrLn out header + + let combo:_ = combos + -- putStrLn $ mkFun 1 combo + hPutStrLn out $ mkFuns 0 combos + + hPutStrLn out $ mkTests 0 combos + hPutStrLn out "main = do" + + -- Actually invoke all the tests + let runTest n = + hPutStrLn out $ " putStrLn $ \"test" ++ show n ++ " \" ++ (show test" ++ show n ++ ")" + mapM runTest [0 .. length combos - 1] + + hClose out ===================================== testsuite/tests/unboxedsums/ManyUbxSums.stdout ===================================== @@ -0,0 +1,1331 @@ +test0 True +test1 True +test2 True +test3 True +test4 True +test5 True +test6 True +test7 True +test8 True +test9 True +test10 True +test11 True +test12 True +test13 True +test14 True +test15 True +test16 True +test17 True +test18 True +test19 True +test20 True +test21 True +test22 True +test23 True +test24 True +test25 True +test26 True +test27 True +test28 True +test29 True +test30 True +test31 True +test32 True +test33 True +test34 True +test35 True +test36 True +test37 True +test38 True +test39 True +test40 True +test41 True +test42 True +test43 True +test44 True +test45 True +test46 True +test47 True +test48 True +test49 True +test50 True +test51 True +test52 True +test53 True +test54 True +test55 True +test56 True +test57 True +test58 True +test59 True +test60 True +test61 True +test62 True +test63 True +test64 True +test65 True +test66 True +test67 True +test68 True +test69 True +test70 True +test71 True +test72 True +test73 True +test74 True +test75 True +test76 True +test77 True +test78 True +test79 True +test80 True +test81 True +test82 True +test83 True +test84 True +test85 True +test86 True +test87 True +test88 True +test89 True +test90 True +test91 True +test92 True +test93 True +test94 True +test95 True +test96 True +test97 True +test98 True +test99 True +test100 True +test101 True +test102 True +test103 True +test104 True +test105 True +test106 True +test107 True +test108 True +test109 True +test110 True +test111 True +test112 True +test113 True +test114 True +test115 True +test116 True +test117 True +test118 True +test119 True +test120 True +test121 True +test122 True +test123 True +test124 True +test125 True +test126 True +test127 True +test128 True +test129 True +test130 True +test131 True +test132 True +test133 True +test134 True +test135 True +test136 True +test137 True +test138 True +test139 True +test140 True +test141 True +test142 True +test143 True +test144 True +test145 True +test146 True +test147 True +test148 True +test149 True +test150 True +test151 True +test152 True +test153 True +test154 True +test155 True +test156 True +test157 True +test158 True +test159 True +test160 True +test161 True +test162 True +test163 True +test164 True +test165 True +test166 True +test167 True +test168 True +test169 True +test170 True +test171 True +test172 True +test173 True +test174 True +test175 True +test176 True +test177 True +test178 True +test179 True +test180 True +test181 True +test182 True +test183 True +test184 True +test185 True +test186 True +test187 True +test188 True +test189 True +test190 True +test191 True +test192 True +test193 True +test194 True +test195 True +test196 True +test197 True +test198 True +test199 True +test200 True +test201 True +test202 True +test203 True +test204 True +test205 True +test206 True +test207 True +test208 True +test209 True +test210 True +test211 True +test212 True +test213 True +test214 True +test215 True +test216 True +test217 True +test218 True +test219 True +test220 True +test221 True +test222 True +test223 True +test224 True +test225 True +test226 True +test227 True +test228 True +test229 True +test230 True +test231 True +test232 True +test233 True +test234 True +test235 True +test236 True +test237 True +test238 True +test239 True +test240 True +test241 True +test242 True +test243 True +test244 True +test245 True +test246 True +test247 True +test248 True +test249 True +test250 True +test251 True +test252 True +test253 True +test254 True +test255 True +test256 True +test257 True +test258 True +test259 True +test260 True +test261 True +test262 True +test263 True +test264 True +test265 True +test266 True +test267 True +test268 True +test269 True +test270 True +test271 True +test272 True +test273 True +test274 True +test275 True +test276 True +test277 True +test278 True +test279 True +test280 True +test281 True +test282 True +test283 True +test284 True +test285 True +test286 True +test287 True +test288 True +test289 True +test290 True +test291 True +test292 True +test293 True +test294 True +test295 True +test296 True +test297 True +test298 True +test299 True +test300 True +test301 True +test302 True +test303 True +test304 True +test305 True +test306 True +test307 True +test308 True +test309 True +test310 True +test311 True +test312 True +test313 True +test314 True +test315 True +test316 True +test317 True +test318 True +test319 True +test320 True +test321 True +test322 True +test323 True +test324 True +test325 True +test326 True +test327 True +test328 True +test329 True +test330 True +test331 True +test332 True +test333 True +test334 True +test335 True +test336 True +test337 True +test338 True +test339 True +test340 True +test341 True +test342 True +test343 True +test344 True +test345 True +test346 True +test347 True +test348 True +test349 True +test350 True +test351 True +test352 True +test353 True +test354 True +test355 True +test356 True +test357 True +test358 True +test359 True +test360 True +test361 True +test362 True +test363 True +test364 True +test365 True +test366 True +test367 True +test368 True +test369 True +test370 True +test371 True +test372 True +test373 True +test374 True +test375 True +test376 True +test377 True +test378 True +test379 True +test380 True +test381 True +test382 True +test383 True +test384 True +test385 True +test386 True +test387 True +test388 True +test389 True +test390 True +test391 True +test392 True +test393 True +test394 True +test395 True +test396 True +test397 True +test398 True +test399 True +test400 True +test401 True +test402 True +test403 True +test404 True +test405 True +test406 True +test407 True +test408 True +test409 True +test410 True +test411 True +test412 True +test413 True +test414 True +test415 True +test416 True +test417 True +test418 True +test419 True +test420 True +test421 True +test422 True +test423 True +test424 True +test425 True +test426 True +test427 True +test428 True +test429 True +test430 True +test431 True +test432 True +test433 True +test434 True +test435 True +test436 True +test437 True +test438 True +test439 True +test440 True +test441 True +test442 True +test443 True +test444 True +test445 True +test446 True +test447 True +test448 True +test449 True +test450 True +test451 True +test452 True +test453 True +test454 True +test455 True +test456 True +test457 True +test458 True +test459 True +test460 True +test461 True +test462 True +test463 True +test464 True +test465 True +test466 True +test467 True +test468 True +test469 True +test470 True +test471 True +test472 True +test473 True +test474 True +test475 True +test476 True +test477 True +test478 True +test479 True +test480 True +test481 True +test482 True +test483 True +test484 True +test485 True +test486 True +test487 True +test488 True +test489 True +test490 True +test491 True +test492 True +test493 True +test494 True +test495 True +test496 True +test497 True +test498 True +test499 True +test500 True +test501 True +test502 True +test503 True +test504 True +test505 True +test506 True +test507 True +test508 True +test509 True +test510 True +test511 True +test512 True +test513 True +test514 True +test515 True +test516 True +test517 True +test518 True +test519 True +test520 True +test521 True +test522 True +test523 True +test524 True +test525 True +test526 True +test527 True +test528 True +test529 True +test530 True +test531 True +test532 True +test533 True +test534 True +test535 True +test536 True +test537 True +test538 True +test539 True +test540 True +test541 True +test542 True +test543 True +test544 True +test545 True +test546 True +test547 True +test548 True +test549 True +test550 True +test551 True +test552 True +test553 True +test554 True +test555 True +test556 True +test557 True +test558 True +test559 True +test560 True +test561 True +test562 True +test563 True +test564 True +test565 True +test566 True +test567 True +test568 True +test569 True +test570 True +test571 True +test572 True +test573 True +test574 True +test575 True +test576 True +test577 True +test578 True +test579 True +test580 True +test581 True +test582 True +test583 True +test584 True +test585 True +test586 True +test587 True +test588 True +test589 True +test590 True +test591 True +test592 True +test593 True +test594 True +test595 True +test596 True +test597 True +test598 True +test599 True +test600 True +test601 True +test602 True +test603 True +test604 True +test605 True +test606 True +test607 True +test608 True +test609 True +test610 True +test611 True +test612 True +test613 True +test614 True +test615 True +test616 True +test617 True +test618 True +test619 True +test620 True +test621 True +test622 True +test623 True +test624 True +test625 True +test626 True +test627 True +test628 True +test629 True +test630 True +test631 True +test632 True +test633 True +test634 True +test635 True +test636 True +test637 True +test638 True +test639 True +test640 True +test641 True +test642 True +test643 True +test644 True +test645 True +test646 True +test647 True +test648 True +test649 True +test650 True +test651 True +test652 True +test653 True +test654 True +test655 True +test656 True +test657 True +test658 True +test659 True +test660 True +test661 True +test662 True +test663 True +test664 True +test665 True +test666 True +test667 True +test668 True +test669 True +test670 True +test671 True +test672 True +test673 True +test674 True +test675 True +test676 True +test677 True +test678 True +test679 True +test680 True +test681 True +test682 True +test683 True +test684 True +test685 True +test686 True +test687 True +test688 True +test689 True +test690 True +test691 True +test692 True +test693 True +test694 True +test695 True +test696 True +test697 True +test698 True +test699 True +test700 True +test701 True +test702 True +test703 True +test704 True +test705 True +test706 True +test707 True +test708 True +test709 True +test710 True +test711 True +test712 True +test713 True +test714 True +test715 True +test716 True +test717 True +test718 True +test719 True +test720 True +test721 True +test722 True +test723 True +test724 True +test725 True +test726 True +test727 True +test728 True +test729 True +test730 True +test731 True +test732 True +test733 True +test734 True +test735 True +test736 True +test737 True +test738 True +test739 True +test740 True +test741 True +test742 True +test743 True +test744 True +test745 True +test746 True +test747 True +test748 True +test749 True +test750 True +test751 True +test752 True +test753 True +test754 True +test755 True +test756 True +test757 True +test758 True +test759 True +test760 True +test761 True +test762 True +test763 True +test764 True +test765 True +test766 True +test767 True +test768 True +test769 True +test770 True +test771 True +test772 True +test773 True +test774 True +test775 True +test776 True +test777 True +test778 True +test779 True +test780 True +test781 True +test782 True +test783 True +test784 True +test785 True +test786 True +test787 True +test788 True +test789 True +test790 True +test791 True +test792 True +test793 True +test794 True +test795 True +test796 True +test797 True +test798 True +test799 True +test800 True +test801 True +test802 True +test803 True +test804 True +test805 True +test806 True +test807 True +test808 True +test809 True +test810 True +test811 True +test812 True +test813 True +test814 True +test815 True +test816 True +test817 True +test818 True +test819 True +test820 True +test821 True +test822 True +test823 True +test824 True +test825 True +test826 True +test827 True +test828 True +test829 True +test830 True +test831 True +test832 True +test833 True +test834 True +test835 True +test836 True +test837 True +test838 True +test839 True +test840 True +test841 True +test842 True +test843 True +test844 True +test845 True +test846 True +test847 True +test848 True +test849 True +test850 True +test851 True +test852 True +test853 True +test854 True +test855 True +test856 True +test857 True +test858 True +test859 True +test860 True +test861 True +test862 True +test863 True +test864 True +test865 True +test866 True +test867 True +test868 True +test869 True +test870 True +test871 True +test872 True +test873 True +test874 True +test875 True +test876 True +test877 True +test878 True +test879 True +test880 True +test881 True +test882 True +test883 True +test884 True +test885 True +test886 True +test887 True +test888 True +test889 True +test890 True +test891 True +test892 True +test893 True +test894 True +test895 True +test896 True +test897 True +test898 True +test899 True +test900 True +test901 True +test902 True +test903 True +test904 True +test905 True +test906 True +test907 True +test908 True +test909 True +test910 True +test911 True +test912 True +test913 True +test914 True +test915 True +test916 True +test917 True +test918 True +test919 True +test920 True +test921 True +test922 True +test923 True +test924 True +test925 True +test926 True +test927 True +test928 True +test929 True +test930 True +test931 True +test932 True +test933 True +test934 True +test935 True +test936 True +test937 True +test938 True +test939 True +test940 True +test941 True +test942 True +test943 True +test944 True +test945 True +test946 True +test947 True +test948 True +test949 True +test950 True +test951 True +test952 True +test953 True +test954 True +test955 True +test956 True +test957 True +test958 True +test959 True +test960 True +test961 True +test962 True +test963 True +test964 True +test965 True +test966 True +test967 True +test968 True +test969 True +test970 True +test971 True +test972 True +test973 True +test974 True +test975 True +test976 True +test977 True +test978 True +test979 True +test980 True +test981 True +test982 True +test983 True +test984 True +test985 True +test986 True +test987 True +test988 True +test989 True +test990 True +test991 True +test992 True +test993 True +test994 True +test995 True +test996 True +test997 True +test998 True +test999 True +test1000 True +test1001 True +test1002 True +test1003 True +test1004 True +test1005 True +test1006 True +test1007 True +test1008 True +test1009 True +test1010 True +test1011 True +test1012 True +test1013 True +test1014 True +test1015 True +test1016 True +test1017 True +test1018 True +test1019 True +test1020 True +test1021 True +test1022 True +test1023 True +test1024 True +test1025 True +test1026 True +test1027 True +test1028 True +test1029 True +test1030 True +test1031 True +test1032 True +test1033 True +test1034 True +test1035 True +test1036 True +test1037 True +test1038 True +test1039 True +test1040 True +test1041 True +test1042 True +test1043 True +test1044 True +test1045 True +test1046 True +test1047 True +test1048 True +test1049 True +test1050 True +test1051 True +test1052 True +test1053 True +test1054 True +test1055 True +test1056 True +test1057 True +test1058 True +test1059 True +test1060 True +test1061 True +test1062 True +test1063 True +test1064 True +test1065 True +test1066 True +test1067 True +test1068 True +test1069 True +test1070 True +test1071 True +test1072 True +test1073 True +test1074 True +test1075 True +test1076 True +test1077 True +test1078 True +test1079 True +test1080 True +test1081 True +test1082 True +test1083 True +test1084 True +test1085 True +test1086 True +test1087 True +test1088 True +test1089 True +test1090 True +test1091 True +test1092 True +test1093 True +test1094 True +test1095 True +test1096 True +test1097 True +test1098 True +test1099 True +test1100 True +test1101 True +test1102 True +test1103 True +test1104 True +test1105 True +test1106 True +test1107 True +test1108 True +test1109 True +test1110 True +test1111 True +test1112 True +test1113 True +test1114 True +test1115 True +test1116 True +test1117 True +test1118 True +test1119 True +test1120 True +test1121 True +test1122 True +test1123 True +test1124 True +test1125 True +test1126 True +test1127 True +test1128 True +test1129 True +test1130 True +test1131 True +test1132 True +test1133 True +test1134 True +test1135 True +test1136 True +test1137 True +test1138 True +test1139 True +test1140 True +test1141 True +test1142 True +test1143 True +test1144 True +test1145 True +test1146 True +test1147 True +test1148 True +test1149 True +test1150 True +test1151 True +test1152 True +test1153 True +test1154 True +test1155 True +test1156 True +test1157 True +test1158 True +test1159 True +test1160 True +test1161 True +test1162 True +test1163 True +test1164 True +test1165 True +test1166 True +test1167 True +test1168 True +test1169 True +test1170 True +test1171 True +test1172 True +test1173 True +test1174 True +test1175 True +test1176 True +test1177 True +test1178 True +test1179 True +test1180 True +test1181 True +test1182 True +test1183 True +test1184 True +test1185 True +test1186 True +test1187 True +test1188 True +test1189 True +test1190 True +test1191 True +test1192 True +test1193 True +test1194 True +test1195 True +test1196 True +test1197 True +test1198 True +test1199 True +test1200 True +test1201 True +test1202 True +test1203 True +test1204 True +test1205 True +test1206 True +test1207 True +test1208 True +test1209 True +test1210 True +test1211 True +test1212 True +test1213 True +test1214 True +test1215 True +test1216 True +test1217 True +test1218 True +test1219 True +test1220 True +test1221 True +test1222 True +test1223 True +test1224 True +test1225 True +test1226 True +test1227 True +test1228 True +test1229 True +test1230 True +test1231 True +test1232 True +test1233 True +test1234 True +test1235 True +test1236 True +test1237 True +test1238 True +test1239 True +test1240 True +test1241 True +test1242 True +test1243 True +test1244 True +test1245 True +test1246 True +test1247 True +test1248 True +test1249 True +test1250 True +test1251 True +test1252 True +test1253 True +test1254 True +test1255 True +test1256 True +test1257 True +test1258 True +test1259 True +test1260 True +test1261 True +test1262 True +test1263 True +test1264 True +test1265 True +test1266 True +test1267 True +test1268 True +test1269 True +test1270 True +test1271 True +test1272 True +test1273 True +test1274 True +test1275 True +test1276 True +test1277 True +test1278 True +test1279 True +test1280 True +test1281 True +test1282 True +test1283 True +test1284 True +test1285 True +test1286 True +test1287 True +test1288 True +test1289 True +test1290 True +test1291 True +test1292 True +test1293 True +test1294 True +test1295 True +test1296 True +test1297 True +test1298 True +test1299 True +test1300 True +test1301 True +test1302 True +test1303 True +test1304 True +test1305 True +test1306 True +test1307 True +test1308 True +test1309 True +test1310 True +test1311 True +test1312 True +test1313 True +test1314 True +test1315 True +test1316 True +test1317 True +test1318 True +test1319 True +test1320 True +test1321 True +test1322 True +test1323 True +test1324 True +test1325 True +test1326 True +test1327 True +test1328 True +test1329 True +test1330 True ===================================== testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs ===================================== @@ -0,0 +1,26 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnboxedSums #-} + +{-# OPTIONS_GHC -Wno-missing-methods #-} + +module ManyUbxSums_Addr where + +import GHC.Exts +-- import GHC.Word +-- import GHC.Int +--import GHC.Utils.Misc + +data Addr = Addr Addr# + +instance Eq Addr where + (Addr x) == (Addr y) = case (eqAddr# x y) of + 1# -> True + 0# -> False + +instance Num Addr where + fromInteger x = case fromIntegral x of I# x1 -> Addr (int2Addr# x1) + +instance Bounded Addr where + maxBound = fromIntegral (maxBound :: Word) + minBound = 0 \ No newline at end of file ===================================== testsuite/tests/unboxedsums/T22208.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedSums #-} +{-# LANGUAGE UnboxedTuples #-} +module M where + +import GHC.Base + +-- Reproducer from #22208 +foo :: (# Float# | Double# #) -> (# Float# | Float #) +foo (# x | #) = (# x | #) +bar :: (# Word# | Int64# #) -> (# Double# | Word# #) +bar (# y | #) = let x = y in (# | x #) +baz :: (# Word# | Word64# #) -> (# Word# | (##) #) +baz (# x | #) = (# x | #) + +foo1 :: (# Float# | Double# #) -> (# Float# | Float #) +foo1 (# x | #) = (# x | #) +bar1 :: (# Word# | Int64# #) -> (# Double# | Word# #) +bar1 (# y | #) = let x = y in (# | x #) +baz1 :: (# Word# | Word64# #) -> (# Word# | (##) #) +baz1 (# x | #) = (# x | #) + +-- i8 value from w64 slot +baz2 :: (# Int8# | Word64# #) -> (# Int8# | (##) #) +baz2 (# x | #) = (# x | #) + +-- w8 value from w64 slot +baz3 :: (# Word8# | Word64# #) -> (# Word8# | (##) #) +baz3 (# x | #) = (# x | #) + +-- w8 from w slot +baz4 :: (# Word8# | Word# #) -> (# Word8# | (##) #) +baz4 (# x | #) = (# x | #) + +-- w from w slot +baz5 :: (# Word8# | Word# #) -> (# Word# | (##) #) +baz5 (# | x #) = (# x | #) + +-- addr from w slot +baz6 :: (# Addr# | Word# #) -> (# Addr# | (##) #) +baz6 (# x | #) = (# x | #) \ No newline at end of file ===================================== testsuite/tests/unboxedsums/all.T ===================================== @@ -35,3 +35,12 @@ test('T20858b', [extra_files(['T20858.hs']) ,extra_hc_opts("-fprint-explicit-runtime-reps -fprint-explicit-kinds")] , ghci_script, ['T20858b.script']) test('T20859', normal, compile, ['']) +test('T22208', normal, compile, ['-dstg-lint -dcmm-lint']) +test('ManyUbxSums', + [ pre_cmd('./GenManyUbxSums.hs'), + extra_files(['GenManyUbxSums.hs', 'ManyUbxSums_Addr.hs']), + ], + multi_compile_and_run, + ['ManyUbxSums', + [('ManyUbxSums_Addr.hs','')] + , '-v0 -dstg-lint -dcmm-lint']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4feb4966c5f46709554a5f94eadf75fae3004077 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4feb4966c5f46709554a5f94eadf75fae3004077 You're receiving 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 Oct 13 17:09:40 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 13 Oct 2022 13:09:40 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/llvm-ways Message-ID: <63484654da069_2c5d73513d85803e9@gitlab.mail> Matthew Pickering pushed new branch wip/llvm-ways at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/llvm-ways You're receiving 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 Oct 13 17:10:29 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 13 Oct 2022 13:10:29 -0400 Subject: [Git][ghc/ghc][wip/llvm-ways] testsuite: Fix typo when setting llvm_ways Message-ID: <63484685f1f1e_2c5d735145058245f@gitlab.mail> Matthew Pickering pushed to branch wip/llvm-ways at Glasgow Haskell Compiler / GHC Commits: 31bbe13e by Matthew Pickering at 2022-10-13T18:10:08+01:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - 1 changed file: - testsuite/config/ghc Changes: ===================================== testsuite/config/ghc ===================================== @@ -176,8 +176,7 @@ opt_ways = [x[0] for x in config.way_flags.items() if '-O' in x[1]] llvm_ways = [x[0] for x in config.way_flags.items() - if '-fflvm' in x[1]] - + if '-fllvm' in x[1]] def get_compiler_info(): if config.unregisterised: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31bbe13e8d287f4215acd08979142ec84be9fd5a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/31bbe13e8d287f4215acd08979142ec84be9fd5a You're receiving 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 Oct 13 20:21:08 2022 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Thu, 13 Oct 2022 16:21:08 -0400 Subject: [Git][ghc/ghc][wip/az/T21355-exactprint-update] 6 commits: Add a perf test for the generics code pattern from #21839. Message-ID: <63487334432d3_2c5d73515046275dc@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T21355-exactprint-update at Glasgow Haskell Compiler / GHC Commits: ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 5baa2b4c by Alan Zimmerman at 2022-10-13T21:19:59+01:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 30 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/phases.rst - rts/linker/Elf.c - rts/linker/ElfTypes.h - + rts/linker/InitFini.c - + rts/linker/InitFini.h - rts/linker/PEi386.c - rts/linker/PEi386Types.h - rts/rts.cabal.in - testsuite/tests/gadt/T14719.stderr - testsuite/tests/ghc-api/exactprint/AddDecl2.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.hs - testsuite/tests/indexed-types/should_fail/T14033.stderr - testsuite/tests/indexed-types/should_fail/T2334A.stderr - testsuite/tests/linear/should_fail/LinearGADTNewtype.stderr - testsuite/tests/parser/should_fail/readFail008.stderr - + testsuite/tests/perf/compiler/T21839c.hs - + testsuite/tests/perf/compiler/T21839c.stdout - testsuite/tests/perf/compiler/all.T - + testsuite/tests/perf/should_run/T21839r.hs - + testsuite/tests/perf/should_run/T21839r.stdout - testsuite/tests/perf/should_run/all.T - testsuite/tests/polykinds/T11459.stderr - testsuite/tests/typecheck/should_fail/T15523.stderr - testsuite/tests/typecheck/should_fail/T15796.stderr - testsuite/tests/typecheck/should_fail/T17955.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34adbd93b71d70f91f74e287977230a463ef61ce...5baa2b4c8d2c2fde3c5e2693e3e7711d7e94d480 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34adbd93b71d70f91f74e287977230a463ef61ce...5baa2b4c8d2c2fde3c5e2693e3e7711d7e94d480 You're receiving 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 Oct 13 23:04:59 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Oct 2022 19:04:59 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Add a perf test for the generics code pattern from #21839. Message-ID: <6348999bb96b4_2c5d735142863979b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 6538d7aa by Pierre Le Marre at 2022-10-13T19:04:46-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - 6f86bcf8 by Bodigrim at 2022-10-13T19:04:50-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - 30 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/phases.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/linker/Elf.c - rts/linker/ElfTypes.h - + rts/linker/InitFini.c - + rts/linker/InitFini.h - rts/linker/PEi386.c - rts/linker/PEi386Types.h - rts/rts.cabal.in - testsuite/tests/gadt/T14719.stderr - testsuite/tests/indexed-types/should_fail/T14033.stderr - testsuite/tests/indexed-types/should_fail/T2334A.stderr - testsuite/tests/linear/should_fail/LinearGADTNewtype.stderr - testsuite/tests/parser/should_fail/readFail008.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/db525d07c1f73044f11cf343c5122f2efe87ba7b...6f86bcf81708c54ed8dd98212b290c5cc8510eb3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/db525d07c1f73044f11cf343c5122f2efe87ba7b...6f86bcf81708c54ed8dd98212b290c5cc8510eb3 You're receiving 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 Oct 14 01:01:53 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Thu, 13 Oct 2022 21:01:53 -0400 Subject: [Git][ghc/ghc][wip/andreask/stgLintFix] 46 commits: Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Message-ID: <6348b50141a28_2c5d7351504658196@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stgLintFix at Glasgow Haskell Compiler / GHC Commits: 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 7ffe7787 by Andreas Klebinger at 2022-10-14T02:59:10+02:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Pipeline/Types.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Backpack.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7be73fc761501317244999e262b08616ed03955...7ffe77879ac77a6be61b9efbc8d739b70f08a0c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7be73fc761501317244999e262b08616ed03955...7ffe77879ac77a6be61b9efbc8d739b70f08a0c6 You're receiving 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 Oct 14 04:35:35 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 00:35:35 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <6348e7178d933_2c5d73513c468436c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9e491f7b by Pierre Le Marre at 2022-10-14T00:35:11-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - bb13eed5 by Bodigrim at 2022-10-14T00:35:14-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - 13 changed files: - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh Changes: ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -140,6 +140,11 @@ Runtime system - Updated to `Unicode 15.0.0 `_. +- Add standard Unicode case predicates :base-ref:`Data.Char.isUpperCase` and + :base-ref:`Data.Char.isLowerCase`. These predicates use the standard Unicode + case properties and are more intuitive than :base-ref:`Data.Char.isUpper` and + :base-ref:`Data.Char.isLower`. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/Data/Char.hs ===================================== @@ -6,7 +6,7 @@ -- Module : Data.Char -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : stable -- Portability : portable @@ -24,7 +24,7 @@ module Data.Char -- punctuation, symbols, separators (including spaces) and others -- (including control characters). , isControl, isSpace - , isLower, isUpper, isAlpha, isAlphaNum, isPrint + , isLower, isLowerCase, isUpper, isUpperCase, isAlpha, isAlphaNum, isPrint , isDigit, isOctDigit, isHexDigit , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator ===================================== libraries/base/Data/OldList.hs ===================================== @@ -1249,6 +1249,7 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs at . +-- -- This function is productive on infinite inputs: -- -- >>> take 6 $ map (take 3) $ permutations ['a'..] @@ -1259,21 +1260,25 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] -- -permutations :: [a] -> [[a]] +permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation. -- Related discussions: -- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html -- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html -permutations xs0 = xs0 : perms xs0 [] +permutations xs0 = xs0 : perms xs0 [] where + perms :: forall a. [a] -> [a] -> [[a]] perms [] _ = [] perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) - where interleave xs r = let (_,zs) = interleave' id xs r in zs - interleave' _ [] r = (ts, r) - interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r - in (y:us, f (t:y:us) : zs) - + where + interleave :: [a] -> [[a]] -> [[a]] + interleave xs r = let (_,zs) = interleave' id xs r in zs + + interleave' :: ([a] -> b) -> [a] -> [b] -> ([a], [b]) + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) ------------------------------------------------------------------------------ -- Quick Sort algorithm taken from HBC's QSort library. ===================================== libraries/base/GHC/Unicode.hs ===================================== @@ -24,8 +24,8 @@ module GHC.Unicode ( GeneralCategory (..), generalCategory, isAscii, isLatin1, isControl, isAsciiUpper, isAsciiLower, - isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, + isPrint, isSpace, isUpper, isUpperCase, + isLower, isLowerCase, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, isPunctuation, isSymbol, toUpper, toLower, toTitle @@ -37,6 +37,7 @@ import GHC.Enum ( Enum (..), Bounded (..) ) import GHC.Ix ( Ix (..) ) import GHC.Num import GHC.Unicode.Internal.Version +import qualified GHC.Unicode.Internal.Char.DerivedCoreProperties as DCP import qualified GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory as GC import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping as C import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping as C @@ -236,18 +237,68 @@ isSpace c -- | Selects upper-case or title-case alphabetic Unicode characters (letters). -- Title case is used by a small number of letter ligatures like the -- single-character form of /Lj/. +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'UppercaseLetter' or 'TitlecaseLetter'. +-- +-- See 'isUpperCase' for a more intuitive predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). isUpper :: Char -> Bool isUpper c = case generalCategory c of UppercaseLetter -> True TitlecaseLetter -> True _ -> False +-- | Selects upper-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Uppercase@, which include letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). +-- +-- See 'isUpper' for the legacy predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). +-- +-- @since 4.18.0.0 +{-# INLINE isUpperCase #-} +isUpperCase :: Char -> Bool +isUpperCase = DCP.isUppercase + -- | Selects lower-case alphabetic Unicode characters (letters). +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'LowercaseLetter'. +-- +-- See 'isLowerCase' for a more intuitive predicate. isLower :: Char -> Bool isLower c = case generalCategory c of LowercaseLetter -> True _ -> False +-- | Selects lower-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Lowercase@, which includes letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). +-- +-- See 'isLower' for the legacy predicate. +-- +-- @since 4.18.0.0 +{-# INLINE isLowerCase #-} +isLowerCase :: Char -> Bool +isLowerCase = DCP.isLowercase + -- | Selects alphabetic Unicode characters (lower-case, upper-case and -- title-case letters, plus letters of caseless scripts and modifiers letters). -- This function is equivalent to 'Data.Char.isLetter'. ===================================== libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs ===================================== @@ -0,0 +1,35 @@ +-- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell, +-- with data from: https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt. + +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Unicode.Internal.Char.DerivedCoreProperties +-- Copyright : (c) 2020 Composewell Technologies and Contributors +-- License : BSD-3-Clause +-- Maintainer : streamly at composewell.com +-- Stability : internal +----------------------------------------------------------------------------- + +module GHC.Unicode.Internal.Char.DerivedCoreProperties +(isUppercase , isLowercase) +where + +import GHC.Base (Bool, Char, Ord(..), (&&), ord) +import GHC.Unicode.Internal.Bits (lookupBit64) + +{-# INLINE isUppercase #-} +isUppercase :: Char -> Bool +isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\2\65\1\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"# + +{-# INLINE isLowercase #-} +isLowercase :: Char -> Bool +isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\5\170\2\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"# + ===================================== libraries/base/base.cabal ===================================== @@ -352,6 +352,7 @@ Library GHC.Event.Unique -- GHC.IOPort -- TODO: hide again after debug GHC.Unicode.Internal.Bits + GHC.Unicode.Internal.Char.DerivedCoreProperties GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping ===================================== libraries/base/changelog.md ===================================== @@ -30,6 +30,10 @@ for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). + * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to + `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode + case properties and are more intuitive than `isUpper` and `isLower`. See + [CLC proposal #90](https://github.com/haskell/core-libraries-committee/issues/90). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tests/unicode001.hs ===================================== @@ -16,17 +16,45 @@ main = do f True = "X " f False = " " -strs = ["upper","lower","alpha","alnum","digit","print","space","cntrl"] +strs = + [ "upper", + "uppr2", + "lower", + "lowr2", + "alpha", + "alnum", + "digit", + "print", + "space", + "cntrl" ] -functions = [isUpper,isLower,isAlpha,isAlphaNum,isDigit,isPrint,isSpace,isControl] +functions = + [ isUpper, + isUpperCase, + isLower, + isLowerCase, + isAlpha, + isAlphaNum, + isDigit, + isPrint, + isSpace, + isControl ] chars = [backspace,tab,space,zero,lower_a,upper_a,delete, right_pointing_double_angle_quotation_mark, + latin_capital_letter_l_with_small_letter_j, + latin_small_letter_i_with_caron, + combining_acute_accent, greek_capital_letter_alpha, bengali_digit_zero, en_space, + roman_numeral_one, + small_roman_numeral_one, + circled_latin_capital_letter_a, + circled_latin_small_letter_a, gothic_letter_ahsa, - monospaced_digit_zero + monospaced_digit_zero, + squared_latin_capital_letter_a ] backspace = '\x08' @@ -37,10 +65,16 @@ lower_a = 'a' upper_a = 'A' delete = '\x7f' right_pointing_double_angle_quotation_mark = '\xBB' +latin_capital_letter_l_with_small_letter_j = '\x01C8' latin_small_letter_i_with_caron = '\x1D0' combining_acute_accent = '\x301' greek_capital_letter_alpha = '\x0391' bengali_digit_zero = '\x09E6' en_space = '\x2002' +roman_numeral_one = '\x2160' +small_roman_numeral_one = '\x2170' +circled_latin_capital_letter_a = '\x24B6' +circled_latin_small_letter_a = '\x24D6' gothic_letter_ahsa = '\x10330' monospaced_digit_zero = '\x1D7F6' +squared_latin_capital_letter_a = '\x1F130' ===================================== libraries/base/tests/unicode001.stdout ===================================== @@ -1,14 +1,22 @@ - upper lower alpha alnum digit print space cntrl -'\b' X -'\t' X X -' ' X X -'0' X X X -'a' X X X X -'A' X X X X -'\DEL' X -'\187' X -'\913' X X X X -'\2534' X X -'\8194' X X -'\66352' X X X -'\120822' X X + upper uppr2 lower lowr2 alpha alnum digit print space cntrl +'\b' X +'\t' X X +' ' X X +'0' X X X +'a' X X X X X +'A' X X X X X +'\DEL' X +'\187' X +'\456' X X X X +'\464' X X X X X +'\769' X +'\913' X X X X X +'\2534' X X +'\8194' X X +'\8544' X X X +'\8560' X X X +'\9398' X X +'\9430' X X +'\66352' X X X +'\120822' X X +'\127280' X X ===================================== libraries/base/tools/ucd2haskell/exe/Parser/Text.hs ===================================== @@ -22,12 +22,12 @@ module Parser.Text (genModules) where import Control.Exception (catch, IOException) import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO)) --- import Data.Bits (Bits(..)) [NOTE] Used by disabled generator +import Data.Bits (Bits(..)) import Data.Word (Word8) -import Data.Char (chr, ord {-, isSpace-}) +import Data.Char (chr, ord, isSpace) import Data.Functor ((<&>)) import Data.Function ((&)) --- import Data.List (unfoldr, intersperse) [NOTE] Used by disabled generator +import Data.List (intersperse, unfoldr) import Data.List.Split (splitWhen) import Numeric (showHex) import Streamly.Data.Fold (Fold) @@ -132,7 +132,6 @@ readCodePointM :: String -> Maybe Char readCodePointM "" = Nothing readCodePointM u = Just (readCodePoint u) -{- [NOTE] Used by disabled generator genSignature :: String -> String genSignature = (<> " :: Char -> Bool") @@ -189,7 +188,6 @@ bitMapToAddrLiteral bs cs = foldr encode cs (unfoldr mkChunks bs) toByte :: [Bool] -> Int toByte xs = sum $ map (\i -> if xs !! i then 1 `shiftL` i else 0) [0..7] --} genEnumBitmap :: forall a. (Bounded a, Enum a, Show a) => @@ -642,8 +640,6 @@ genSimpleCaseMappingModule moduleName funcName field = showHexChar c = showHex (ord c) -{- [NOTE] Disabled generator - genCorePropertiesModule :: Monad m => String -> (String -> Bool) -> Fold m (String, [Int]) String genCorePropertiesModule moduleName isProp = @@ -674,7 +670,6 @@ genCorePropertiesModule moduleName isProp = , "import GHC.Unicode.Internal.Bits (lookupBit64)" , "" ] --} {- [NOTE] Disabled generator genUnicode002TestResults :: Monad m => Fold m DetailedChar String @@ -778,8 +773,6 @@ genUnicode002TestResults = done <$> Fold.foldl' step initial -- Parsing property files ------------------------------------------------------------------------------- -{- [NOTE] Used by disabled generator - type PropertyLine = (String, [Int]) trim :: String -> String @@ -826,7 +819,6 @@ parsePropertyLines = Stream.splitOn isDivider $ Fold.lmap parsePropertyLine $ Fold.foldl' combinePropertyLines emptyPropertyLine --} -- | A range entry in @UnicodeData.txt at . data UnicodeDataRange @@ -1014,7 +1006,7 @@ runGenerator indir file transformLines outdir recipes = combinedFld = void $ Fold.distribute generatedFolds genModules :: String -> String -> [String] -> IO () -genModules indir outdir _props = do +genModules indir outdir props = do genUnicodeVersion outdir -- [NOTE] Disabled generator @@ -1060,13 +1052,12 @@ genModules indir outdir _props = do -- outdir -- [ uncurry ModuleRecipe propList ] - -- [NOTE] Disabled generator - -- runGenerator - -- indir - -- "DerivedCoreProperties.txt" - -- parsePropertyLines - -- outdir - -- [ uncurry ModuleRecipe derivedCoreProperties ] + runGenerator + indir + "DerivedCoreProperties.txt" + parsePropertyLines + outdir + [ uncurry ModuleRecipe derivedCoreProperties ] where @@ -1075,10 +1066,9 @@ genModules indir outdir _props = do -- ("GHC.Unicode.Internal.Char.PropList" -- , (`genCorePropertiesModule` (`elem` props))) - -- [NOTE] Disabled generator - -- derivedCoreProperties = - -- ("GHC.Unicode.Internal.Char.DerivedCoreProperties" - -- , (`genCorePropertiesModule` (`elem` props))) + derivedCoreProperties = + ("GHC.Unicode.Internal.Char.DerivedCoreProperties" + , (`genCorePropertiesModule` (`elem` props))) -- [NOTE] Disabled generator -- compositions exc non0 = ===================================== libraries/base/tools/ucd2haskell/tests/check_all_chars.py ===================================== @@ -10,6 +10,15 @@ from operator import methodcaller def parse_codepoint(s: str, base=16): return chr(int(s, base)) +def parse_bool(s: str): + match(s): + case "True": + return True + case "False": + return False + case _: + raise ValueError(s) + def general_category(c: str): match(unicodedata.category(c)): case "Lu": @@ -107,6 +116,11 @@ def check_case_mapping(case_mapping: str, char: str, raw_expected: str, verbosit f"“{expected}” (1 char)." ) +def check_case_predicate(case_predicate: str, char: str, raw_expected: str, verbosity: int): + got = methodcaller(case_predicate)(char) + expected = parse_bool(raw_expected) + check(got == expected, (char, got, expected)) + if __name__ == "__main__": parser = make_parser() @@ -125,10 +139,12 @@ if __name__ == "__main__": next(fp) reader = csv.reader(fp) for row in reader: - raw_code, gc, raw_lower, raw_upper, raw_title = row + raw_code, gc, raw_lower, raw_upper, raw_title, raw_islower, raw_isupper = row char = parse_codepoint(raw_code) codepoint = f"U+{raw_code.upper():0>4}" check(gc == general_category(char), (char, gc, general_category(char))) check_case_mapping("lower", char, raw_lower, verbosity) check_case_mapping("upper", char, raw_upper, verbosity) check_case_mapping("title", char, raw_title, verbosity) + check_case_predicate("islower", char, raw_islower, verbosity) + check_case_predicate("isupper", char, raw_isupper, verbosity) ===================================== libraries/base/tools/ucd2haskell/tests/export_all_chars.hs ===================================== @@ -26,7 +26,7 @@ main = do -- | File header header :: String -header = "Char,General Category,Lower Case,Upper Case,Title Case" +header = "Char,General Category,Lower Case,Upper Case,Title Case,isLowerCase,isUpperCase" -- | Convert a character to its (short) hexadecimal Unicode codepoint. mkCodePointHex :: Char -> String @@ -43,4 +43,8 @@ addEntry c = do putChar ',' putStr (mkCodePointHex (toUpper c)) putChar ',' - putStrLn (mkCodePointHex (toTitle c)) + putStr (mkCodePointHex (toTitle c)) + putChar ',' + putStr (show (isLowerCase c)) + putChar ',' + putStrLn (show (isUpperCase c)) ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,6 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ + ucd/DerivedCoreProperties.txt:d367290bc0867e6b484c68370530bdd1a08b6b32404601b8c7accaf83e05628d \ ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -58,10 +59,10 @@ run_generator() { # Compile and run ucd2haskell cabal run exe:ucd2haskell -- \ --input "$SCRIPT_DIR/ucd/" \ - --output "$GHC_MODULE_PATH/" - # [NOTE] disabled generaor - # --core-prop Uppercase \ - # --core-prop Lowercase \ + --output "$GHC_MODULE_PATH/" \ + --core-prop Uppercase \ + --core-prop Lowercase + # [NOTE] disabled generator # --core-prop Alphabetic # --core-prop White_Space \ # --core-prop ID_Start \ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f86bcf81708c54ed8dd98212b290c5cc8510eb3...bb13eed53f66de571a90051c0e66534167812650 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f86bcf81708c54ed8dd98212b290c5cc8510eb3...bb13eed53f66de571a90051c0e66534167812650 You're receiving 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 Oct 14 08:35:54 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 04:35:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <63491f6a7c12a_2c5d73514787183f5@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 55f93e68 by Pierre Le Marre at 2022-10-14T04:35:31-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - 3ef7e9ff by Bodigrim at 2022-10-14T04:35:34-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - 13 changed files: - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh Changes: ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -140,6 +140,11 @@ Runtime system - Updated to `Unicode 15.0.0 `_. +- Add standard Unicode case predicates :base-ref:`Data.Char.isUpperCase` and + :base-ref:`Data.Char.isLowerCase`. These predicates use the standard Unicode + case properties and are more intuitive than :base-ref:`Data.Char.isUpper` and + :base-ref:`Data.Char.isLower`. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/Data/Char.hs ===================================== @@ -6,7 +6,7 @@ -- Module : Data.Char -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : stable -- Portability : portable @@ -24,7 +24,7 @@ module Data.Char -- punctuation, symbols, separators (including spaces) and others -- (including control characters). , isControl, isSpace - , isLower, isUpper, isAlpha, isAlphaNum, isPrint + , isLower, isLowerCase, isUpper, isUpperCase, isAlpha, isAlphaNum, isPrint , isDigit, isOctDigit, isHexDigit , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator ===================================== libraries/base/Data/OldList.hs ===================================== @@ -1249,6 +1249,7 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs at . +-- -- This function is productive on infinite inputs: -- -- >>> take 6 $ map (take 3) $ permutations ['a'..] @@ -1259,21 +1260,25 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] -- -permutations :: [a] -> [[a]] +permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation. -- Related discussions: -- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html -- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html -permutations xs0 = xs0 : perms xs0 [] +permutations xs0 = xs0 : perms xs0 [] where + perms :: forall a. [a] -> [a] -> [[a]] perms [] _ = [] perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) - where interleave xs r = let (_,zs) = interleave' id xs r in zs - interleave' _ [] r = (ts, r) - interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r - in (y:us, f (t:y:us) : zs) - + where + interleave :: [a] -> [[a]] -> [[a]] + interleave xs r = let (_,zs) = interleave' id xs r in zs + + interleave' :: ([a] -> b) -> [a] -> [b] -> ([a], [b]) + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) ------------------------------------------------------------------------------ -- Quick Sort algorithm taken from HBC's QSort library. ===================================== libraries/base/GHC/Unicode.hs ===================================== @@ -24,8 +24,8 @@ module GHC.Unicode ( GeneralCategory (..), generalCategory, isAscii, isLatin1, isControl, isAsciiUpper, isAsciiLower, - isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, + isPrint, isSpace, isUpper, isUpperCase, + isLower, isLowerCase, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, isPunctuation, isSymbol, toUpper, toLower, toTitle @@ -37,6 +37,7 @@ import GHC.Enum ( Enum (..), Bounded (..) ) import GHC.Ix ( Ix (..) ) import GHC.Num import GHC.Unicode.Internal.Version +import qualified GHC.Unicode.Internal.Char.DerivedCoreProperties as DCP import qualified GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory as GC import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping as C import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping as C @@ -236,18 +237,68 @@ isSpace c -- | Selects upper-case or title-case alphabetic Unicode characters (letters). -- Title case is used by a small number of letter ligatures like the -- single-character form of /Lj/. +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'UppercaseLetter' or 'TitlecaseLetter'. +-- +-- See 'isUpperCase' for a more intuitive predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). isUpper :: Char -> Bool isUpper c = case generalCategory c of UppercaseLetter -> True TitlecaseLetter -> True _ -> False +-- | Selects upper-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Uppercase@, which include letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). +-- +-- See 'isUpper' for the legacy predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). +-- +-- @since 4.18.0.0 +{-# INLINE isUpperCase #-} +isUpperCase :: Char -> Bool +isUpperCase = DCP.isUppercase + -- | Selects lower-case alphabetic Unicode characters (letters). +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'LowercaseLetter'. +-- +-- See 'isLowerCase' for a more intuitive predicate. isLower :: Char -> Bool isLower c = case generalCategory c of LowercaseLetter -> True _ -> False +-- | Selects lower-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Lowercase@, which includes letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). +-- +-- See 'isLower' for the legacy predicate. +-- +-- @since 4.18.0.0 +{-# INLINE isLowerCase #-} +isLowerCase :: Char -> Bool +isLowerCase = DCP.isLowercase + -- | Selects alphabetic Unicode characters (lower-case, upper-case and -- title-case letters, plus letters of caseless scripts and modifiers letters). -- This function is equivalent to 'Data.Char.isLetter'. ===================================== libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs ===================================== @@ -0,0 +1,35 @@ +-- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell, +-- with data from: https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt. + +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Unicode.Internal.Char.DerivedCoreProperties +-- Copyright : (c) 2020 Composewell Technologies and Contributors +-- License : BSD-3-Clause +-- Maintainer : streamly at composewell.com +-- Stability : internal +----------------------------------------------------------------------------- + +module GHC.Unicode.Internal.Char.DerivedCoreProperties +(isUppercase , isLowercase) +where + +import GHC.Base (Bool, Char, Ord(..), (&&), ord) +import GHC.Unicode.Internal.Bits (lookupBit64) + +{-# INLINE isUppercase #-} +isUppercase :: Char -> Bool +isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\2\65\1\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"# + +{-# INLINE isLowercase #-} +isLowercase :: Char -> Bool +isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\5\170\2\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"# + ===================================== libraries/base/base.cabal ===================================== @@ -352,6 +352,7 @@ Library GHC.Event.Unique -- GHC.IOPort -- TODO: hide again after debug GHC.Unicode.Internal.Bits + GHC.Unicode.Internal.Char.DerivedCoreProperties GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping ===================================== libraries/base/changelog.md ===================================== @@ -30,6 +30,10 @@ for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). + * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to + `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode + case properties and are more intuitive than `isUpper` and `isLower`. See + [CLC proposal #90](https://github.com/haskell/core-libraries-committee/issues/90). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tests/unicode001.hs ===================================== @@ -16,17 +16,45 @@ main = do f True = "X " f False = " " -strs = ["upper","lower","alpha","alnum","digit","print","space","cntrl"] +strs = + [ "upper", + "uppr2", + "lower", + "lowr2", + "alpha", + "alnum", + "digit", + "print", + "space", + "cntrl" ] -functions = [isUpper,isLower,isAlpha,isAlphaNum,isDigit,isPrint,isSpace,isControl] +functions = + [ isUpper, + isUpperCase, + isLower, + isLowerCase, + isAlpha, + isAlphaNum, + isDigit, + isPrint, + isSpace, + isControl ] chars = [backspace,tab,space,zero,lower_a,upper_a,delete, right_pointing_double_angle_quotation_mark, + latin_capital_letter_l_with_small_letter_j, + latin_small_letter_i_with_caron, + combining_acute_accent, greek_capital_letter_alpha, bengali_digit_zero, en_space, + roman_numeral_one, + small_roman_numeral_one, + circled_latin_capital_letter_a, + circled_latin_small_letter_a, gothic_letter_ahsa, - monospaced_digit_zero + monospaced_digit_zero, + squared_latin_capital_letter_a ] backspace = '\x08' @@ -37,10 +65,16 @@ lower_a = 'a' upper_a = 'A' delete = '\x7f' right_pointing_double_angle_quotation_mark = '\xBB' +latin_capital_letter_l_with_small_letter_j = '\x01C8' latin_small_letter_i_with_caron = '\x1D0' combining_acute_accent = '\x301' greek_capital_letter_alpha = '\x0391' bengali_digit_zero = '\x09E6' en_space = '\x2002' +roman_numeral_one = '\x2160' +small_roman_numeral_one = '\x2170' +circled_latin_capital_letter_a = '\x24B6' +circled_latin_small_letter_a = '\x24D6' gothic_letter_ahsa = '\x10330' monospaced_digit_zero = '\x1D7F6' +squared_latin_capital_letter_a = '\x1F130' ===================================== libraries/base/tests/unicode001.stdout ===================================== @@ -1,14 +1,22 @@ - upper lower alpha alnum digit print space cntrl -'\b' X -'\t' X X -' ' X X -'0' X X X -'a' X X X X -'A' X X X X -'\DEL' X -'\187' X -'\913' X X X X -'\2534' X X -'\8194' X X -'\66352' X X X -'\120822' X X + upper uppr2 lower lowr2 alpha alnum digit print space cntrl +'\b' X +'\t' X X +' ' X X +'0' X X X +'a' X X X X X +'A' X X X X X +'\DEL' X +'\187' X +'\456' X X X X +'\464' X X X X X +'\769' X +'\913' X X X X X +'\2534' X X +'\8194' X X +'\8544' X X X +'\8560' X X X +'\9398' X X +'\9430' X X +'\66352' X X X +'\120822' X X +'\127280' X X ===================================== libraries/base/tools/ucd2haskell/exe/Parser/Text.hs ===================================== @@ -22,12 +22,12 @@ module Parser.Text (genModules) where import Control.Exception (catch, IOException) import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO)) --- import Data.Bits (Bits(..)) [NOTE] Used by disabled generator +import Data.Bits (Bits(..)) import Data.Word (Word8) -import Data.Char (chr, ord {-, isSpace-}) +import Data.Char (chr, ord, isSpace) import Data.Functor ((<&>)) import Data.Function ((&)) --- import Data.List (unfoldr, intersperse) [NOTE] Used by disabled generator +import Data.List (intersperse, unfoldr) import Data.List.Split (splitWhen) import Numeric (showHex) import Streamly.Data.Fold (Fold) @@ -132,7 +132,6 @@ readCodePointM :: String -> Maybe Char readCodePointM "" = Nothing readCodePointM u = Just (readCodePoint u) -{- [NOTE] Used by disabled generator genSignature :: String -> String genSignature = (<> " :: Char -> Bool") @@ -189,7 +188,6 @@ bitMapToAddrLiteral bs cs = foldr encode cs (unfoldr mkChunks bs) toByte :: [Bool] -> Int toByte xs = sum $ map (\i -> if xs !! i then 1 `shiftL` i else 0) [0..7] --} genEnumBitmap :: forall a. (Bounded a, Enum a, Show a) => @@ -642,8 +640,6 @@ genSimpleCaseMappingModule moduleName funcName field = showHexChar c = showHex (ord c) -{- [NOTE] Disabled generator - genCorePropertiesModule :: Monad m => String -> (String -> Bool) -> Fold m (String, [Int]) String genCorePropertiesModule moduleName isProp = @@ -674,7 +670,6 @@ genCorePropertiesModule moduleName isProp = , "import GHC.Unicode.Internal.Bits (lookupBit64)" , "" ] --} {- [NOTE] Disabled generator genUnicode002TestResults :: Monad m => Fold m DetailedChar String @@ -778,8 +773,6 @@ genUnicode002TestResults = done <$> Fold.foldl' step initial -- Parsing property files ------------------------------------------------------------------------------- -{- [NOTE] Used by disabled generator - type PropertyLine = (String, [Int]) trim :: String -> String @@ -826,7 +819,6 @@ parsePropertyLines = Stream.splitOn isDivider $ Fold.lmap parsePropertyLine $ Fold.foldl' combinePropertyLines emptyPropertyLine --} -- | A range entry in @UnicodeData.txt at . data UnicodeDataRange @@ -1014,7 +1006,7 @@ runGenerator indir file transformLines outdir recipes = combinedFld = void $ Fold.distribute generatedFolds genModules :: String -> String -> [String] -> IO () -genModules indir outdir _props = do +genModules indir outdir props = do genUnicodeVersion outdir -- [NOTE] Disabled generator @@ -1060,13 +1052,12 @@ genModules indir outdir _props = do -- outdir -- [ uncurry ModuleRecipe propList ] - -- [NOTE] Disabled generator - -- runGenerator - -- indir - -- "DerivedCoreProperties.txt" - -- parsePropertyLines - -- outdir - -- [ uncurry ModuleRecipe derivedCoreProperties ] + runGenerator + indir + "DerivedCoreProperties.txt" + parsePropertyLines + outdir + [ uncurry ModuleRecipe derivedCoreProperties ] where @@ -1075,10 +1066,9 @@ genModules indir outdir _props = do -- ("GHC.Unicode.Internal.Char.PropList" -- , (`genCorePropertiesModule` (`elem` props))) - -- [NOTE] Disabled generator - -- derivedCoreProperties = - -- ("GHC.Unicode.Internal.Char.DerivedCoreProperties" - -- , (`genCorePropertiesModule` (`elem` props))) + derivedCoreProperties = + ("GHC.Unicode.Internal.Char.DerivedCoreProperties" + , (`genCorePropertiesModule` (`elem` props))) -- [NOTE] Disabled generator -- compositions exc non0 = ===================================== libraries/base/tools/ucd2haskell/tests/check_all_chars.py ===================================== @@ -10,6 +10,15 @@ from operator import methodcaller def parse_codepoint(s: str, base=16): return chr(int(s, base)) +def parse_bool(s: str): + match(s): + case "True": + return True + case "False": + return False + case _: + raise ValueError(s) + def general_category(c: str): match(unicodedata.category(c)): case "Lu": @@ -107,6 +116,11 @@ def check_case_mapping(case_mapping: str, char: str, raw_expected: str, verbosit f"“{expected}” (1 char)." ) +def check_case_predicate(case_predicate: str, char: str, raw_expected: str, verbosity: int): + got = methodcaller(case_predicate)(char) + expected = parse_bool(raw_expected) + check(got == expected, (char, got, expected)) + if __name__ == "__main__": parser = make_parser() @@ -125,10 +139,12 @@ if __name__ == "__main__": next(fp) reader = csv.reader(fp) for row in reader: - raw_code, gc, raw_lower, raw_upper, raw_title = row + raw_code, gc, raw_lower, raw_upper, raw_title, raw_islower, raw_isupper = row char = parse_codepoint(raw_code) codepoint = f"U+{raw_code.upper():0>4}" check(gc == general_category(char), (char, gc, general_category(char))) check_case_mapping("lower", char, raw_lower, verbosity) check_case_mapping("upper", char, raw_upper, verbosity) check_case_mapping("title", char, raw_title, verbosity) + check_case_predicate("islower", char, raw_islower, verbosity) + check_case_predicate("isupper", char, raw_isupper, verbosity) ===================================== libraries/base/tools/ucd2haskell/tests/export_all_chars.hs ===================================== @@ -26,7 +26,7 @@ main = do -- | File header header :: String -header = "Char,General Category,Lower Case,Upper Case,Title Case" +header = "Char,General Category,Lower Case,Upper Case,Title Case,isLowerCase,isUpperCase" -- | Convert a character to its (short) hexadecimal Unicode codepoint. mkCodePointHex :: Char -> String @@ -43,4 +43,8 @@ addEntry c = do putChar ',' putStr (mkCodePointHex (toUpper c)) putChar ',' - putStrLn (mkCodePointHex (toTitle c)) + putStr (mkCodePointHex (toTitle c)) + putChar ',' + putStr (show (isLowerCase c)) + putChar ',' + putStrLn (show (isUpperCase c)) ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,6 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ + ucd/DerivedCoreProperties.txt:d367290bc0867e6b484c68370530bdd1a08b6b32404601b8c7accaf83e05628d \ ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -58,10 +59,10 @@ run_generator() { # Compile and run ucd2haskell cabal run exe:ucd2haskell -- \ --input "$SCRIPT_DIR/ucd/" \ - --output "$GHC_MODULE_PATH/" - # [NOTE] disabled generaor - # --core-prop Uppercase \ - # --core-prop Lowercase \ + --output "$GHC_MODULE_PATH/" \ + --core-prop Uppercase \ + --core-prop Lowercase + # [NOTE] disabled generator # --core-prop Alphabetic # --core-prop White_Space \ # --core-prop ID_Start \ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bb13eed53f66de571a90051c0e66534167812650...3ef7e9ffac49d337d3b25433bf42669d3c12115b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bb13eed53f66de571a90051c0e66534167812650...3ef7e9ffac49d337d3b25433bf42669d3c12115b You're receiving 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 Oct 14 10:15:54 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 06:15:54 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Use FastMutInt in G for uniques Message-ID: <634936dae309_2c5d735143c761614@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 1e139730 by Sylvain Henry at 2022-10-14T12:18:54+02:00 Use FastMutInt in G for uniques - - - - - 3 changed files: - compiler/GHC/StgToJS/Ids.hs - compiler/GHC/StgToJS/Monad.hs - compiler/GHC/StgToJS/Types.hs Changes: ===================================== compiler/GHC/StgToJS/Ids.hs ===================================== @@ -53,8 +53,10 @@ import GHC.Types.Name import GHC.Unit.Module import GHC.Utils.Encoding (zEncodeString) import GHC.Data.FastString +import GHC.Data.FastMutInt import Control.Monad +import Control.Monad.IO.Class import qualified Control.Monad.Trans.State.Strict as State import qualified Data.Map as M import Data.Maybe @@ -62,8 +64,12 @@ import Data.Maybe -- | Get fresh unique number freshUnique :: G Int freshUnique = do - State.modify (\s -> s { gsId = gsId s + 1}) - State.gets gsId + id_gen <- State.gets gsId + liftIO $ do + -- no need for atomicFetchAdd as we don't use threads in G + v <- readFastMutInt id_gen + writeFastMutInt id_gen (v+1) + pure v -- | Get fresh local Ident of the form: h$$unit:module_uniq freshIdent :: G Ident ===================================== compiler/GHC/StgToJS/Monad.hs ===================================== @@ -39,6 +39,7 @@ import GHC.Types.ForeignCall import qualified Control.Monad.Trans.State.Strict as State import GHC.Data.FastString +import GHC.Data.FastMutInt import qualified Data.Map as M import qualified Data.Set as S @@ -48,18 +49,20 @@ import Data.Function import GHC.Types.Unique.DSet runG :: StgToJSConfig -> Module -> UniqFM Id CgStgExpr -> G a -> IO a -runG config m unfloat action = State.evalStateT action (initState config m unfloat) - -initState :: StgToJSConfig -> Module -> UniqFM Id CgStgExpr -> GenState -initState config m unfloat = GenState - { gsSettings = config - , gsModule = m - , gsId = 1 - , gsIdents = emptyIdCache - , gsUnfloated = unfloat - , gsGroup = defaultGenGroupState - , gsGlobal = [] - } +runG config m unfloat action = State.evalStateT action =<< initState config m unfloat + +initState :: StgToJSConfig -> Module -> UniqFM Id CgStgExpr -> IO GenState +initState config m unfloat = do + id_gen <- newFastMutInt 1 + pure $ GenState + { gsSettings = config + , gsModule = m + , gsId = id_gen + , gsIdents = emptyIdCache + , gsUnfloated = unfloat + , gsGroup = defaultGenGroupState + , gsGlobal = [] + } modifyGroup :: (GenGroupState -> GenGroupState) -> G () ===================================== compiler/GHC/StgToJS/Types.hs ===================================== @@ -39,6 +39,7 @@ import Control.Monad.Trans.State.Strict import GHC.Utils.Outputable (Outputable (..), text, SDocContext, (<+>), ($$)) import GHC.Data.FastString +import GHC.Data.FastMutInt import GHC.Unit.Module @@ -55,9 +56,9 @@ type G = StateT GenState IO -- | The JS code generator state data GenState = GenState - { gsSettings :: StgToJSConfig -- ^ codegen settings, read-only + { gsSettings :: !StgToJSConfig -- ^ codegen settings, read-only , gsModule :: !Module -- ^ current module - , gsId :: !Int -- ^ unique number for the id generator + , gsId :: {-# UNPACK #-} !FastMutInt -- ^ unique number for the id generator , gsIdents :: !IdCache -- ^ hash consing for identifiers from a Unique , gsUnfloated :: !(UniqFM Id CgStgExpr) -- ^ unfloated arguments , gsGroup :: GenGroupState -- ^ state for the current binding group @@ -159,7 +160,6 @@ instance ToJExpr CIStatic where data VarType = PtrV -- ^ pointer = reference to heap object (closure object) | VoidV -- ^ no fields - -- | FloatV -- one field -- no single precision supported | DoubleV -- ^ A Double: one field | IntV -- ^ An Int (32bit because JS): one field | LongV -- ^ A Long: two fields one for the upper 32bits, one for the lower (NB: JS is little endian) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e13973052f5772badafbf7624b345a1a5acb966 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e13973052f5772badafbf7624b345a1a5acb966 You're receiving 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 Oct 14 10:24:08 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 06:24:08 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Compactor: remove dead code Message-ID: <634938c8509f_2c5d73513c47640d2@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: cf1d7dcd by Sylvain Henry at 2022-10-14T12:27:28+02:00 Compactor: remove dead code - - - - - 2 changed files: - compiler/GHC/StgToJS/Linker/Compactor.hs - compiler/GHC/StgToJS/Linker/Types.hs Changes: ===================================== compiler/GHC/StgToJS/Linker/Compactor.hs ===================================== @@ -32,7 +32,6 @@ module GHC.StgToJS.Linker.Compactor ( compact - , collectGlobals , debugShowStat , packStrings , staticInfoArgs @@ -76,11 +75,6 @@ import Prelude import GHC.Utils.Encoding --- | collect global objects (data / CAFs). rename them and add them to the table -collectGlobals :: [StaticInfo] - -> State CompactorState () -collectGlobals = mapM_ (\(StaticInfo i _ _) -> renameObj i) - debugShowStat :: (JStat, [ClosureInfo], [StaticInfo]) -> String debugShowStat (_s, cis, sis) = "closures:\n" ++ @@ -173,42 +167,10 @@ staticDeclStat (StaticInfo global_name static_value _) = decl to_byte_list = JList . map (Int . fromIntegral) . BS.unpack --- | rename a heap object, which means adding it to the --- static init table in addition to the renamer -renameObj :: FastString - -> State CompactorState FastString -renameObj xs = do - (TxtI xs') <- renameVar (TxtI xs) -- added to the renamer - modify (addStaticEntry xs') -- and now the table - return xs' - lookupRenamed :: CompactorState -> Ident -> Ident lookupRenamed cs i@(TxtI t) = fromMaybe i (lookupUniqMap (csNameMap cs) t) -renameVar :: Ident -- ^ text identifier to rename - -> State CompactorState Ident -- ^ the updated renamer state and the new ident -renameVar i@(TxtI t) - | "h$$" `List.isPrefixOf` unpackFS t = do - m <- gets csNameMap - case lookupUniqMap m t of - Just r -> return r - Nothing -> do - y <- newIdent - let add_var cs' = cs' {csNameMap = addToUniqMap (csNameMap cs') t y} - modify add_var - return y - | otherwise = return i - -newIdent :: State CompactorState Ident -newIdent = do - yys <- gets csIdentSupply - case yys of - (y:ys) -> do - modify (\cs -> cs {csIdentSupply = ys}) - return y - _ -> error "newIdent: empty list" - -- | rename a compactor info entry according to the compactor state (no new renamings are added) renameClosureInfo :: CompactorState -> ClosureInfo ===================================== compiler/GHC/StgToJS/Linker/Types.hs ===================================== @@ -43,23 +43,12 @@ import System.IO import Prelude --- | Return a list of fresh local @Ident@ --- --- Prefix them with 'h$$' such that these will be compacted by the compactor. -newLocals :: [Ident] -newLocals = mkIdents 0 - where - mkIdent s = TxtI (mkFastString ("h$$" <> s)) - mkIdents n = [mkIdent (c0:cs) | c0 <- chars, cs <- replicateM n chars] ++ mkIdents (n+1) - chars = ['0'..'9'] ++ ['a'..'z'] ++ ['A'..'Z'] - -------------------------------------------------------------------------------- -- CompactorState -------------------------------------------------------------------------------- data CompactorState = CompactorState - { csIdentSupply :: ![Ident] -- ^ ident supply for new names - , csNameMap :: !(UniqMap FastString Ident) -- ^ renaming mapping for internal names + { csNameMap :: !(UniqMap FastString Ident) -- ^ renaming mapping for internal names , csEntries :: !(UniqMap FastString Int) -- ^ entry functions (these get listed in the metadata init -- array) , csNumEntries :: !Int @@ -85,18 +74,19 @@ data StringTable = StringTable -- | The empty @CompactorState@ emptyCompactorState :: CompactorState -emptyCompactorState = CompactorState newLocals - mempty - mempty - 0 - mempty - 0 - mempty - 0 - mempty - mempty - mempty - emptyStringTable +emptyCompactorState = CompactorState + { csNameMap = mempty + , csEntries = mempty + , csNumEntries = 0 + , csStatics = mempty + , csNumStatics = 0 + , csLabels = mempty + , csNumLabels = 0 + , csParentEntries = mempty + , csParentStatics = mempty + , csParentLabels = mempty + , csStringTable = emptyStringTable + } -- | The empty @StringTable@ emptyStringTable :: StringTable View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf1d7dcdc7fb9c03eb7fe771ba4f6ee7b4389b0b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf1d7dcdc7fb9c03eb7fe771ba4f6ee7b4389b0b You're receiving 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 Oct 14 10:27:46 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 06:27:46 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Compactor: remove more dead code Message-ID: <634939a221805_2c5d735143c766311@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 43477793 by Sylvain Henry at 2022-10-14T12:31:06+02:00 Compactor: remove more dead code - - - - - 1 changed file: - compiler/GHC/StgToJS/Linker/Compactor.hs Changes: ===================================== compiler/GHC/StgToJS/Linker/Compactor.hs ===================================== @@ -34,8 +34,6 @@ module GHC.StgToJS.Linker.Compactor ( compact , debugShowStat , packStrings - , staticInfoArgs - , staticValArgs ) where @@ -207,16 +205,6 @@ staticIdentsA :: (FastString -> FastString) -> StaticArg -> StaticArg staticIdentsA f (StaticObjArg t) = StaticObjArg $! f t staticIdentsA _ x = x -staticInfoArgs :: Applicative f => (StaticArg -> f StaticArg) -> StaticInfo -> f StaticInfo -staticInfoArgs f (StaticInfo si sv sa) = StaticInfo si <$> staticValArgs f sv <*> pure sa - -staticValArgs :: Applicative f => (StaticArg -> f StaticArg) -> StaticVal -> f StaticVal -staticValArgs f (StaticFun fn as) = StaticFun fn <$> traverse f as -staticValArgs f (StaticThunk (Just (t, as))) = StaticThunk . Just . (t,) <$> traverse f as -staticValArgs f (StaticData c as) = StaticData c <$> traverse f as -staticValArgs f (StaticList as mt) = StaticList <$> traverse f as <*> pure mt -staticValArgs _ x = pure x - compact :: JSLinkConfig -> StgToJSConfig -> CompactorState View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43477793b9d373d28d449892ef14078c128ffd76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43477793b9d373d28d449892ef14078c128ffd76 You're receiving 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 Oct 14 11:46:07 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 07:46:07 -0400 Subject: [Git][ghc/ghc][master] Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <63494bff87a90_8b90f5175c4958b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - 12 changed files: - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh Changes: ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -140,6 +140,11 @@ Runtime system - Updated to `Unicode 15.0.0 `_. +- Add standard Unicode case predicates :base-ref:`Data.Char.isUpperCase` and + :base-ref:`Data.Char.isLowerCase`. These predicates use the standard Unicode + case properties and are more intuitive than :base-ref:`Data.Char.isUpper` and + :base-ref:`Data.Char.isLower`. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/Data/Char.hs ===================================== @@ -6,7 +6,7 @@ -- Module : Data.Char -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : stable -- Portability : portable @@ -24,7 +24,7 @@ module Data.Char -- punctuation, symbols, separators (including spaces) and others -- (including control characters). , isControl, isSpace - , isLower, isUpper, isAlpha, isAlphaNum, isPrint + , isLower, isLowerCase, isUpper, isUpperCase, isAlpha, isAlphaNum, isPrint , isDigit, isOctDigit, isHexDigit , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator ===================================== libraries/base/GHC/Unicode.hs ===================================== @@ -24,8 +24,8 @@ module GHC.Unicode ( GeneralCategory (..), generalCategory, isAscii, isLatin1, isControl, isAsciiUpper, isAsciiLower, - isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, + isPrint, isSpace, isUpper, isUpperCase, + isLower, isLowerCase, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, isPunctuation, isSymbol, toUpper, toLower, toTitle @@ -37,6 +37,7 @@ import GHC.Enum ( Enum (..), Bounded (..) ) import GHC.Ix ( Ix (..) ) import GHC.Num import GHC.Unicode.Internal.Version +import qualified GHC.Unicode.Internal.Char.DerivedCoreProperties as DCP import qualified GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory as GC import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping as C import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping as C @@ -236,18 +237,68 @@ isSpace c -- | Selects upper-case or title-case alphabetic Unicode characters (letters). -- Title case is used by a small number of letter ligatures like the -- single-character form of /Lj/. +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'UppercaseLetter' or 'TitlecaseLetter'. +-- +-- See 'isUpperCase' for a more intuitive predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). isUpper :: Char -> Bool isUpper c = case generalCategory c of UppercaseLetter -> True TitlecaseLetter -> True _ -> False +-- | Selects upper-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Uppercase@, which include letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). +-- +-- See 'isUpper' for the legacy predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). +-- +-- @since 4.18.0.0 +{-# INLINE isUpperCase #-} +isUpperCase :: Char -> Bool +isUpperCase = DCP.isUppercase + -- | Selects lower-case alphabetic Unicode characters (letters). +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'LowercaseLetter'. +-- +-- See 'isLowerCase' for a more intuitive predicate. isLower :: Char -> Bool isLower c = case generalCategory c of LowercaseLetter -> True _ -> False +-- | Selects lower-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Lowercase@, which includes letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). +-- +-- See 'isLower' for the legacy predicate. +-- +-- @since 4.18.0.0 +{-# INLINE isLowerCase #-} +isLowerCase :: Char -> Bool +isLowerCase = DCP.isLowercase + -- | Selects alphabetic Unicode characters (lower-case, upper-case and -- title-case letters, plus letters of caseless scripts and modifiers letters). -- This function is equivalent to 'Data.Char.isLetter'. ===================================== libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs ===================================== @@ -0,0 +1,35 @@ +-- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell, +-- with data from: https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt. + +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Unicode.Internal.Char.DerivedCoreProperties +-- Copyright : (c) 2020 Composewell Technologies and Contributors +-- License : BSD-3-Clause +-- Maintainer : streamly at composewell.com +-- Stability : internal +----------------------------------------------------------------------------- + +module GHC.Unicode.Internal.Char.DerivedCoreProperties +(isUppercase , isLowercase) +where + +import GHC.Base (Bool, Char, Ord(..), (&&), ord) +import GHC.Unicode.Internal.Bits (lookupBit64) + +{-# INLINE isUppercase #-} +isUppercase :: Char -> Bool +isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\2\65\1\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"# + +{-# INLINE isLowercase #-} +isLowercase :: Char -> Bool +isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\5\170\2\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"# + ===================================== libraries/base/base.cabal ===================================== @@ -352,6 +352,7 @@ Library GHC.Event.Unique -- GHC.IOPort -- TODO: hide again after debug GHC.Unicode.Internal.Bits + GHC.Unicode.Internal.Char.DerivedCoreProperties GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping ===================================== libraries/base/changelog.md ===================================== @@ -30,6 +30,10 @@ for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). + * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to + `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode + case properties and are more intuitive than `isUpper` and `isLower`. See + [CLC proposal #90](https://github.com/haskell/core-libraries-committee/issues/90). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tests/unicode001.hs ===================================== @@ -16,17 +16,45 @@ main = do f True = "X " f False = " " -strs = ["upper","lower","alpha","alnum","digit","print","space","cntrl"] +strs = + [ "upper", + "uppr2", + "lower", + "lowr2", + "alpha", + "alnum", + "digit", + "print", + "space", + "cntrl" ] -functions = [isUpper,isLower,isAlpha,isAlphaNum,isDigit,isPrint,isSpace,isControl] +functions = + [ isUpper, + isUpperCase, + isLower, + isLowerCase, + isAlpha, + isAlphaNum, + isDigit, + isPrint, + isSpace, + isControl ] chars = [backspace,tab,space,zero,lower_a,upper_a,delete, right_pointing_double_angle_quotation_mark, + latin_capital_letter_l_with_small_letter_j, + latin_small_letter_i_with_caron, + combining_acute_accent, greek_capital_letter_alpha, bengali_digit_zero, en_space, + roman_numeral_one, + small_roman_numeral_one, + circled_latin_capital_letter_a, + circled_latin_small_letter_a, gothic_letter_ahsa, - monospaced_digit_zero + monospaced_digit_zero, + squared_latin_capital_letter_a ] backspace = '\x08' @@ -37,10 +65,16 @@ lower_a = 'a' upper_a = 'A' delete = '\x7f' right_pointing_double_angle_quotation_mark = '\xBB' +latin_capital_letter_l_with_small_letter_j = '\x01C8' latin_small_letter_i_with_caron = '\x1D0' combining_acute_accent = '\x301' greek_capital_letter_alpha = '\x0391' bengali_digit_zero = '\x09E6' en_space = '\x2002' +roman_numeral_one = '\x2160' +small_roman_numeral_one = '\x2170' +circled_latin_capital_letter_a = '\x24B6' +circled_latin_small_letter_a = '\x24D6' gothic_letter_ahsa = '\x10330' monospaced_digit_zero = '\x1D7F6' +squared_latin_capital_letter_a = '\x1F130' ===================================== libraries/base/tests/unicode001.stdout ===================================== @@ -1,14 +1,22 @@ - upper lower alpha alnum digit print space cntrl -'\b' X -'\t' X X -' ' X X -'0' X X X -'a' X X X X -'A' X X X X -'\DEL' X -'\187' X -'\913' X X X X -'\2534' X X -'\8194' X X -'\66352' X X X -'\120822' X X + upper uppr2 lower lowr2 alpha alnum digit print space cntrl +'\b' X +'\t' X X +' ' X X +'0' X X X +'a' X X X X X +'A' X X X X X +'\DEL' X +'\187' X +'\456' X X X X +'\464' X X X X X +'\769' X +'\913' X X X X X +'\2534' X X +'\8194' X X +'\8544' X X X +'\8560' X X X +'\9398' X X +'\9430' X X +'\66352' X X X +'\120822' X X +'\127280' X X ===================================== libraries/base/tools/ucd2haskell/exe/Parser/Text.hs ===================================== @@ -22,12 +22,12 @@ module Parser.Text (genModules) where import Control.Exception (catch, IOException) import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO)) --- import Data.Bits (Bits(..)) [NOTE] Used by disabled generator +import Data.Bits (Bits(..)) import Data.Word (Word8) -import Data.Char (chr, ord {-, isSpace-}) +import Data.Char (chr, ord, isSpace) import Data.Functor ((<&>)) import Data.Function ((&)) --- import Data.List (unfoldr, intersperse) [NOTE] Used by disabled generator +import Data.List (intersperse, unfoldr) import Data.List.Split (splitWhen) import Numeric (showHex) import Streamly.Data.Fold (Fold) @@ -132,7 +132,6 @@ readCodePointM :: String -> Maybe Char readCodePointM "" = Nothing readCodePointM u = Just (readCodePoint u) -{- [NOTE] Used by disabled generator genSignature :: String -> String genSignature = (<> " :: Char -> Bool") @@ -189,7 +188,6 @@ bitMapToAddrLiteral bs cs = foldr encode cs (unfoldr mkChunks bs) toByte :: [Bool] -> Int toByte xs = sum $ map (\i -> if xs !! i then 1 `shiftL` i else 0) [0..7] --} genEnumBitmap :: forall a. (Bounded a, Enum a, Show a) => @@ -642,8 +640,6 @@ genSimpleCaseMappingModule moduleName funcName field = showHexChar c = showHex (ord c) -{- [NOTE] Disabled generator - genCorePropertiesModule :: Monad m => String -> (String -> Bool) -> Fold m (String, [Int]) String genCorePropertiesModule moduleName isProp = @@ -674,7 +670,6 @@ genCorePropertiesModule moduleName isProp = , "import GHC.Unicode.Internal.Bits (lookupBit64)" , "" ] --} {- [NOTE] Disabled generator genUnicode002TestResults :: Monad m => Fold m DetailedChar String @@ -778,8 +773,6 @@ genUnicode002TestResults = done <$> Fold.foldl' step initial -- Parsing property files ------------------------------------------------------------------------------- -{- [NOTE] Used by disabled generator - type PropertyLine = (String, [Int]) trim :: String -> String @@ -826,7 +819,6 @@ parsePropertyLines = Stream.splitOn isDivider $ Fold.lmap parsePropertyLine $ Fold.foldl' combinePropertyLines emptyPropertyLine --} -- | A range entry in @UnicodeData.txt at . data UnicodeDataRange @@ -1014,7 +1006,7 @@ runGenerator indir file transformLines outdir recipes = combinedFld = void $ Fold.distribute generatedFolds genModules :: String -> String -> [String] -> IO () -genModules indir outdir _props = do +genModules indir outdir props = do genUnicodeVersion outdir -- [NOTE] Disabled generator @@ -1060,13 +1052,12 @@ genModules indir outdir _props = do -- outdir -- [ uncurry ModuleRecipe propList ] - -- [NOTE] Disabled generator - -- runGenerator - -- indir - -- "DerivedCoreProperties.txt" - -- parsePropertyLines - -- outdir - -- [ uncurry ModuleRecipe derivedCoreProperties ] + runGenerator + indir + "DerivedCoreProperties.txt" + parsePropertyLines + outdir + [ uncurry ModuleRecipe derivedCoreProperties ] where @@ -1075,10 +1066,9 @@ genModules indir outdir _props = do -- ("GHC.Unicode.Internal.Char.PropList" -- , (`genCorePropertiesModule` (`elem` props))) - -- [NOTE] Disabled generator - -- derivedCoreProperties = - -- ("GHC.Unicode.Internal.Char.DerivedCoreProperties" - -- , (`genCorePropertiesModule` (`elem` props))) + derivedCoreProperties = + ("GHC.Unicode.Internal.Char.DerivedCoreProperties" + , (`genCorePropertiesModule` (`elem` props))) -- [NOTE] Disabled generator -- compositions exc non0 = ===================================== libraries/base/tools/ucd2haskell/tests/check_all_chars.py ===================================== @@ -10,6 +10,15 @@ from operator import methodcaller def parse_codepoint(s: str, base=16): return chr(int(s, base)) +def parse_bool(s: str): + match(s): + case "True": + return True + case "False": + return False + case _: + raise ValueError(s) + def general_category(c: str): match(unicodedata.category(c)): case "Lu": @@ -107,6 +116,11 @@ def check_case_mapping(case_mapping: str, char: str, raw_expected: str, verbosit f"“{expected}” (1 char)." ) +def check_case_predicate(case_predicate: str, char: str, raw_expected: str, verbosity: int): + got = methodcaller(case_predicate)(char) + expected = parse_bool(raw_expected) + check(got == expected, (char, got, expected)) + if __name__ == "__main__": parser = make_parser() @@ -125,10 +139,12 @@ if __name__ == "__main__": next(fp) reader = csv.reader(fp) for row in reader: - raw_code, gc, raw_lower, raw_upper, raw_title = row + raw_code, gc, raw_lower, raw_upper, raw_title, raw_islower, raw_isupper = row char = parse_codepoint(raw_code) codepoint = f"U+{raw_code.upper():0>4}" check(gc == general_category(char), (char, gc, general_category(char))) check_case_mapping("lower", char, raw_lower, verbosity) check_case_mapping("upper", char, raw_upper, verbosity) check_case_mapping("title", char, raw_title, verbosity) + check_case_predicate("islower", char, raw_islower, verbosity) + check_case_predicate("isupper", char, raw_isupper, verbosity) ===================================== libraries/base/tools/ucd2haskell/tests/export_all_chars.hs ===================================== @@ -26,7 +26,7 @@ main = do -- | File header header :: String -header = "Char,General Category,Lower Case,Upper Case,Title Case" +header = "Char,General Category,Lower Case,Upper Case,Title Case,isLowerCase,isUpperCase" -- | Convert a character to its (short) hexadecimal Unicode codepoint. mkCodePointHex :: Char -> String @@ -43,4 +43,8 @@ addEntry c = do putChar ',' putStr (mkCodePointHex (toUpper c)) putChar ',' - putStrLn (mkCodePointHex (toTitle c)) + putStr (mkCodePointHex (toTitle c)) + putChar ',' + putStr (show (isLowerCase c)) + putChar ',' + putStrLn (show (isUpperCase c)) ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,6 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ + ucd/DerivedCoreProperties.txt:d367290bc0867e6b484c68370530bdd1a08b6b32404601b8c7accaf83e05628d \ ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -58,10 +59,10 @@ run_generator() { # Compile and run ucd2haskell cabal run exe:ucd2haskell -- \ --input "$SCRIPT_DIR/ucd/" \ - --output "$GHC_MODULE_PATH/" - # [NOTE] disabled generaor - # --core-prop Uppercase \ - # --core-prop Lowercase \ + --output "$GHC_MODULE_PATH/" \ + --core-prop Uppercase \ + --core-prop Lowercase + # [NOTE] disabled generator # --core-prop Alphabetic # --core-prop White_Space \ # --core-prop ID_Start \ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43ab435afc01284c1fb7e500783703f580a55a90 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43ab435afc01284c1fb7e500783703f580a55a90 You're receiving 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 Oct 14 11:46:37 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 07:46:37 -0400 Subject: [Git][ghc/ghc][master] Add type signatures in where-clause of Data.List.permutations Message-ID: <63494c1d1fbb9_8b90f5174852950@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - 1 changed file: - libraries/base/Data/OldList.hs Changes: ===================================== libraries/base/Data/OldList.hs ===================================== @@ -1249,6 +1249,7 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs at . +-- -- This function is productive on infinite inputs: -- -- >>> take 6 $ map (take 3) $ permutations ['a'..] @@ -1259,21 +1260,25 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] -- -permutations :: [a] -> [[a]] +permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation. -- Related discussions: -- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html -- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html -permutations xs0 = xs0 : perms xs0 [] +permutations xs0 = xs0 : perms xs0 [] where + perms :: forall a. [a] -> [a] -> [[a]] perms [] _ = [] perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) - where interleave xs r = let (_,zs) = interleave' id xs r in zs - interleave' _ [] r = (ts, r) - interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r - in (y:us, f (t:y:us) : zs) - + where + interleave :: [a] -> [[a]] -> [[a]] + interleave xs r = let (_,zs) = interleave' id xs r in zs + + interleave' :: ([a] -> b) -> [a] -> [b] -> ([a], [b]) + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) ------------------------------------------------------------------------------ -- Quick Sort algorithm taken from HBC's QSort library. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aec5a443bc45ca99cfeedc1777edb0aceca142cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aec5a443bc45ca99cfeedc1777edb0aceca142cf You're receiving 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 Oct 14 11:47:25 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 07:47:25 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Compactor: remove unused debug code Message-ID: <63494c4da2d26_8b90f5141453172@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: fce6ce82 by Sylvain Henry at 2022-10-14T12:32:00+02:00 Compactor: remove unused debug code - - - - - 920e8999 by Sylvain Henry at 2022-10-14T12:32:35+02:00 Compactor: remove unimplemented packStrings - - - - - d68c8309 by Sylvain Henry at 2022-10-14T13:45:33+02:00 RTS: fix query/replace error - - - - - 2 changed files: - compiler/GHC/StgToJS/Linker/Compactor.hs - rts/js/environment.js Changes: ===================================== compiler/GHC/StgToJS/Linker/Compactor.hs ===================================== @@ -32,8 +32,6 @@ module GHC.StgToJS.Linker.Compactor ( compact - , debugShowStat - , packStrings ) where @@ -73,28 +71,6 @@ import Prelude import GHC.Utils.Encoding -debugShowStat :: (JStat, [ClosureInfo], [StaticInfo]) -> String -debugShowStat (_s, cis, sis) = - "closures:\n" ++ - unlines (map show cis) ++ - "\nstatics:" ++ - unlines (map show sis) ++ - "\n\n" - -{- create a single string initializer for all StaticUnboxedString references - in the code, and rewrite all references to point to it - - if incremental linking is used, each increment gets its own packed string - blob. if a string value already exists in an earlier blob it is not added - again - -} -packStrings :: HasDebugCallStack - => JSLinkConfig - -> CompactorState - -> [LinkedUnit] - -> (CompactorState, [LinkedUnit]) -packStrings _settings _cstate _code = panic "Compactor.packstrings not yet implemented!" - renameInternals :: HasDebugCallStack => JSLinkConfig -> StgToJSConfig ===================================== rts/js/environment.js ===================================== @@ -174,7 +174,7 @@ function h$setProgArgv(n, ptr_d, ptr_o) { var arg = h$decodeUtf8z(p[0], p[1]); args.push(arg); } - h$programArgs() = args; + h$programArgs_ = args; } function h$getpid() { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43477793b9d373d28d449892ef14078c128ffd76...d68c8309a7b18781c03bd2941b5c2e3ed1974183 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43477793b9d373d28d449892ef14078c128ffd76...d68c8309a7b18781c03bd2941b5c2e3ed1974183 You're receiving 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 Oct 14 12:00:38 2022 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Fri, 14 Oct 2022 08:00:38 -0400 Subject: [Git][ghc/ghc][wip/js-staging] remove unused STM check invariants Message-ID: <63494f6655651_8b90f517985555e@gitlab.mail> Luite Stegeman pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 663cee6c by Luite Stegeman at 2022-10-14T14:00:28+02:00 remove unused STM check invariants - - - - - 2 changed files: - compiler/GHC/StgToJS/Rts/Rts.hs - rts/js/stm.js Changes: ===================================== compiler/GHC/StgToJS/Rts/Rts.hs ===================================== @@ -629,46 +629,8 @@ rts' s = (appS "h$stmCommitTransaction" [] <> adjSpN' 2 <> returnS (stack .! sp)) - (push' s [var "h$checkInvariants_e"] - <> returnS (app "h$stmStartTransaction" [stack .! (sp - 2)]))) - , closure (ClosureInfo "h$checkInvariants_e" (CIRegs 0 [PtrV]) "check transaction invariants" (CILayoutFixed 0 []) CIStackFrame mempty) - (adjSpN' 1 - <> returnS (app "h$stmCheckInvariants" [])) - , closure (ClosureInfo "h$stmCheckInvariantStart_e" (CIRegs 0 []) "start checking invariant" (CILayoutFixed 2 [ObjV, RtsObjV]) CIStackFrame mempty) - (jVar $ \t inv m t1 -> - mconcat [ t |= stack .! (sp - 2) - , inv |= stack .! (sp - 1) - , m |= var "h$currentThread" .^ "mask" - , adjSpN' 3 - , t1 |= UOpExpr NewOp (app "h$Transaction" [inv .^ "action", t]) - , t1 .^ "checkRead" |= UOpExpr NewOp (app "h$Set" []) - , var "h$currentTread" .^ "transaction" |= t1 - , push' s [t1, m, var "h$stmInvariantViolatedHandler", var "h$catchStm_e"] - , r1 |= inv .^ "action" - , returnS (app "h$ap_1_0_fast" []) - ]) - , closure (ClosureInfo "h$stmCheckInvariantResult_e" (CIRegs 0 [PtrV]) "finish checking invariant" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) - (jVar $ \inv -> - mconcat [ inv |= stack .! (sp -1) - , adjSpN' 2 - , appS "h$stmUpdateInvariantDependencies" [inv] - , appS "h$stmAbortTransaction" [] - , returnS (stack .! sp) - ]) + (returnS (app "h$stmStartTransaction" [stack .! (sp - 2)]))) - -- update invariant TVar dependencies and rethrow exception - -- handler must be pushed above h$stmCheckInvariantResult_e frame - , closure (ClosureInfo "h$stmInvariantViolatedHandler_e" (CIRegs 0 [PtrV]) "finish checking invariant" (CILayoutFixed 0 []) (CIFun 2 1) mempty) - (jVar $ \inv -> - mconcat [ jwhenS (stack .! sp .===. var "h$stmCheckInvariantResult_e") - (appS "throw" [jString "h$stmInvariantViolatedHandler_e: unexpected value on stack"]) - , inv |= stack .! (sp - 2) - , adjSpN' 2 - , appS "h$stmUpdateInvariantDependencies" [] - , appS "h$stmAbortTransaction" [] - , returnS (app "h$throw" [r2, false_]) - ]) - , TxtI "h$stmInvariantViolatedHandler" ||= app "h$c" (var "h$stmInvariantViolatedHandler_e" : [jSystemCCS | csProf s]) , closure (ClosureInfo "h$stmCatchRetry_e" (CIRegs 0 [PtrV]) "catch retry" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) (adjSpN' 2 <> appS "h$stmCommitTransaction" [] @@ -683,7 +645,6 @@ rts' s = (appS "throw" [jString "h$stmResumeRetry_e: unexpected value on stack"]) , blocked |= stack .! (sp - 1) , adjSpN' 2 - , push' s [var "h$checkInvariants_e"] , appS "h$stmRemoveBlockedThread" [blocked, var "h$currentThread"] , returnS (app "h$stmStartTransaction" [stack .! (sp - 2)]) ]) ===================================== rts/js/stm.js ===================================== @@ -25,23 +25,14 @@ function h$Transaction(o, parent) { this.tvars = new h$Map(); // h$TVar -> h$LocalTVar, all local tvars accessed anywhere in the transaction this.accessed = parent===null?new h$Map():parent.accessed; - // nonnull while running a check, contains read variables in this part of the transaction - this.checkRead = parent===null?null:parent.checkRead; this.parent = parent; this.state = h$stmTransactionActive; - this.invariants = []; // invariants added in this transaction this.m = 0; // gc mark #ifdef GHCJS_DEBUG_ALLOC h$debugAlloc_notifyAlloc(this); #endif } -var h$stmInvariantN = 0; -/** @constructor */ -function h$StmInvariant(a) { - this.action = a; - this._key = ++h$stmInvariantN; -} /** @constructor */ function h$WrittenTVar(tv,v) { this.tvar = tv; @@ -54,7 +45,6 @@ function h$TVar(v) { TRACE_STM("creating TVar, value: " + h$collectProps(v)); this.val = v; // current value this.blocked = new h$Set(); // threads that get woken up if this TVar is updated - this.invariants = null; // invariants that use this TVar (h$Set) this.m = 0; // gc mark this._key = ++h$TVarN; // for storing in h$Map/h$Set #ifdef GHCJS_DEBUG_ALLOC @@ -70,12 +60,6 @@ function h$TVarsWaiting(s) { #endif } -/** @constructor */ -function h$LocalInvariant(o) { - this.action = o; - this.dependencies = new h$Set(); -} - // local view of a TVar /** @constructor */ function h$LocalTVar(v) { @@ -86,7 +70,7 @@ function h$LocalTVar(v) { } function h$atomically(o) { - h$p3(o, h$atomically_e, h$checkInvariants_e); + h$p2(o, h$atomically_e); return h$stmStartTransaction(o); } @@ -98,20 +82,6 @@ function h$stmStartTransaction(o) { return h$ap_1_0_fast(); } -function h$stmUpdateInvariantDependencies(inv) { - var ii, iter = h$currentThread.transaction.checkRead.iter(); - if(inv instanceof h$LocalInvariant) { - while((ii = iter.next()) !== null) inv.dependencies.add(ii); - } else { - while((ii = iter.next()) !== null) h$stmAddTVarInvariant(ii, inv); - } -} - -function h$stmAddTVarInvariant(tv, inv) { - if(tv.invariants === null) tv.invariants = new h$Set(); - tv.invariants.add(inv); -} - // commit current transaction, // if it's top-level, commit the TVars, otherwise commit to parent function h$stmCommitTransaction() { @@ -131,15 +101,10 @@ function h$stmCommitTransaction() { h$stmRemoveBlockedThread(thread.blockedOn, thread); h$wakeupThread(thread); } - // commit our new invariants - for(var j=0;j 0) { @@ -250,9 +208,6 @@ function h$sameTVar(tv1, tv2) { // get the local value of the TVar in the transaction t // tvar is added to the read set function h$readLocalTVar(t, tv) { - if(t.checkRead !== null) { - t.checkRead.add(tv); - } var t0 = t; while(t0 !== null) { var v = t0.tvars.get(tv); @@ -282,27 +237,6 @@ function h$setLocalTVar(t, tv, v) { } } -function h$stmCheckInvariants() { - var t = h$currentThread.transaction; - function addCheck(inv) { - h$p5(inv, h$stmCheckInvariantResult_e, t, inv, h$stmCheckInvariantStart_e); - } - h$p2(h$r1, h$return); - var wtv, i = t.tvars.iter(); - while((wtv = i.nextVal()) !== null) { - TRACE_STM("h$stmCheckInvariants: checking: " + h$collectProps(wtv)); - var ii = wtv.tvar.invariants; - if(ii) { - var iv, iii = ii.iter(); - while((iv = iii.next()) !== null) addCheck(iv); - } - } - for(var j=0;j From gitlab at gitlab.haskell.org Fri Oct 14 12:26:27 2022 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 14 Oct 2022 08:26:27 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Refactor renaming functions from Compactor module into the Linker Message-ID: <6349557320da6_8b90f5143c6339e@gitlab.mail> Josh Meredith pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 89db61b6 by Josh Meredith at 2022-10-14T12:26:02+00:00 Refactor renaming functions from Compactor module into the Linker - - - - - 2 changed files: - − compiler/GHC/StgToJS/Linker/Compactor.hs - compiler/GHC/StgToJS/Linker/Linker.hs Changes: ===================================== compiler/GHC/StgToJS/Linker/Compactor.hs deleted ===================================== @@ -1,829 +0,0 @@ -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE LambdaCase #-} - -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} - ------------------------------------------------------------------------------ --- | --- Module : GHC.StgToJS.Linker.Compactor --- Copyright : (c) The University of Glasgow 2001 --- License : BSD-style (see the file LICENSE) --- --- Maintainer : Luite Stegeman --- Sylvain Henry --- Jeffrey Young --- Josh Meredith --- Stability : experimental --- --- The compactor does link-time optimization. It is much simpler than the --- Optimizer, no fancy dataflow analysis here. --- --- Optimizations: --- - rewrite all variables starting with h$$ to shorter names, these are internal names --- - write all function metadata compactly --- --- Note: - This module is not yet complete (as of 23/09/2022), for the complete --- version to adapt see GHCJS's Gen2/Compactor.hs module. For now we have only --- the functions that constitue the API for the module so that the JS Backend --- Linker and RTS can compile and run. ------------------------------------------------------------------------------ - -module GHC.StgToJS.Linker.Compactor - ( compact - ) where - - -import GHC.Utils.Panic -import GHC.Utils.Misc -import GHC.Types.Unique.Map -import GHC.Types.Unique.Set -import GHC.Types.Unique.DSet - -import Control.Applicative -import GHC.Utils.Monad.State.Strict -import Data.Function - -import Data.Bifunctor (second) -import qualified Data.ByteString.Lazy as BL -import qualified Data.ByteString as BS -import qualified Data.ByteString.Char8 as BSC -import qualified Data.ByteString.Builder as BB -import qualified Data.Graph as G -import qualified Data.Map.Strict as M -import Data.Map (Map) -import Data.Int -import qualified Data.List as List -import Data.Maybe -import GHC.Data.FastString - -import GHC.JS.Syntax -import GHC.JS.Make -import GHC.JS.Transform -import GHC.StgToJS.Printer (pretty) -import GHC.StgToJS.Types -import GHC.StgToJS.Linker.Types -import GHC.StgToJS.Closure -import GHC.StgToJS.Arg - -import Prelude -import GHC.Utils.Encoding - - -renameInternals :: HasDebugCallStack - => JSLinkConfig - -> StgToJSConfig - -> CompactorState - -> [FastString] - -> [LinkedUnit] - -> (CompactorState, [JStat], JStat) -renameInternals ln_cfg cfg cs0 rtsDeps stats0a = (cs, stats, meta) - where - (stbs, stats0) = (if lcDedupe ln_cfg - then dedupeBodies rtsDeps . dedupe rtsDeps - else (mempty,)) stats0a - ((stats, meta), cs) = runState renamed cs0 - - renamed :: State CompactorState ([JStat], JStat) - renamed - - | True = do - cs <- get - let renamedStats = map (identsS' (lookupRenamed cs) . lu_js_code) stats0 - statics = map (renameStaticInfo cs) $ - concatMap lu_statics stats0 - infos = map (renameClosureInfo cs) $ - concatMap lu_closures stats0 - -- render metadata as individual statements - meta = mconcat (map staticDeclStat statics) <> - identsS' (lookupRenamed cs) stbs <> - mconcat (map (staticInitStat $ csProf cfg) statics) <> - mconcat (map (closureInfoStat True) infos) - return (renamedStats, meta) - --- | initialize a global object. all global objects have to be declared (staticInfoDecl) first --- (this is only used with -debug, normal init would go through the static data table) -staticInitStat :: Bool -- ^ profiling enabled - -> StaticInfo - -> JStat -staticInitStat _prof (StaticInfo i sv cc) = - case sv of - StaticData con args -> appS "h$sti" ([var i, var con, jsStaticArgs args] ++ ccArg) - StaticFun f args -> appS "h$sti" ([var i, var f, jsStaticArgs args] ++ ccArg) - StaticList args mt -> - appS "h$stl" ([var i, jsStaticArgs args, toJExpr $ maybe null_ (toJExpr . TxtI) mt] ++ ccArg) - StaticThunk (Just (f,args)) -> - appS "h$stc" ([var i, var f, jsStaticArgs args] ++ ccArg) - _ -> mempty - where - ccArg = maybeToList (fmap toJExpr cc) - --- | declare and do first-pass init of a global object (create JS object for heap objects) -staticDeclStat :: StaticInfo -> JStat -staticDeclStat (StaticInfo global_name static_value _) = decl - where - global_ident = TxtI global_name - decl_init v = global_ident ||= v - decl_no_init = appS "h$di" [toJExpr global_ident] - - decl = case static_value of - StaticUnboxed u -> decl_init (unboxed_expr u) - StaticThunk Nothing -> decl_no_init -- CAF initialized in an alternative way - _ -> decl_init (app "h$d" []) - - unboxed_expr = \case - StaticUnboxedBool b -> app "h$p" [toJExpr b] - StaticUnboxedInt i -> app "h$p" [toJExpr i] - StaticUnboxedDouble d -> app "h$p" [toJExpr (unSaneDouble d)] - StaticUnboxedString str -> app "h$rawStringData" [ValExpr (to_byte_list str)] - StaticUnboxedStringOffset {} -> 0 - - to_byte_list = JList . map (Int . fromIntegral) . BS.unpack - -lookupRenamed :: CompactorState -> Ident -> Ident -lookupRenamed cs i@(TxtI t) = - fromMaybe i (lookupUniqMap (csNameMap cs) t) - --- | rename a compactor info entry according to the compactor state (no new renamings are added) -renameClosureInfo :: CompactorState - -> ClosureInfo - -> ClosureInfo -renameClosureInfo cs (ClosureInfo v rs n l t s) = - ClosureInfo (renameV v) rs n l t (f s) - where - renameV t = maybe t itxt (lookupUniqMap m t) - m = csNameMap cs - f (CIStaticRefs rs) = CIStaticRefs (map renameV rs) - --- | rename a static info entry according to the compactor state (no new renamings are added) -renameStaticInfo :: CompactorState - -> StaticInfo - -> StaticInfo -renameStaticInfo cs = staticIdents renameIdent - where - renameIdent t = maybe t itxt (lookupUniqMap (csNameMap cs) t) - -staticIdents :: (FastString -> FastString) - -> StaticInfo - -> StaticInfo -staticIdents f (StaticInfo i v cc) = StaticInfo (f i) (staticIdentsV f v) cc - -staticIdentsV ::(FastString -> FastString) -> StaticVal -> StaticVal -staticIdentsV f (StaticFun i args) = StaticFun (f i) (staticIdentsA f <$> args) -staticIdentsV f (StaticThunk (Just (i, args))) = StaticThunk . Just $ - (f i, staticIdentsA f <$> args) -staticIdentsV f (StaticData con args) = StaticData (f con) (staticIdentsA f <$> args) -staticIdentsV f (StaticList xs t) = StaticList (staticIdentsA f <$> xs) (f <$> t) -staticIdentsV _ x = x - -staticIdentsA :: (FastString -> FastString) -> StaticArg -> StaticArg -staticIdentsA f (StaticObjArg t) = StaticObjArg $! f t -staticIdentsA _ x = x - -compact :: JSLinkConfig - -> StgToJSConfig - -> CompactorState - -> [FastString] - -> [LinkedUnit] - -> (CompactorState, [JStat], JStat) -compact ln_cfg cfg cs0 rtsDeps0 input0 - = - let rtsDeps1 = rtsDeps0 ++ - map (<> "_e") rtsDeps0 ++ - map (<> "_con_e") rtsDeps0 - in renameInternals ln_cfg cfg cs0 rtsDeps1 input0 - - --- hash compactification -dedupeBodies :: [FastString] - -> [LinkedUnit] - -> (JStat, [LinkedUnit]) -dedupeBodies rtsDeps input = (renderBuildFunctions bfN bfCB, input') - where - (bfN, bfCB, input') = rewriteBodies globals hdefsR hdefs input - hdefs = M.fromListWith (\(s,ks1) (_,ks2) -> (s, ks1++ks2)) - (map (\(k, s, bs) -> (bs, (s, [k]))) hdefs0) - hdefsR = listToUniqMap $ map (\(k, _, bs) -> (k, bs)) hdefs0 - hdefs0 :: [(FastString, Int, BS.ByteString)] - hdefs0 = concatMap ((map (\(k,h) -> - let (s,fh, _deps) = finalizeHash' h - in (k, s, fh)) - . hashDefinitions globals) . lu_js_code) - input - globals = List.foldl' delOneFromUniqSet (findAllGlobals input) rtsDeps - -renderBuildFunctions :: [BuildFunction] -> [BuildFunction] -> JStat -renderBuildFunctions normalBfs cycleBreakerBfs = - cycleBr1 <> mconcat (map renderBuildFunction normalBfs) <> cycleBr2 - where - renderCbr f = mconcat (zipWith f cycleBreakerBfs [1..]) - cbName :: Int -> FastString - cbName = mkFastString . ("h$$$cb"++) . show - cycleBr1 = renderCbr $ \bf n -> - let args = map (TxtI . mkFastString . ('a':) . show) [1..bfArgs bf] - body = ReturnStat $ ApplExpr (ValExpr (JVar (TxtI $ cbName n))) - (map (ValExpr . JVar) args) - bfn = bfName bf - in (TxtI bfn) ||= (ValExpr (JFunc args body)) - cycleBr2 = renderCbr $ \bf n -> renderBuildFunction (bf { bfName = cbName n }) - -data BuildFunction = BuildFunction - { bfName :: !FastString - , bfBuilder :: !Ident - , bfDeps :: [FastString] - , bfArgs :: !Int - } deriving (Eq, Show) - -{- - Stack frame initialization order is important when code is reused: - all dependencies have to be ready when the closure is built. - - This function sorts the initializers and returns an additional list - of cycle breakers, which are built in a two-step fashion - -} -sortBuildFunctions :: [BuildFunction] -> ([BuildFunction], [BuildFunction]) -sortBuildFunctions bfs = (map snd normBFs, map snd cbBFs) - where - (normBFs, cbBFs) = List.partition (not.fst) . concatMap fromSCC $ sccs bfs - bfm :: UniqMap FastString BuildFunction - bfm = listToUniqMap (map (\x -> (bfName x, x)) bfs) - fromSCC :: G.SCC LexicalFastString -> [(Bool, BuildFunction)] - fromSCC (G.AcyclicSCC (LexicalFastString x)) = [(False, fromJust $ lookupUniqMap bfm x)] - fromSCC (G.CyclicSCC xs) = breakCycles $ map (\(LexicalFastString f) -> f) xs - sccs :: [BuildFunction] -> [G.SCC LexicalFastString] - sccs b = G.stronglyConnComp $ - map (\bf -> let n = bfName bf in (LexicalFastString n, LexicalFastString n, map LexicalFastString $ bfDeps bf)) b - {- - finding the maximum acyclic subgraph is the Minimum Feedback Arc Set problem, - which is NP-complete. We use an approximation here. - -} - breakCycles :: [FastString] -> [(Bool, BuildFunction)] - breakCycles nodes = - (True, fromJust $ lookupUniqMap bfm selected) - : concatMap fromSCC (sccs (map (fromJust . lookupUniqMap bfm) $ filter (/=selected) nodes)) - where - outDeg, inDeg :: UniqMap FastString Int - outDeg = listToUniqMap $ map (\n -> (n, length (bfDeps (fromJust $ lookupUniqMap bfm n)))) nodes - inDeg = listToUniqMap_C (+) (map (,1) . concatMap (bfDeps . (fromJust . lookupUniqMap bfm)) $ nodes) - -- ELS heuristic (Eades et. al.) - selected :: FastString - selected = List.maximumBy (compare `on` (\x -> fromJust (lookupUniqMap outDeg x) - fromJust (lookupUniqMap inDeg x))) nodes - -rewriteBodies :: UniqSet FastString - -> UniqMap FastString BS.ByteString - -> Map BS.ByteString (Int, [FastString]) - -> [LinkedUnit] - -> ([BuildFunction], [BuildFunction], [LinkedUnit]) -rewriteBodies globals idx1 idx2 input = (bfsNormal, bfsCycleBreaker, input') - where - (bfs1, input') = unzip (map rewriteBlock input) - (bfsNormal, bfsCycleBreaker) = sortBuildFunctions (concat bfs1) - - -- this index only contains the entries we actually want to dedupe - idx2' :: Map BS.ByteString (Int, [FastString]) - idx2' = M.filter (\(s, xs) -> dedupeBody (length xs) s) idx2 - - rewriteBlock :: LinkedUnit -> ([BuildFunction], LinkedUnit) - rewriteBlock (LinkedUnit st cis sis) = - let (bfs, st') = rewriteFunctions st - -- remove the declarations for things that we just deduped - st'' = removeDecls (mkUniqSet $ map bfName bfs) st' - in (bfs, LinkedUnit st'' cis sis) - - removeDecls :: UniqSet FastString -> JStat -> JStat - removeDecls t (BlockStat ss) = BlockStat (map (removeDecls t) ss) - removeDecls t (DeclStat (TxtI i) _) - | elementOfUniqSet i t = mempty - removeDecls _ s = s - - rewriteFunctions :: JStat -> ([BuildFunction], JStat) - rewriteFunctions (BlockStat ss) = - let (bfs, ss') = unzip (map rewriteFunctions ss) - in (concat bfs, BlockStat ss') - rewriteFunctions (AssignStat (ValExpr (JVar (TxtI i))) - (ValExpr (JFunc args st))) - | Just h <- lookupUniqMap idx1 i - , Just (_s, his) <- M.lookup h idx2' = - let (bf, st') = rewriteFunction i h his args st in ([bf], st') - rewriteFunctions x = ([], x) - - rewriteFunction :: FastString - -> BS.ByteString - -> [FastString] - -> [Ident] - -> JStat - -> (BuildFunction, JStat) - rewriteFunction i h his args body - | i == iFirst = (bf, createFunction i idx g args body) - | otherwise = (bf, mempty) - where - bf :: BuildFunction - bf = BuildFunction i (buildFunId idx) g (length args) - g :: [FastString] - g = findGlobals globals body - iFirst = head his - Just idx = M.lookupIndex h idx2' - - createFunction :: FastString - -> Int - -> [FastString] - -> [Ident] - -> JStat - -> JStat - createFunction _i idx g args body = - bi ||= ValExpr (JFunc bargs bbody) - where - ng = length g - bi = buildFunId idx - bargs :: [Ident] - bargs = map (TxtI . mkFastString . ("h$$$g"++) . show) [1..ng] - bgm :: UniqMap FastString Ident - bgm = listToUniqMap (zip g bargs) - bbody :: JStat - bbody = ReturnStat (ValExpr $ JFunc args ibody) - ibody :: JStat - ibody = identsS' (\ti@(TxtI i) -> fromMaybe ti (lookupUniqMap bgm i)) body - -renderBuildFunction :: BuildFunction -> JStat -renderBuildFunction (BuildFunction i bfid deps _nargs) = - (TxtI i) ||= (ApplExpr (ValExpr (JVar bfid)) (map (ValExpr . JVar . TxtI) deps)) - -dedupeBody :: Int -> Int -> Bool -dedupeBody n size - | n < 2 = False - | size * n > 200 = True - | n > 6 = True - | otherwise = False - -buildFunId :: Int -> Ident -buildFunId i = TxtI (mkFastString $ "h$$$f" ++ show i) - --- result is ordered, does not contain duplicates -findGlobals :: UniqSet FastString -> JStat -> [FastString] -findGlobals globals stat = filter isGlobal . map itxt . uniqDSetToList $ identsS stat - where - locals = mkUniqSet (findLocals stat) - isGlobal i = elementOfUniqSet i globals && not (elementOfUniqSet i locals) - -findLocals :: JStat -> [FastString] -findLocals (BlockStat ss) = concatMap findLocals ss -findLocals (DeclStat (TxtI i) _) = [i] -findLocals _ = [] - - -data HashIdx = HashIdx (UniqMap FastString Hash) (Map Hash FastString) - - -dedupe :: [FastString] - -> [LinkedUnit] - -> [LinkedUnit] -dedupe rtsDeps input --- | dumpHashIdx idx - = - map (dedupeBlock idx) input - where - idx = HashIdx hashes hr - hashes0 = buildHashes rtsDeps input - hashes = List.foldl' delFromUniqMap hashes0 rtsDeps - -- Adding to a map, and selecting a deterministic element on overlapping keys - -- using pickShortest avoids the non-determinism introduced by nonDetEltsUniqMap. - hr = M.fromListWith pickShortest $ - map (\(i, h) -> (h, i)) (nonDetEltsUniqMap hashes) - pickShortest :: FastString -> FastString -> FastString - pickShortest x y - | x == y = x - | lengthFS x < lengthFS y = x - | lengthFS x > lengthFS y = y - | LexicalFastString x < LexicalFastString y = x -- these are the same length, so pick the - | otherwise = y -- lexically first one for determinism - - -dedupeBlock :: HashIdx - -> LinkedUnit - -> LinkedUnit -dedupeBlock hi (LinkedUnit st ci si) = LinkedUnit - { lu_js_code = dedupeStat hi st - , lu_closures = mapMaybe (dedupeClosureInfo hi) ci - , lu_statics = mapMaybe (dedupeStaticInfo hi) si - } - -dedupeStat :: HashIdx -> JStat -> JStat -dedupeStat hi = go - where - go (BlockStat ss) = BlockStat (map go ss) - go s@(DeclStat (TxtI i) _) - | not (isCanon hi i) = mempty - | otherwise = s - go (AssignStat v@(ValExpr (JVar (TxtI i))) e) - | not (isCanon hi i) = mempty - | otherwise = AssignStat v (identsE' (toCanonI hi) e) - -- rewrite identifiers in e - go s = identsS' (toCanonI hi) s - -dedupeClosureInfo :: HashIdx -> ClosureInfo -> Maybe ClosureInfo -dedupeClosureInfo hi (ClosureInfo i rs n l ty st) - | isCanon hi i = Just (ClosureInfo i rs n l ty (dedupeCIStatic hi st)) -dedupeClosureInfo _ _ = Nothing - -dedupeStaticInfo :: HashIdx -> StaticInfo -> Maybe StaticInfo -dedupeStaticInfo hi (StaticInfo i val ccs) - | isCanon hi i = Just (StaticInfo i (dedupeStaticVal hi val) ccs) -dedupeStaticInfo _ _ = Nothing - -dedupeCIStatic :: HashIdx -> CIStatic -> CIStatic -dedupeCIStatic hi (CIStaticRefs refs) = CIStaticRefs (List.nub $ map (toCanon hi) refs) - -dedupeStaticVal :: HashIdx -> StaticVal -> StaticVal -dedupeStaticVal hi (StaticFun t args) = - StaticFun (toCanon hi t) (map (dedupeStaticArg hi) args) -dedupeStaticVal hi (StaticThunk (Just (o, args))) = - StaticThunk (Just (toCanon hi o, map (dedupeStaticArg hi) args)) -dedupeStaticVal hi (StaticData dcon args) = - StaticData (toCanon hi dcon) (map (dedupeStaticArg hi) args) -dedupeStaticVal hi (StaticList args lt) = - StaticList (map (dedupeStaticArg hi) args) (fmap (toCanon hi) lt) -dedupeStaticVal _ v = v -- unboxed value or thunk with alt init, no rewrite needed - -dedupeStaticArg :: HashIdx -> StaticArg -> StaticArg -dedupeStaticArg hi (StaticObjArg o) - = StaticObjArg (toCanon hi o) -dedupeStaticArg hi (StaticConArg c args) - = StaticConArg (toCanon hi c) - (map (dedupeStaticArg hi) args) -dedupeStaticArg _hi a at StaticLitArg{} = a - -isCanon :: HashIdx -> FastString -> Bool -isCanon (HashIdx a b) t - | Nothing <- la = True - | Just h <- la - , Just t' <- M.lookup h b = t == t' - | otherwise = False - where la = lookupUniqMap a t - -toCanon :: HashIdx -> FastString -> FastString -toCanon (HashIdx a b) t - | Just h <- lookupUniqMap a t - , Just t' <- M.lookup h b = t' - | otherwise = t - -toCanonI :: HashIdx -> Ident -> Ident -toCanonI hi (TxtI x) = TxtI $ toCanon hi x - -type Hash = (BS.ByteString, [LexicalFastString]) - -data HashBuilder = HashBuilder !BB.Builder ![FastString] - -instance Monoid HashBuilder where - mempty = HashBuilder mempty mempty - -instance Semigroup HashBuilder where - (<>) (HashBuilder b1 l1) (HashBuilder b2 l2) = - HashBuilder (b1 <> b2) (l1 <> l2) - -{- -dumpHashIdx :: HashIdx -> Bool -dumpHashIdx hi@(HashIdx ma mb) = - let ks = M.keys ma - difCanon i = let i' = toCanon hi i - in if i == i' then Nothing else Just i' - writeHashIdx = do - putStrLn "writing hash idx" - T.writeFile "hashidx.txt" - (T.unlines . sort $ mapMaybe (\i -> fmap ((i <> " -> ") <>) (difCanon i)) ks) - putStrLn "writing full hash idx" - T.writeFile "hashIdxFull.txt" - (T.unlines . sort $ M.keys ma) - in unsafePerformIO writeHashIdx `seq` True --} --- debug thing -{- -dumpHashes' :: [(JStat, [ClosureInfo], [StaticInfo])] -> Bool -dumpHashes' input = - let hashes = buildHashes input - writeHashes = do - putStrLn "writing hashes" - BL.writeFile "hashes.json" (Aeson.encode $ dumpHashes hashes) - in unsafePerformIO writeHashes `seq` True --} -buildHashes :: [FastString] -> [LinkedUnit] -> UniqMap FastString Hash -buildHashes rtsDeps xss - -- - | dumpHashes0 hashes0 - = fixHashes (mapUniqMap finalizeHash hashes0) - where - globals = List.foldl' delOneFromUniqSet (findAllGlobals xss) rtsDeps - hashes0 = foldl plusUniqMap emptyUniqMap (map buildHashesBlock xss) - buildHashesBlock (LinkedUnit st cis sis) = - let hdefs = hashDefinitions globals st - hcis = map hashClosureInfo cis - hsis = map hashStaticInfo (filter (not . ignoreStatic) sis) - in listToUniqMap (combineHashes hdefs hcis ++ hsis) - -findAllGlobals :: [LinkedUnit] -> UniqSet FastString -findAllGlobals xss = mkUniqSet $ concatMap f xss - where - f (LinkedUnit _js_code closures statics) = - map (\(ClosureInfo i _ _ _ _ _) -> i) closures ++ - map (\(StaticInfo i _ _) -> i) statics - -fixHashes :: UniqMap FastString Hash -> UniqMap FastString Hash -fixHashes hashes = fmap (second (map replaceHash)) hashes - where - replaceHash :: LexicalFastString -> LexicalFastString - replaceHash h'@(LexicalFastString h) = maybe h' (LexicalFastString . mkFastString) (lookupUniqMap finalHashes h) - hashText bs = "h$$$" <> utf8DecodeByteString bs - sccs :: [[FastString]] - sccs = map fromSCC $ - G.stronglyConnComp (map (\(k, (_bs, deps)) -> (k, LexicalFastString k, deps)) kvs) - kvs = List.sortOn (LexicalFastString . fst) $ nonDetEltsUniqMap hashes -- sort lexically to avoid non-determinism - ks = fst $ unzip kvs - invDeps = listToUniqMap_C (++) (concatMap mkInvDeps kvs) - mkInvDeps (k, (_, ds)) = map (\(LexicalFastString d) -> (d,[k])) ds - finalHashes = fmap hashText (fixHashesIter 500 invDeps ks ks sccs hashes mempty) - -fromSCC :: G.SCC a -> [a] -fromSCC (G.AcyclicSCC x) = [x] -fromSCC (G.CyclicSCC xs) = xs - -fixHashesIter :: Int - -> UniqMap FastString [FastString] - -> [FastString] - -> [FastString] - -> [[FastString]] - -> UniqMap FastString Hash - -> UniqMap FastString BS.ByteString - -> UniqMap FastString BS.ByteString -fixHashesIter n invDeps allKeys checkKeys sccs hashes finalHashes - -- - | unsafePerformIO (putStrLn ("fixHashesIter: " ++ show n)) `seq` False = undefined - | n < 0 = finalHashes - | not (null newHashes) = fixHashesIter (n-1) invDeps allKeys checkKeys' sccs hashes - (addListToUniqMap finalHashes newHashes) - -- - | unsafePerformIO (putStrLn ("fixHashesIter killing cycles:\n" ++ show rootSCCs)) `seq` False = undefined - | not (null rootSCCs) = fixHashesIter n {- -1 -} invDeps allKeys allKeys sccs hashes - (addListToUniqMap finalHashes (concatMap hashRootSCC rootSCCs)) - | otherwise = finalHashes - where - checkKeys' | length newHashes > sizeUniqMap hashes `div` 10 = allKeys - | otherwise = uniqDSetToList . mkUniqDSet $ concatMap (newHashDeps) newHashes - newHashDeps :: (FastString, BSC.ByteString) -> [FastString] - newHashDeps (k, _) = fromMaybe [] (lookupUniqMap invDeps k) - mkNewHash k | not $ elemUniqMap k finalHashes - , Just (hb, htxt) <- lookupUniqMap hashes k - , Just bs <- mapM (\(LexicalFastString ht) -> lookupUniqMap finalHashes ht) htxt = - Just (k, makeFinalHash hb bs) - | otherwise = Nothing - newHashes :: [(FastString, BS.ByteString)] - newHashes = mapMaybe mkNewHash checkKeys - rootSCCs :: [[FastString]] - rootSCCs = filter isRootSCC sccs - isRootSCC :: [FastString] -> Bool - isRootSCC scc = not (all (`elemUniqMap` finalHashes) scc) && all check scc - where - check n = let Just (_bs, out) = lookupUniqMap hashes n - in all checkEdge out - checkEdge (LexicalFastString e) = e `elementOfUniqSet` s || e `elemUniqMap` finalHashes - s = mkUniqSet scc - hashRootSCC :: [FastString] -> [(FastString,BS.ByteString)] - hashRootSCC scc - | any (`elemUniqMap` finalHashes) scc = panic "Gen2.Compactor.hashRootSCC: has finalized nodes" - | otherwise = map makeHash toHash - where - makeHash k = let Just (bs,deps) = lookupUniqMap hashes k - luds = map lookupDep deps - in (k, makeFinalHash bs luds) - lookupDep :: LexicalFastString -> BS.ByteString - lookupDep (LexicalFastString d) - | Just b <- lookupUniqMap finalHashes d = b - | Just i <- lookupUniqMap toHashIdx d - = grpHash <> (utf8EncodeByteString . show $ i) - | otherwise - = panic $ "Gen2.Compactor.hashRootSCC: unknown key: " ++ - unpackFS d - toHashIdx :: UniqMap FastString Integer - toHashIdx = listToUniqMap $ zip toHash [1..] - grpHash :: BS.ByteString - grpHash = BL.toStrict - . BB.toLazyByteString - $ mconcat (map (mkGrpHash . fromJust . lookupUniqMap hashes) toHash) - mkGrpHash (h, deps) = - let deps' = mapMaybe (\(LexicalFastString d) -> lookupUniqMap finalHashes d) deps - in BB.byteString h <> - BB.int64LE (fromIntegral $ length deps') <> - mconcat (map BB.byteString deps') - toHash :: [FastString] - toHash = List.sortBy (compare `on` fst . (fromJust . lookupUniqMap hashes)) scc - -makeFinalHash :: BS.ByteString -> [BS.ByteString] -> BS.ByteString -makeFinalHash b bs = mconcat (b:bs) - --- do not deduplicate thunks -ignoreStatic :: StaticInfo -> Bool -ignoreStatic (StaticInfo _ StaticThunk {} _) = True -ignoreStatic _ = False - --- combine hashes from x and y, leaving only those which have an entry in both -combineHashes :: [(FastString, HashBuilder)] - -> [(FastString, HashBuilder)] - -> [(FastString, HashBuilder)] -combineHashes x y = map unlexical . M.toList $ M.intersectionWith (<>) - (M.fromList $ map lexical x) - (M.fromList $ map lexical y) - where - lexical (f, x) = (LexicalFastString f, x) - unlexical (LexicalFastString f, x) = (f, x) - -{- -dumpHashes0 :: Map ShortText HashBuilder -> Bool -dumpHashes0 hashes = unsafePerformIO writeHashes `seq` True - where - hashLine (n, HashBuilder bb txt) = - n <> " ->\n " <> - escapeBS (BB.toLazyByteString bb) <> "\n [" <> T.intercalate " " txt <> "]\n" - escapeBS :: BL.ByteString -> T.Text - escapeBS = mkFastString . concatMap escapeCH . BL.unpack - escapeCH c | c < 32 || c > 127 = '\\' : show c - | c == 92 = "\\\\" - | otherwise = [chr (fromIntegral c)] - - writeHashes = do - putStrLn "writing hashes0" - T.writeFile "hashes0.dump" (T.unlines $ map hashLine (M.toList hashes)) - -dumpHashes :: Map ShortText Hash -> Value -dumpHashes idx = toJSON iidx - where - iidx :: Map ShortText [(Text, [ShortText])] - iidx = M.fromListWith (++) $ - map (\(t, (b, deps)) -> (TE.decodeUtf8 (B16.encode b), [(t,deps)])) (M.toList idx) --} - -ht :: Int8 -> HashBuilder -ht x = HashBuilder (BB.int8 x) [] - -hi :: Int -> HashBuilder -hi x = HashBuilder (BB.int64LE $ fromIntegral x) [] - -hi' :: (Show a, Integral a) => a -> HashBuilder -hi' x | x' > toInteger (maxBound :: Int64) || x' < toInteger (minBound :: Int64) = - panic $ "Gen2.Compactor.hi': integer out of range: " ++ show x - | otherwise = HashBuilder (BB.int64LE $ fromInteger x') [] - where - x' = toInteger x - -hd :: Double -> HashBuilder -hd d = HashBuilder (BB.doubleLE d) [] - -htxt :: FastString -> HashBuilder -htxt x = HashBuilder (BB.int64LE (fromIntegral $ BS.length bs) <> BB.byteString bs) [] - where - bs = utf8EncodeByteString $ unpackFS x - -hobj :: FastString -> HashBuilder -hobj x = HashBuilder (BB.int8 127) [x] - -hb :: BS.ByteString -> HashBuilder -hb x = HashBuilder (BB.int64LE (fromIntegral $ BS.length x) <> BB.byteString x) [] - -hashDefinitions :: UniqSet FastString -> JStat -> [(FastString, HashBuilder)] -hashDefinitions globals st = - let defs = findDefinitions st - in map (uncurry (hashSingleDefinition globals)) defs - -findDefinitions :: JStat -> [(Ident, JExpr)] -findDefinitions (BlockStat ss) = concatMap findDefinitions ss -findDefinitions (AssignStat (ValExpr (JVar i)) e) = [(i,e)] -findDefinitions _ = [] - -hashSingleDefinition :: UniqSet FastString -> Ident -> JExpr -> (FastString, HashBuilder) -hashSingleDefinition globals (TxtI i) expr = (i, ht 0 <> render st <> mconcat (map hobj globalRefs)) - where - globalRefs = filter (`elementOfUniqSet` globals) . map itxt $ uniqDSetToList (identsE expr) - globalMap = listToUniqMap $ zip globalRefs (map (mkFastString . ("h$$$global_"++) . show) [(1::Int)..]) - expr' = identsE' (\i@(TxtI t) -> maybe i TxtI (lookupUniqMap globalMap t)) expr - st = AssignStat (ValExpr (JVar (TxtI "dummy"))) expr' - render = htxt . mkFastString. show . pretty - - -identsE' :: (Ident -> Ident) -> JExpr -> JExpr -identsE' f (ValExpr v) = ValExpr $! identsV' f v -identsE' f (SelExpr e i) = SelExpr (identsE' f e) i -- do not rename properties -identsE' f (IdxExpr e1 e2) = IdxExpr (identsE' f e1) (identsE' f e2) -identsE' f (InfixExpr s e1 e2) = InfixExpr s (identsE' f e1) (identsE' f e2) -identsE' f (UOpExpr o e) = UOpExpr o $! identsE' f e -identsE' f (IfExpr e1 e2 e3) = IfExpr (identsE' f e1) (identsE' f e2) (identsE' f e3) -identsE' f (ApplExpr e es) = ApplExpr (identsE' f e) (identsE' f <$> es) -identsE' _ UnsatExpr{} = error "identsE': UnsatExpr" - -identsV' :: (Ident -> Ident) -> JVal -> JVal -identsV' f (JVar i) = JVar $! f i -identsV' f (JList xs) = JList $! (fmap . identsE') f xs -identsV' _ d at JDouble{} = d -identsV' _ i at JInt{} = i -identsV' _ s at JStr{} = s -identsV' _ r at JRegEx{} = r -identsV' f (JHash m) = JHash $! (fmap . identsE') f m -identsV' f (JFunc args s) = JFunc (fmap f args) (identsS' f s) -identsV' _ UnsatVal{} = error "identsV': UnsatVal" - -identsS' :: (Ident -> Ident) -> JStat -> JStat -identsS' f (DeclStat i e) = DeclStat (f i) e -identsS' f (ReturnStat e) = ReturnStat $! identsE' f e -identsS' f (IfStat e s1 s2) = IfStat (identsE' f e) (identsS' f s1) (identsS' f s2) -identsS' f (WhileStat b e s) = WhileStat b (identsE' f e) (identsS' f s) -identsS' f (ForInStat b i e s) = ForInStat b (f i) (identsE' f e) (identsS' f s) -identsS' f (SwitchStat e xs s) = SwitchStat (identsE' f e) (fmap (traverseCase f) xs) (identsS' f s) - where traverseCase g (e,s) = (identsE' g e, identsS' g s) -identsS' f (TryStat s1 i s2 s3) = TryStat (identsS' f s1) (f i) (identsS' f s2) (identsS' f s3) -identsS' f (BlockStat xs) = BlockStat $! identsS' f <$> xs -identsS' f (ApplStat e es) = ApplStat (identsE' f e) (identsE' f <$> es) -identsS' f (UOpStat op e) = UOpStat op $! identsE' f e -identsS' f (AssignStat e1 e2) = AssignStat (identsE' f e1) (identsE' f e2) -identsS' _ UnsatBlock{} = error "identsS': UnsatBlock" -identsS' f (LabelStat l s) = LabelStat l $! identsS' f s -identsS' _ b at BreakStat{} = b -identsS' _ c at ContinueStat{} = c - -hashClosureInfo :: ClosureInfo -> (FastString, HashBuilder) -hashClosureInfo (ClosureInfo civ cir _cin cil cit cis) = - (civ, ht 1 <> hashCIRegs cir <> hashCILayout cil <> hashCIType cit <> hashCIStatic cis) - -hashStaticInfo :: StaticInfo -> (FastString, HashBuilder) -hashStaticInfo (StaticInfo sivr sivl _sicc) = - (sivr, ht 2 <> hashStaticVal sivl) - -hashCIType :: CIType -> HashBuilder -hashCIType (CIFun a r) = ht 1 <> hi a <> hi r -hashCIType CIThunk = ht 2 -hashCIType (CICon c) = ht 3 <> hi c -hashCIType CIPap = ht 4 -hashCIType CIBlackhole = ht 5 -hashCIType CIStackFrame = ht 6 - - -hashCIRegs :: CIRegs -> HashBuilder -hashCIRegs CIRegsUnknown = ht 1 -hashCIRegs (CIRegs sk tys) = ht 2 <> hi sk <> hashList hashVT tys - -hashCILayout :: CILayout -> HashBuilder -hashCILayout CILayoutVariable = ht 1 -hashCILayout (CILayoutUnknown size) = ht 2 <> hi size -hashCILayout (CILayoutFixed n l) = ht 3 <> hi n <> hashList hashVT l - -hashCIStatic :: CIStatic -> HashBuilder -hashCIStatic CIStaticRefs{} = mempty -- hashList hobj xs -- we get these from the code - -hashList :: (a -> HashBuilder) -> [a] -> HashBuilder -hashList f xs = hi (length xs) <> mconcat (map f xs) - -hashVT :: VarType -> HashBuilder -hashVT = hi . fromEnum - -hashStaticVal :: StaticVal -> HashBuilder -hashStaticVal (StaticFun t args) = ht 1 <> hobj t <> hashList hashStaticArg args -hashStaticVal (StaticThunk mtn) = ht 2 <> hashMaybe htobj mtn - where - htobj (o, args) = hobj o <> hashList hashStaticArg args -hashStaticVal (StaticUnboxed su) = ht 3 <> hashStaticUnboxed su -hashStaticVal (StaticData dcon args) = ht 4 <> hobj dcon <> hashList hashStaticArg args -hashStaticVal (StaticList args lt) = ht 5 <> hashList hashStaticArg args <> hashMaybe hobj lt - -hashMaybe :: (a -> HashBuilder) -> Maybe a -> HashBuilder -hashMaybe _ Nothing = ht 1 -hashMaybe f (Just x) = ht 2 <> f x - -hashStaticUnboxed :: StaticUnboxed -> HashBuilder -hashStaticUnboxed (StaticUnboxedBool b) = ht 1 <> hi (fromEnum b) -hashStaticUnboxed (StaticUnboxedInt iv) = ht 2 <> hi' iv -hashStaticUnboxed (StaticUnboxedDouble sd) = ht 3 <> hashSaneDouble sd -hashStaticUnboxed (StaticUnboxedString str) = ht 4 <> hb str -hashStaticUnboxed (StaticUnboxedStringOffset str) = ht 5 <> hb str - - -hashStaticArg :: StaticArg -> HashBuilder -hashStaticArg (StaticObjArg t) = ht 1 <> hobj t -hashStaticArg (StaticLitArg sl) = ht 2 <> hashStaticLit sl -hashStaticArg (StaticConArg cn args) = ht 3 <> hobj cn <> hashList hashStaticArg args - -hashStaticLit :: StaticLit -> HashBuilder -hashStaticLit (BoolLit b) = ht 1 <> hi (fromEnum b) -hashStaticLit (IntLit iv) = ht 2 <> hi (fromIntegral iv) -hashStaticLit NullLit = ht 3 -hashStaticLit (DoubleLit d) = ht 4 <> hashSaneDouble d -hashStaticLit (StringLit tt) = ht 5 <> htxt tt -hashStaticLit (BinLit bs) = ht 6 <> hb bs -hashStaticLit (LabelLit bb ln) = ht 7 <> hi (fromEnum bb) <> htxt ln - -hashSaneDouble :: SaneDouble -> HashBuilder -hashSaneDouble (SaneDouble sd) = hd sd - -finalizeHash :: HashBuilder -> Hash -finalizeHash (HashBuilder hb tt) = - let h = (BL.toStrict $ BB.toLazyByteString hb) - in h `seq` (h, map LexicalFastString tt) - -finalizeHash' :: HashBuilder -> (Int, BS.ByteString, [FastString]) -finalizeHash' (HashBuilder hb tt) = - let b = BL.toStrict (BB.toLazyByteString hb) - bl = BS.length b - h = b - in h `seq` bl `seq` (bl, h, tt) ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -30,6 +30,7 @@ import Prelude import GHC.Platform.Host (hostPlatformArchOS) +import GHC.JS.Make import GHC.JS.Syntax import GHC.Driver.Session (DynFlags(..)) @@ -41,12 +42,15 @@ import GHC.Linker.Static.Utils (exeFileName) import GHC.StgToJS.Linker.Types import GHC.StgToJS.Linker.Utils -import GHC.StgToJS.Linker.Compactor import GHC.StgToJS.Rts.Rts import GHC.StgToJS.Object import GHC.StgToJS.Types hiding (LinkableUnit) import GHC.StgToJS.UnitUtils import GHC.StgToJS.Printer +import GHC.StgToJS.Arg +import GHC.StgToJS.Closure + +import GHC.Types.Unique.Map import GHC.Unit.State import GHC.Unit.Env @@ -63,6 +67,9 @@ import GHC.Utils.Binary import qualified GHC.Utils.Ppr as Ppr import GHC.Utils.Monad import GHC.Utils.TmpFs +import GHC.Utils.Misc +import GHC.Utils.Monad.State.Strict (State, runState) +import qualified GHC.Utils.Monad.State.Strict as State import qualified GHC.SysTools.Ar as Ar @@ -76,12 +83,13 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy.Char8 as BLC import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString as BS import Data.Function (on) import Data.IntSet (IntSet) import qualified Data.IntSet as IS import Data.IORef import Data.List ( partition, nub, intercalate, group, sort - , groupBy, intersperse + , groupBy, intersperse, ) import Data.Map.Strict (Map) import qualified Data.Map.Strict as M @@ -157,7 +165,7 @@ link lc_cfg cfg logger unit_env out _include units objFiles jsFiles isRootFun ex -- link all Haskell code (program + dependencies) into out.js -- compute dependencies - (dep_map, dep_units, all_deps, rts_wired_functions, dep_archives) + (dep_map, dep_units, all_deps, _rts_wired_functions, dep_archives) <- computeLinkDependencies cfg logger out unit_env units objFiles extraStaticDeps isRootFun -- retrieve code for dependencies @@ -165,7 +173,7 @@ link lc_cfg cfg logger unit_env out _include units objFiles jsFiles isRootFun ex -- LTO + rendering of JS code link_stats <- withBinaryFile (out "out.js") WriteMode $ \h -> do - (_compactorState, stats) <- renderLinker lc_cfg cfg h emptyCompactorState rts_wired_functions mods jsFiles + (_compactorState, stats) <- renderLinker cfg h emptyCompactorState mods jsFiles pure stats ------------------------------------------------------------- @@ -282,15 +290,13 @@ data ModuleCode = ModuleCode } renderLinker - :: JSLinkConfig - -> StgToJSConfig + :: StgToJSConfig -> Handle -> CompactorState - -> Set ExportedFun -> [ModuleCode] -- ^ linked code per module -> [FilePath] -- ^ additional JS files -> IO (CompactorState, LinkerStats) -renderLinker settings cfg h renamer_state rtsDeps mods jsFiles = do +renderLinker cfg h renamer_state mods jsFiles = do -- extract ModuleCode fields required to make a LinkedUnit let code_to_linked_unit c = LinkedUnit @@ -300,9 +306,7 @@ renderLinker settings cfg h renamer_state rtsDeps mods jsFiles = do } -- call the compactor - let (renamer_state', compacted, meta) = compact settings cfg renamer_state - (map ((\(LexicalFastString f) -> f) . funSymbol) $ S.toList rtsDeps) - (map code_to_linked_unit mods) + let (renamer_state', compacted, meta) = rename cfg renamer_state (map code_to_linked_unit mods) let putBS = B.hPut h @@ -860,3 +864,155 @@ jsFileNeedsCpp :: FilePath -> IO Bool jsFileNeedsCpp fn = do opts <- getOptionsFromJsFile fn pure (CPP `elem` opts) + +rename :: StgToJSConfig + -> CompactorState + -> [LinkedUnit] + -> (CompactorState, [JStat], JStat) +rename cfg cs0 input0 + = renameInternals cfg cs0 input0 + +renameInternals :: HasDebugCallStack + => StgToJSConfig + -> CompactorState + -> [LinkedUnit] + -> (CompactorState, [JStat], JStat) +renameInternals cfg cs0 stats0a = (cs, stats, meta) + where + (stbs, stats0) = (mempty, stats0a) + ((stats, meta), cs) = runState renamed cs0 + + renamed :: State CompactorState ([JStat], JStat) + renamed + + | True = do + cs <- State.get + let renamedStats = map (identsS' (lookupRenamed cs) . lu_js_code) stats0 + statics = map (renameStaticInfo cs) $ + concatMap lu_statics stats0 + infos = map (renameClosureInfo cs) $ + concatMap lu_closures stats0 + -- render metadata as individual statements + meta = mconcat (map staticDeclStat statics) <> + identsS' (lookupRenamed cs) stbs <> + mconcat (map (staticInitStat $ csProf cfg) statics) <> + mconcat (map (closureInfoStat True) infos) + return (renamedStats, meta) + +lookupRenamed :: CompactorState -> Ident -> Ident +lookupRenamed cs i@(TxtI t) = + fromMaybe i (lookupUniqMap (csNameMap cs) t) + +-- | rename a compactor info entry according to the compactor state (no new renamings are added) +renameClosureInfo :: CompactorState + -> ClosureInfo + -> ClosureInfo +renameClosureInfo cs (ClosureInfo v rs n l t s) = + ClosureInfo (renameV v) rs n l t (f s) + where + renameV t = maybe t itxt (lookupUniqMap m t) + m = csNameMap cs + f (CIStaticRefs rs) = CIStaticRefs (map renameV rs) + +-- | rename a static info entry according to the compactor state (no new renamings are added) +renameStaticInfo :: CompactorState + -> StaticInfo + -> StaticInfo +renameStaticInfo cs = staticIdents renameIdent + where + renameIdent t = maybe t itxt (lookupUniqMap (csNameMap cs) t) + +-- | initialize a global object. all global objects have to be declared (staticInfoDecl) first +-- (this is only used with -debug, normal init would go through the static data table) +staticInitStat :: Bool -- ^ profiling enabled + -> StaticInfo + -> JStat +staticInitStat _prof (StaticInfo i sv cc) = + case sv of + StaticData con args -> appS "h$sti" ([var i, var con, jsStaticArgs args] ++ ccArg) + StaticFun f args -> appS "h$sti" ([var i, var f, jsStaticArgs args] ++ ccArg) + StaticList args mt -> + appS "h$stl" ([var i, jsStaticArgs args, toJExpr $ maybe null_ (toJExpr . TxtI) mt] ++ ccArg) + StaticThunk (Just (f,args)) -> + appS "h$stc" ([var i, var f, jsStaticArgs args] ++ ccArg) + _ -> mempty + where + ccArg = maybeToList (fmap toJExpr cc) + +staticIdents :: (FastString -> FastString) + -> StaticInfo + -> StaticInfo +staticIdents f (StaticInfo i v cc) = StaticInfo (f i) (staticIdentsV f v) cc + +staticIdentsV ::(FastString -> FastString) -> StaticVal -> StaticVal +staticIdentsV f (StaticFun i args) = StaticFun (f i) (staticIdentsA f <$> args) +staticIdentsV f (StaticThunk (Just (i, args))) = StaticThunk . Just $ + (f i, staticIdentsA f <$> args) +staticIdentsV f (StaticData con args) = StaticData (f con) (staticIdentsA f <$> args) +staticIdentsV f (StaticList xs t) = StaticList (staticIdentsA f <$> xs) (f <$> t) +staticIdentsV _ x = x + +staticIdentsA :: (FastString -> FastString) -> StaticArg -> StaticArg +staticIdentsA f (StaticObjArg t) = StaticObjArg $! f t +staticIdentsA _ x = x + +-- | declare and do first-pass init of a global object (create JS object for heap objects) +staticDeclStat :: StaticInfo -> JStat +staticDeclStat (StaticInfo global_name static_value _) = decl + where + global_ident = TxtI global_name + decl_init v = global_ident ||= v + decl_no_init = appS "h$di" [toJExpr global_ident] + + decl = case static_value of + StaticUnboxed u -> decl_init (unboxed_expr u) + StaticThunk Nothing -> decl_no_init -- CAF initialized in an alternative way + _ -> decl_init (app "h$d" []) + + unboxed_expr = \case + StaticUnboxedBool b -> app "h$p" [toJExpr b] + StaticUnboxedInt i -> app "h$p" [toJExpr i] + StaticUnboxedDouble d -> app "h$p" [toJExpr (unSaneDouble d)] + StaticUnboxedString str -> app "h$rawStringData" [ValExpr (to_byte_list str)] + StaticUnboxedStringOffset {} -> 0 + + to_byte_list = JList . map (Int . fromIntegral) . BS.unpack + +identsE' :: (Ident -> Ident) -> JExpr -> JExpr +identsE' f (ValExpr v) = ValExpr $! identsV' f v +identsE' f (SelExpr e i) = SelExpr (identsE' f e) i -- do not rename properties +identsE' f (IdxExpr e1 e2) = IdxExpr (identsE' f e1) (identsE' f e2) +identsE' f (InfixExpr s e1 e2) = InfixExpr s (identsE' f e1) (identsE' f e2) +identsE' f (UOpExpr o e) = UOpExpr o $! identsE' f e +identsE' f (IfExpr e1 e2 e3) = IfExpr (identsE' f e1) (identsE' f e2) (identsE' f e3) +identsE' f (ApplExpr e es) = ApplExpr (identsE' f e) (identsE' f <$> es) +identsE' _ UnsatExpr{} = error "identsE': UnsatExpr" + +identsV' :: (Ident -> Ident) -> JVal -> JVal +identsV' f (JVar i) = JVar $! f i +identsV' f (JList xs) = JList $! (fmap . identsE') f xs +identsV' _ d at JDouble{} = d +identsV' _ i at JInt{} = i +identsV' _ s at JStr{} = s +identsV' _ r at JRegEx{} = r +identsV' f (JHash m) = JHash $! (fmap . identsE') f m +identsV' f (JFunc args s) = JFunc (fmap f args) (identsS' f s) +identsV' _ UnsatVal{} = error "identsV': UnsatVal" + +identsS' :: (Ident -> Ident) -> JStat -> JStat +identsS' f (DeclStat i e) = DeclStat (f i) e +identsS' f (ReturnStat e) = ReturnStat $! identsE' f e +identsS' f (IfStat e s1 s2) = IfStat (identsE' f e) (identsS' f s1) (identsS' f s2) +identsS' f (WhileStat b e s) = WhileStat b (identsE' f e) (identsS' f s) +identsS' f (ForInStat b i e s) = ForInStat b (f i) (identsE' f e) (identsS' f s) +identsS' f (SwitchStat e xs s) = SwitchStat (identsE' f e) (fmap (traverseCase f) xs) (identsS' f s) + where traverseCase g (e,s) = (identsE' g e, identsS' g s) +identsS' f (TryStat s1 i s2 s3) = TryStat (identsS' f s1) (f i) (identsS' f s2) (identsS' f s3) +identsS' f (BlockStat xs) = BlockStat $! identsS' f <$> xs +identsS' f (ApplStat e es) = ApplStat (identsE' f e) (identsE' f <$> es) +identsS' f (UOpStat op e) = UOpStat op $! identsE' f e +identsS' f (AssignStat e1 e2) = AssignStat (identsE' f e1) (identsE' f e2) +identsS' _ UnsatBlock{} = error "identsS': UnsatBlock" +identsS' f (LabelStat l s) = LabelStat l $! identsS' f s +identsS' _ b at BreakStat{} = b +identsS' _ c at ContinueStat{} = c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/89db61b634d3077e8ef9e99f73bc90f7ed5f2226 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/89db61b634d3077e8ef9e99f73bc90f7ed5f2226 You're receiving 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 Oct 14 13:17:57 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 09:17:57 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 2 commits: Linker: refactor and cleanup after compactor removal Message-ID: <634961856f2c5_8b90f5143c69368@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 21f88955 by Sylvain Henry at 2022-10-14T15:12:12+02:00 Linker: refactor and cleanup after compactor removal - - - - - 18a51ca6 by Sylvain Henry at 2022-10-14T15:15:06+02:00 Filter empty exports to avoid printing a lot of useless newlines - - - - - 3 changed files: - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Types.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -50,8 +50,6 @@ import GHC.StgToJS.Printer import GHC.StgToJS.Arg import GHC.StgToJS.Closure -import GHC.Types.Unique.Map - import GHC.Unit.State import GHC.Unit.Env import GHC.Unit.Home @@ -67,9 +65,6 @@ import GHC.Utils.Binary import qualified GHC.Utils.Ppr as Ppr import GHC.Utils.Monad import GHC.Utils.TmpFs -import GHC.Utils.Misc -import GHC.Utils.Monad.State.Strict (State, runState) -import qualified GHC.Utils.Monad.State.Strict as State import qualified GHC.SysTools.Ar as Ar @@ -172,9 +167,8 @@ link lc_cfg cfg logger unit_env out _include units objFiles jsFiles isRootFun ex mods <- collectDeps dep_map dep_units all_deps -- LTO + rendering of JS code - link_stats <- withBinaryFile (out "out.js") WriteMode $ \h -> do - (_compactorState, stats) <- renderLinker cfg h emptyCompactorState mods jsFiles - pure stats + link_stats <- withBinaryFile (out "out.js") WriteMode $ \h -> + renderLinker h mods jsFiles ------------------------------------------------------------- @@ -280,33 +274,36 @@ computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDep return (dep_map, dep_units, all_deps, rts_wired_functions, dep_archives) +-- | Compiled module data ModuleCode = ModuleCode { mc_module :: !Module - , mc_js_code :: JStat + , mc_js_code :: !JStat , mc_exports :: !B.ByteString -- ^ rendered exports , mc_closures :: ![ClosureInfo] , mc_statics :: ![StaticInfo] , mc_frefs :: ![ForeignJSRef] } +-- | ModuleCode after link with other modules. +-- +-- It contains less information than ModuleCode because they have been commoned +-- up into global "metadata" for the whole link. +data CompactedModuleCode = CompactedModuleCode + { cmc_module :: !Module + , cmc_js_code :: !JStat + , cmc_exports :: !B.ByteString -- ^ rendered exports + } + +-- | Link modules and pretty-print them into the given Handle renderLinker - :: StgToJSConfig - -> Handle - -> CompactorState + :: Handle -> [ModuleCode] -- ^ linked code per module -> [FilePath] -- ^ additional JS files - -> IO (CompactorState, LinkerStats) -renderLinker cfg h renamer_state mods jsFiles = do - - -- extract ModuleCode fields required to make a LinkedUnit - let code_to_linked_unit c = LinkedUnit - { lu_js_code = mc_js_code c - , lu_closures = mc_closures c - , lu_statics = mc_statics c - } + -> IO LinkerStats +renderLinker h mods jsFiles = do - -- call the compactor - let (renamer_state', compacted, meta) = rename cfg renamer_state (map code_to_linked_unit mods) + -- link modules + let (compacted_mods, meta) = linkModules mods let putBS = B.hPut h @@ -325,16 +322,16 @@ renderLinker cfg h renamer_state mods jsFiles = do -- file. -- modules themselves - mod_sizes <- forM (mods `zip` compacted) $ \(mod,compacted_mod) -> do - !mod_size <- fromIntegral <$> putJS compacted_mod - let !mod_mod = mc_module mod + mod_sizes <- forM compacted_mods $ \m -> do + !mod_size <- fromIntegral <$> putJS (cmc_js_code m) + let !mod_mod = cmc_module m pure (mod_mod, mod_size) - -- metadata + -- commoned up metadata !meta_length <- fromIntegral <$> putJS meta - -- exports - mapM_ (putBS . mc_exports) mods + -- module exports + mapM_ (putBS . cmc_exports) compacted_mods -- explicit additional JS files mapM_ (\i -> B.readFile i >>= putBS) jsFiles @@ -345,7 +342,7 @@ renderLinker cfg h renamer_state mods jsFiles = do , packedMetaDataSize = meta_length } - pure (renamer_state', link_stats) + pure link_stats -- | Render linker stats renderLinkerStats :: LinkerStats -> String @@ -568,11 +565,12 @@ extractDeps ar_state units deps loc = where mod = depsModule deps newline = BC.pack "\n" - unlines' = intersperse newline . map oiRaw + mk_exports = mconcat . intersperse newline . filter (not . BS.null) . map oiRaw + mk_js_code = mconcat . map oiStat collectCode l = ModuleCode { mc_module = mod - , mc_js_code = mconcat (map oiStat l) - , mc_exports = mconcat (unlines' l) + , mc_js_code = mk_js_code l + , mc_exports = mk_exports l , mc_closures = concatMap oiClInfo l , mc_statics = concatMap oiStatic l , mc_frefs = concatMap oiFImports l @@ -865,96 +863,68 @@ jsFileNeedsCpp fn = do opts <- getOptionsFromJsFile fn pure (CPP `elem` opts) -rename :: StgToJSConfig - -> CompactorState - -> [LinkedUnit] - -> (CompactorState, [JStat], JStat) -rename cfg cs0 input0 - = renameInternals cfg cs0 input0 - -renameInternals :: HasDebugCallStack - => StgToJSConfig - -> CompactorState - -> [LinkedUnit] - -> (CompactorState, [JStat], JStat) -renameInternals cfg cs0 stats0a = (cs, stats, meta) +-- | Link module codes. +-- +-- Performs link time optimizations and produces one JStat per module plus some +-- commoned up initialization code. +linkModules :: [ModuleCode] -> ([CompactedModuleCode], JStat) +linkModules mods = (compact_mods, meta) where - (stbs, stats0) = (mempty, stats0a) - ((stats, meta), cs) = runState renamed cs0 - - renamed :: State CompactorState ([JStat], JStat) - renamed - - | True = do - cs <- State.get - let renamedStats = map (identsS' (lookupRenamed cs) . lu_js_code) stats0 - statics = map (renameStaticInfo cs) $ - concatMap lu_statics stats0 - infos = map (renameClosureInfo cs) $ - concatMap lu_closures stats0 + compact_mods = map compact mods + + -- here GHCJS used to: + -- - deduplicate declarations + -- - rename local variables into shorter ones + -- - compress initialization data + -- but we haven't ported it (yet). + + compact m = CompactedModuleCode + { cmc_js_code = mc_js_code m + , cmc_module = mc_module m + , cmc_exports = mc_exports m + } + + statics = concatMap mc_statics mods + infos = concatMap mc_closures mods + meta = mconcat -- render metadata as individual statements - meta = mconcat (map staticDeclStat statics) <> - identsS' (lookupRenamed cs) stbs <> - mconcat (map (staticInitStat $ csProf cfg) statics) <> - mconcat (map (closureInfoStat True) infos) - return (renamedStats, meta) - -lookupRenamed :: CompactorState -> Ident -> Ident -lookupRenamed cs i@(TxtI t) = - fromMaybe i (lookupUniqMap (csNameMap cs) t) - --- | rename a compactor info entry according to the compactor state (no new renamings are added) -renameClosureInfo :: CompactorState - -> ClosureInfo - -> ClosureInfo -renameClosureInfo cs (ClosureInfo v rs n l t s) = - ClosureInfo (renameV v) rs n l t (f s) - where - renameV t = maybe t itxt (lookupUniqMap m t) - m = csNameMap cs - f (CIStaticRefs rs) = CIStaticRefs (map renameV rs) - --- | rename a static info entry according to the compactor state (no new renamings are added) -renameStaticInfo :: CompactorState - -> StaticInfo - -> StaticInfo -renameStaticInfo cs = staticIdents renameIdent - where - renameIdent t = maybe t itxt (lookupUniqMap (csNameMap cs) t) - --- | initialize a global object. all global objects have to be declared (staticInfoDecl) first --- (this is only used with -debug, normal init would go through the static data table) -staticInitStat :: Bool -- ^ profiling enabled - -> StaticInfo - -> JStat -staticInitStat _prof (StaticInfo i sv cc) = + [ mconcat (map staticDeclStat statics) + , mconcat (map staticInitStat statics) + , mconcat (map (closureInfoStat True) infos) + ] + +-- | Initialize a global object. +-- +-- All global objects have to be declared (staticInfoDecl) first. +staticInitStat :: StaticInfo -> JStat +staticInitStat (StaticInfo i sv mcc) = case sv of - StaticData con args -> appS "h$sti" ([var i, var con, jsStaticArgs args] ++ ccArg) - StaticFun f args -> appS "h$sti" ([var i, var f, jsStaticArgs args] ++ ccArg) - StaticList args mt -> - appS "h$stl" ([var i, jsStaticArgs args, toJExpr $ maybe null_ (toJExpr . TxtI) mt] ++ ccArg) - StaticThunk (Just (f,args)) -> - appS "h$stc" ([var i, var f, jsStaticArgs args] ++ ccArg) - _ -> mempty + StaticData con args -> appS "h$sti" $ add_cc_arg + [ var i + , var con + , jsStaticArgs args + ] + StaticFun f args -> appS "h$sti" $ add_cc_arg + [ var i + , var f + , jsStaticArgs args + ] + StaticList args mt -> appS "h$stl" $ add_cc_arg + [ var i + , jsStaticArgs args + , toJExpr $ maybe null_ (toJExpr . TxtI) mt + ] + StaticThunk (Just (f,args)) -> appS "h$stc" $ add_cc_arg + [ var i + , var f + , jsStaticArgs args + ] + _ -> mempty where - ccArg = maybeToList (fmap toJExpr cc) - -staticIdents :: (FastString -> FastString) - -> StaticInfo - -> StaticInfo -staticIdents f (StaticInfo i v cc) = StaticInfo (f i) (staticIdentsV f v) cc - -staticIdentsV ::(FastString -> FastString) -> StaticVal -> StaticVal -staticIdentsV f (StaticFun i args) = StaticFun (f i) (staticIdentsA f <$> args) -staticIdentsV f (StaticThunk (Just (i, args))) = StaticThunk . Just $ - (f i, staticIdentsA f <$> args) -staticIdentsV f (StaticData con args) = StaticData (f con) (staticIdentsA f <$> args) -staticIdentsV f (StaticList xs t) = StaticList (staticIdentsA f <$> xs) (f <$> t) -staticIdentsV _ x = x - -staticIdentsA :: (FastString -> FastString) -> StaticArg -> StaticArg -staticIdentsA f (StaticObjArg t) = StaticObjArg $! f t -staticIdentsA _ x = x + -- add optional cost-center argument + add_cc_arg as = case mcc of + Nothing -> as + Just cc -> as ++ [toJExpr cc] -- | declare and do first-pass init of a global object (create JS object for heap objects) staticDeclStat :: StaticInfo -> JStat @@ -977,42 +947,3 @@ staticDeclStat (StaticInfo global_name static_value _) = decl StaticUnboxedStringOffset {} -> 0 to_byte_list = JList . map (Int . fromIntegral) . BS.unpack - -identsE' :: (Ident -> Ident) -> JExpr -> JExpr -identsE' f (ValExpr v) = ValExpr $! identsV' f v -identsE' f (SelExpr e i) = SelExpr (identsE' f e) i -- do not rename properties -identsE' f (IdxExpr e1 e2) = IdxExpr (identsE' f e1) (identsE' f e2) -identsE' f (InfixExpr s e1 e2) = InfixExpr s (identsE' f e1) (identsE' f e2) -identsE' f (UOpExpr o e) = UOpExpr o $! identsE' f e -identsE' f (IfExpr e1 e2 e3) = IfExpr (identsE' f e1) (identsE' f e2) (identsE' f e3) -identsE' f (ApplExpr e es) = ApplExpr (identsE' f e) (identsE' f <$> es) -identsE' _ UnsatExpr{} = error "identsE': UnsatExpr" - -identsV' :: (Ident -> Ident) -> JVal -> JVal -identsV' f (JVar i) = JVar $! f i -identsV' f (JList xs) = JList $! (fmap . identsE') f xs -identsV' _ d at JDouble{} = d -identsV' _ i at JInt{} = i -identsV' _ s at JStr{} = s -identsV' _ r at JRegEx{} = r -identsV' f (JHash m) = JHash $! (fmap . identsE') f m -identsV' f (JFunc args s) = JFunc (fmap f args) (identsS' f s) -identsV' _ UnsatVal{} = error "identsV': UnsatVal" - -identsS' :: (Ident -> Ident) -> JStat -> JStat -identsS' f (DeclStat i e) = DeclStat (f i) e -identsS' f (ReturnStat e) = ReturnStat $! identsE' f e -identsS' f (IfStat e s1 s2) = IfStat (identsE' f e) (identsS' f s1) (identsS' f s2) -identsS' f (WhileStat b e s) = WhileStat b (identsE' f e) (identsS' f s) -identsS' f (ForInStat b i e s) = ForInStat b (f i) (identsE' f e) (identsS' f s) -identsS' f (SwitchStat e xs s) = SwitchStat (identsE' f e) (fmap (traverseCase f) xs) (identsS' f s) - where traverseCase g (e,s) = (identsE' g e, identsS' g s) -identsS' f (TryStat s1 i s2 s3) = TryStat (identsS' f s1) (f i) (identsS' f s2) (identsS' f s3) -identsS' f (BlockStat xs) = BlockStat $! identsS' f <$> xs -identsS' f (ApplStat e es) = ApplStat (identsE' f e) (identsE' f <$> es) -identsS' f (UOpStat op e) = UOpStat op $! identsE' f e -identsS' f (AssignStat e1 e2) = AssignStat (identsE' f e1) (identsE' f e2) -identsS' _ UnsatBlock{} = error "identsS': UnsatBlock" -identsS' f (LabelStat l s) = LabelStat l $! identsS' f s -identsS' _ b at BreakStat{} = b -identsS' _ c at ContinueStat{} = c ===================================== compiler/GHC/StgToJS/Linker/Types.hs ===================================== @@ -18,21 +18,23 @@ -- ----------------------------------------------------------------------------- -module GHC.StgToJS.Linker.Types where +module GHC.StgToJS.Linker.Types + ( GhcjsEnv (..) + , newGhcjsEnv + , JSLinkConfig (..) + , generateAllJs + , LinkedObj (..) + , LinkableUnit + ) +where -import GHC.JS.Syntax import GHC.StgToJS.Object -import GHC.StgToJS.Types (ClosureInfo, StaticInfo) import GHC.Unit.Types -import GHC.Data.FastString -import GHC.Types.Unique.Map import GHC.Utils.Outputable (hsep,Outputable(..),text,ppr) import Control.Monad -import Data.Array -import Data.ByteString (ByteString) import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Set (Set) @@ -43,217 +45,26 @@ import System.IO import Prelude --------------------------------------------------------------------------------- --- CompactorState --------------------------------------------------------------------------------- - -data CompactorState = CompactorState - { csNameMap :: !(UniqMap FastString Ident) -- ^ renaming mapping for internal names - , csEntries :: !(UniqMap FastString Int) -- ^ entry functions (these get listed in the metadata init - -- array) - , csNumEntries :: !Int - , csStatics :: !(UniqMap FastString Int) -- ^ mapping of global closure -> index in current block, - -- for static initialisation - , csNumStatics :: !Int -- ^ number of static entries - , csLabels :: !(UniqMap FastString Int) -- ^ non-Haskell JS labels - , csNumLabels :: !Int -- ^ number of labels - , csParentEntries :: !(UniqMap FastString Int) -- ^ entry functions we're not linking, offset where parent - -- gets [0..n], grandparent [n+1..k] etc - , csParentStatics :: !(UniqMap FastString Int) -- ^ objects we're not linking in base bundle - , csParentLabels :: !(UniqMap FastString Int) -- ^ non-Haskell JS labels in parent - , csStringTable :: !StringTable - } - --- | A Table of Strings representing @Ident at s and their payloads in --- @CompactorState@ -data StringTable = StringTable - { stTableIdents :: !(Array Int FastString) -- ^ An array of table identifiers, used in the compactor - , stOffsets :: !(M.Map ByteString (Int, Int)) -- ^ content of the table - , stIdents :: !(UniqMap FastString (Either Int Int)) -- ^ identifiers in the table - } - --- | The empty @CompactorState@ -emptyCompactorState :: CompactorState -emptyCompactorState = CompactorState - { csNameMap = mempty - , csEntries = mempty - , csNumEntries = 0 - , csStatics = mempty - , csNumStatics = 0 - , csLabels = mempty - , csNumLabels = 0 - , csParentEntries = mempty - , csParentStatics = mempty - , csParentLabels = mempty - , csStringTable = emptyStringTable - } - --- | The empty @StringTable@ -emptyStringTable :: StringTable -emptyStringTable = StringTable (listArray (0,-1) []) M.empty emptyUniqMap - - --------------------------------------------------------------------------------- --- CompactorState helper functors --------------------------------------------------------------------------------- - --- | Update @csEntries@ in @CompactorState@ -entries :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -entries f cs = fmap (\x -> cs { csEntries = x }) (f $ csEntries cs) -{-# INLINE entries #-} - --- | Update @csLabels@ in @CompactorState@ -labels :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -labels f cs = fmap (\x -> cs { csLabels = x }) (f $ csLabels cs) -{-# INLINE labels #-} - --- | Update @csNameMap@ in @CompactorState@ -nameMap :: Functor f - => (UniqMap FastString Ident -> f (UniqMap FastString Ident)) - -> CompactorState - -> f CompactorState -nameMap f cs = fmap (\x -> cs { csNameMap = x }) (f $ csNameMap cs) -{-# INLINE nameMap #-} - --- | Update @csNumEntries@ in @CompactorState@ -numEntries :: Functor f - => (Int -> f Int) - -> CompactorState - -> f CompactorState -numEntries f cs = fmap (\x -> cs { csNumEntries = x }) (f $ csNumEntries cs) -{-# INLINE numEntries #-} - --- | Update @csNumLabels@ in @CompactorState@ -numLabels :: Functor f - => (Int -> f Int) - -> CompactorState - -> f CompactorState -numLabels f cs = fmap (\x -> cs { csNumLabels = x }) (f $ csNumLabels cs) -{-# INLINE numLabels #-} - --- | Update @csNumStatics@ in @CompactorState@ -numStatics :: Functor f - => (Int -> f Int) - -> CompactorState - -> f CompactorState -numStatics f cs = fmap (\x -> cs { csNumStatics = x }) (f $ csNumStatics cs) -{-# INLINE numStatics #-} - --- | Update @csParentEntries@ in @CompactorState@ -parentEntries :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -parentEntries f cs = fmap (\x -> cs { csParentEntries = x }) (f $ csParentEntries cs) -{-# INLINE parentEntries #-} - --- | Update @csParentLabels@ in @CompactorState@ -parentLabels :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -parentLabels f cs = fmap (\x -> cs { csParentLabels = x }) (f $ csParentLabels cs) -{-# INLINE parentLabels #-} - --- | Update @csParentStatics@ in @CompactorState@ -parentStatics :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -parentStatics f cs = fmap (\x -> cs { csParentStatics = x }) (f $ csParentStatics cs) -{-# INLINE parentStatics #-} - --- | Update @csStatics@ in @CompactorState@ -statics :: Functor f - => (UniqMap FastString Int -> f (UniqMap FastString Int)) - -> CompactorState - -> f CompactorState -statics f cs = fmap (\x -> cs { csStatics = x }) (f $ csStatics cs) -{-# INLINE statics #-} - --- | Update @csStringTable@ in @CompactorState@ -stringTable :: Functor f - => (StringTable -> f StringTable) - -> CompactorState - -> f CompactorState -stringTable f cs = fmap (\x -> cs { csStringTable = x }) (f $ csStringTable cs) -{-# INLINE stringTable #-} - - --------------------------------------------------------------------------------- --- CompactorState Insertions --------------------------------------------------------------------------------- - --- | Given a static entry, add the entry to @CompactorState@ -addStaticEntry :: FastString -- ^ The static entry to add - -> CompactorState -- ^ the old state - -> CompactorState -- ^ the new state -addStaticEntry new cs = - -- check if we have seen new before - let cur_statics = csStatics cs - go = lookupUniqMap cur_statics new >> lookupUniqMap (csParentStatics cs) new - in case go of - Just _ -> cs -- we have so return - Nothing -> let cnt = csNumStatics cs -- we haven't so do the business - newStatics = addToUniqMap cur_statics new cnt - newCnt = cnt + 1 - in cs {csStatics = newStatics, csNumStatics = newCnt} - --- | Given an entry function, add the entry function to @CompactorState@ -addEntry :: FastString -- ^ The entry function to add - -> CompactorState -- ^ the old state - -> CompactorState -- ^ the new state -addEntry new cs = - let cur_entries = csEntries cs - go = lookupUniqMap cur_entries new >> lookupUniqMap (csParentEntries cs) new - in case go of - Just _ -> cs - Nothing -> let cnt = csNumEntries cs - newEntries = addToUniqMap cur_entries new cnt - newCnt = cnt + 1 - in cs {csEntries = newEntries, csNumEntries = newCnt} - --- | Given a label, add the label to @CompactorState@ -addLabel :: FastString -- ^ The label to add - -> CompactorState -- ^ the old state - -> CompactorState -- ^ the new state -addLabel new cs = - let cur_lbls = csLabels cs - go = lookupUniqMap cur_lbls new >> lookupUniqMap (csParentLabels cs) new - in case go of - Just _ -> cs - Nothing -> let cnt = csNumLabels cs - newLabels = addToUniqMap cur_lbls new cnt - newCnt = cnt + 1 - in cs {csEntries = newLabels, csNumLabels = newCnt} - -------------------------------------------------------------------------------- -- Linker Config -------------------------------------------------------------------------------- -data JSLinkConfig = - JSLinkConfig { lcNativeExecutables :: Bool - , lcNativeToo :: Bool - , lcBuildRunner :: Bool - , lcNoJSExecutables :: Bool - , lcNoHsMain :: Bool - , lcStripProgram :: Maybe FilePath - , lcLogCommandLine :: Maybe FilePath - , lcGhc :: Maybe FilePath - , lcOnlyOut :: Bool - , lcNoRts :: Bool - , lcNoStats :: Bool - , lcLinkJsLib :: Maybe String - , lcJsLibOutputDir :: Maybe FilePath - , lcJsLibSrcs :: [FilePath] - , lcDedupe :: Bool - } +data JSLinkConfig = JSLinkConfig + { lcNativeExecutables :: Bool + , lcNativeToo :: Bool + , lcBuildRunner :: Bool + , lcNoJSExecutables :: Bool + , lcNoHsMain :: Bool + , lcStripProgram :: Maybe FilePath + , lcLogCommandLine :: Maybe FilePath + , lcGhc :: Maybe FilePath + , lcOnlyOut :: Bool + , lcNoRts :: Bool + , lcNoStats :: Bool + , lcLinkJsLib :: Maybe String + , lcJsLibOutputDir :: Maybe FilePath + , lcJsLibSrcs :: [FilePath] + } -- | we generate a runnable all.js only if we link a complete application, -- no incremental linking and no skipped parts @@ -276,7 +87,6 @@ instance Monoid JSLinkConfig where , lcLinkJsLib = Nothing , lcJsLibOutputDir = Nothing , lcJsLibSrcs = mempty - , lcDedupe = False } instance Semigroup JSLinkConfig where @@ -298,7 +108,6 @@ instance Semigroup JSLinkConfig where , lcLinkJsLib = comb (<>) lcLinkJsLib , lcJsLibOutputDir = comb (<>) lcJsLibOutputDir , lcJsLibSrcs = comb (<>) lcJsLibSrcs - , lcDedupe = comb (||) lcDedupe } -------------------------------------------------------------------------------- @@ -309,13 +118,6 @@ instance Semigroup JSLinkConfig where -- object file type LinkableUnit = (Module, Int) --- | A @LinkedUnit@ is a payload of JS code with its closures and any static info. -data LinkedUnit = LinkedUnit - { lu_js_code :: !JStat - , lu_closures :: ![ClosureInfo] - , lu_statics :: ![StaticInfo] - } - -- | An object file that's either already in memory (with name) or on disk data LinkedObj = ObjFile FilePath -- ^ load from this file ===================================== compiler/ghc.cabal.in ===================================== @@ -661,7 +661,6 @@ Library GHC.StgToJS.Types GHC.StgToJS.UnitUtils GHC.StgToJS.Utils - GHC.StgToJS.Linker.Compactor GHC.StgToJS.Linker.Linker GHC.StgToJS.Linker.Types GHC.StgToJS.Linker.Utils View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89db61b634d3077e8ef9e99f73bc90f7ed5f2226...18a51ca67f1f7e44a2eefa5e7c121732ad88f675 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89db61b634d3077e8ef9e99f73bc90f7ed5f2226...18a51ca67f1f7e44a2eefa5e7c121732ad88f675 You're receiving 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 Oct 14 13:27:24 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 09:27:24 -0400 Subject: [Git][ghc/ghc][wip/js-staging] RTS: remove dangling semicolons Message-ID: <634963bc12fab_8b90f5175c730e5@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 52f69c38 by Sylvain Henry at 2022-10-14T15:30:33+02:00 RTS: remove dangling semicolons - - - - - 1 changed file: - rts/js/arith.js Changes: ===================================== rts/js/arith.js ===================================== @@ -25,7 +25,7 @@ function h$hs_quotWord64(h1,l1,h2,l2) { var a = W64(h1,l1); var b = W64(h2,l2); var r = BigInt.asUintN(64, a / b); - TRACE_ARITH("Word64: " + a + " / " + b + " ==> " + r); + TRACE_ARITH("Word64: " + a + " / " + b + " ==> " + r) RETURN_W64(r); } @@ -33,7 +33,7 @@ function h$hs_remWord64(h1,l1,h2,l2) { var a = W64(h1,l1); var b = W64(h2,l2); var r = BigInt.asUintN(64, a % b); - TRACE_ARITH("Word64: " + a + " % " + b + " ==> " + r); + TRACE_ARITH("Word64: " + a + " % " + b + " ==> " + r) RETURN_W64(r); } @@ -41,7 +41,7 @@ function h$hs_timesWord64(h1,l1,h2,l2) { var a = W64(h1,l1); var b = W64(h2,l2); var r = BigInt.asUintN(64, a * b); - TRACE_ARITH("Word64: " + a + " * " + b + " ==> " + r); + TRACE_ARITH("Word64: " + a + " * " + b + " ==> " + r) RETURN_W64(r); } @@ -49,7 +49,7 @@ function h$hs_minusWord64(h1,l1,h2,l2) { var a = (BigInt(h1) << BigInt(32)) | BigInt(l1>>>0); var b = (BigInt(h2) << BigInt(32)) | BigInt(l2>>>0); var r = BigInt.asUintN(64, a - b); - TRACE_ARITH("Word64: " + a + " - " + b + " ==> " + r); + TRACE_ARITH("Word64: " + a + " - " + b + " ==> " + r) RETURN_W64(r); } @@ -57,7 +57,7 @@ function h$hs_plusWord64(h1,l1,h2,l2) { var a = W64(h1,l1); var b = W64(h2,l2); var r = BigInt.asUintN(64, a + b); - TRACE_ARITH("Word64: " + a + " + " + b + " ==> " + r); + TRACE_ARITH("Word64: " + a + " + " + b + " ==> " + r) RETURN_W64(r); } @@ -65,7 +65,7 @@ function h$hs_timesInt64(h1,l1,h2,l2) { var a = I64(h1,l1); var b = I64(h2,l2); var r = BigInt.asIntN(64, a * b); - TRACE_ARITH("Int64: " + a + " * " + b + " ==> " + r); + TRACE_ARITH("Int64: " + a + " * " + b + " ==> " + r) RETURN_I64(r); } @@ -73,7 +73,7 @@ function h$hs_quotInt64(h1,l1,h2,l2) { var a = I64(h1,l1); var b = I64(h2,l2); var r = BigInt.asIntN(64, a / b); - TRACE_ARITH("Int64: " + a + " / " + b + " ==> " + r); + TRACE_ARITH("Int64: " + a + " / " + b + " ==> " + r) RETURN_I64(r); } @@ -81,7 +81,7 @@ function h$hs_remInt64(h1,l1,h2,l2) { var a = I64(h1,l1); var b = I64(h2,l2); var r = BigInt.asIntN(64, a % b); - TRACE_ARITH("Int64: " + a + " % " + b + " ==> " + r); + TRACE_ARITH("Int64: " + a + " % " + b + " ==> " + r) RETURN_I64(r); } @@ -89,7 +89,7 @@ function h$hs_plusInt64(h1,l1,h2,l2) { var a = I64(h1,l1); var b = I64(h2,l2); var r = BigInt.asIntN(64, a + b); - TRACE_ARITH("Int64: " + a + " + " + b + " ==> " + r); + TRACE_ARITH("Int64: " + a + " + " + b + " ==> " + r) RETURN_I64(r); } @@ -97,7 +97,7 @@ function h$hs_minusInt64(h1,l1,h2,l2) { var a = I64(h1,l1); var b = I64(h2,l2); var r = BigInt.asIntN(64, a - b); - TRACE_ARITH("Int64: " + a + " - " + b + " ==> " + r); + TRACE_ARITH("Int64: " + a + " - " + b + " ==> " + r) RETURN_I64(r); } @@ -118,8 +118,7 @@ function h$hs_uncheckedShiftLWord64(h,l,n) { rh = UN(l << (n - 32)); rl = 0; } - - TRACE_ARITH("Word64: " + W64(h,l) + " << " + n + " ==> " + W64(rh,rl)); + TRACE_ARITH("Word64: " + W64(h,l) + " << " + n + " ==> " + W64(rh,rl)) RETURN_UBX_TUP2(rh,rl); } @@ -140,7 +139,7 @@ function h$hs_uncheckedShiftRWord64(h,l,n) { rh = 0; rl = h >>> (n-32); } - TRACE_ARITH("Word64: " + W64(h,l) + " >>> " + n + " ==> " + W64(rh,rl)); + TRACE_ARITH("Word64: " + W64(h,l) + " >>> " + n + " ==> " + W64(rh,rl)) RETURN_UBX_TUP2(rh,rl); } @@ -161,8 +160,7 @@ function h$hs_uncheckedShiftLLInt64(h,l,n) { rh = l << (n - 32); rl = 0; } - - TRACE_ARITH("Int64: " + W64(h,l) + " << " + n + " ==> " + W64(rh,rl)); + TRACE_ARITH("Int64: " + W64(h,l) + " << " + n + " ==> " + W64(rh,rl)) RETURN_UBX_TUP2(rh,rl); } @@ -180,8 +178,7 @@ function h$hs_uncheckedShiftRAInt64(h,l,n) { rh = h >= 0 ? 0 : -1; rl = UN(h >> (n - 32)); } - - TRACE_ARITH("Int64: " + W64(h,l) + " >> " + n + " ==> " + W64(rh,rl)); + TRACE_ARITH("Int64: " + W64(h,l) + " >> " + n + " ==> " + W64(rh,rl)) RETURN_UBX_TUP2(rh,rl); } @@ -202,8 +199,7 @@ function h$hs_uncheckedShiftRLInt64(h,l,n) { rh = 0; rl = h >>> (n-32); } - - TRACE_ARITH("Int64: " + W64(h,l) + " >>> " + n + " ==> " + W64(rh,rl)); + TRACE_ARITH("Int64: " + W64(h,l) + " >>> " + n + " ==> " + W64(rh,rl)) RETURN_UBX_TUP2(rh,rl); } @@ -216,7 +212,7 @@ function h$hs_timesInt2(l1,l2) { var a = I32(l1); var b = I32(l2); var r = BigInt.asIntN(64, a * b); - TRACE_ARITH("Int32: " + a + " * " + b + " ==> " + r + " (Int64)"); + TRACE_ARITH("Int32: " + a + " * " + b + " ==> " + r + " (Int64)") var rh = I64h(r); var rl = I64l(r)|0; @@ -229,7 +225,7 @@ function h$mulWord32(l1,l2) { var a = W32(l1); var b = W32(l2); var r = BigInt.asUintN(32, a * b); - TRACE_ARITH("Word32: " + a + " * " + b + " ==> " + r); + TRACE_ARITH("Word32: " + a + " * " + b + " ==> " + r) RETURN_W32(r); } @@ -237,7 +233,7 @@ function h$mul2Word32(l1,l2) { var a = W32(l1); var b = W32(l2); var r = BigInt.asUintN(64, a * b); - TRACE_ARITH("Word32: " + a + " * " + b + " ==> " + r + " (Word64)"); + TRACE_ARITH("Word32: " + a + " * " + b + " ==> " + r + " (Word64)") RETURN_W64(r); } @@ -245,7 +241,7 @@ function h$quotWord32(n,d) { var a = W32(n); var b = W32(d); var r = BigInt.asUintN(32, a / b); - TRACE_ARITH("Word32: " + a + " / " + b + " ==> " + r); + TRACE_ARITH("Word32: " + a + " / " + b + " ==> " + r) RETURN_W32(r); } @@ -253,7 +249,7 @@ function h$remWord32(n,d) { var a = W32(n); var b = W32(d); var r = BigInt.asUintN(32, a % b); - TRACE_ARITH("Word32: " + a + " % " + b + " ==> " + r); + TRACE_ARITH("Word32: " + a + " % " + b + " ==> " + r) RETURN_W32(r); } @@ -262,7 +258,7 @@ function h$quotRemWord32(n,d) { var b = W32(d); var q = BigInt.asUintN(32, a / b); var r = BigInt.asUintN(32, a % b); - TRACE_ARITH("Word32: " + a + " `quotRem` " + b + " ==> (" + q + ", " + r + ")"); + TRACE_ARITH("Word32: " + a + " `quotRem` " + b + " ==> (" + q + ", " + r + ")") RETURN_UBX_TUP2(Number(q),Number(r)); } @@ -271,7 +267,7 @@ function h$quotRem2Word32(nh,nl,d) { var b = W32(d); var q = BigInt.asUintN(32, a / b); var r = BigInt.asUintN(32, a % b); - TRACE_ARITH("Word32: " + a + " `quotRem2` " + b + " ==> (" + q + ", " + r + ")"); + TRACE_ARITH("Word32: " + a + " `quotRem2` " + b + " ==> (" + q + ", " + r + ")") RETURN_UBX_TUP2(Number(q),Number(r)); } @@ -279,17 +275,17 @@ function h$wordAdd2(l1,l2) { var a = W32(l1); var b = W32(l2); var r = BigInt.asUintN(64, a + b); - TRACE_ARITH("Word32: " + a + " + " + b + " ==> " + r + " (Word64)"); + TRACE_ARITH("Word32: " + a + " + " + b + " ==> " + r + " (Word64)") RETURN_W64(r); } function h$isDoubleNegativeZero(d) { - TRACE_ARITH("isDoubleNegativeZero: " + d); + TRACE_ARITH("isDoubleNegativeZero: " + d) return (d===0 && (1/d) === -Infinity) ? 1 : 0; } function h$isFloatNegativeZero(d) { - TRACE_ARITH("isFloatNegativeZero: " + d); + TRACE_ARITH("isFloatNegativeZero: " + d) return (d===0 && (1/d) === -Infinity) ? 1 : 0; } @@ -340,7 +336,7 @@ var h$convertWord = new Uint32Array(h$convertBuffer); h$convertFloat[0] = 0.75; function h$decodeFloatInt(d) { - TRACE_ARITH("decodeFloatInt: " + d); + TRACE_ARITH("decodeFloatInt: " + d) if(isNaN(d)) { RETURN_UBX_TUP2(-12582912, 105); } @@ -351,29 +347,29 @@ function h$decodeFloatInt(d) { var s = i&8388607; if(exp === 0) { // zero or denormal if(s === 0) { - TRACE_ARITH("decodeFloatInt s: 0 e: 0"); + TRACE_ARITH("decodeFloatInt s: 0 e: 0") RETURN_UBX_TUP2(0, 0); } else { h$convertFloat[0] = d*8388608; // put d in the normal range (~ shift left 23 bits) i = h$convertInt[0]; s = (i&8388607) | 8388608; e = ((i >> 23) & 0xff) - 173; // take into account normalization above (150+23) - TRACE_ARITH("decodeFloatInt s: " + (sgn * s) + " e: " + e); + TRACE_ARITH("decodeFloatInt s: " + (sgn * s) + " e: " + e) RETURN_UBX_TUP2(sgn*s, e) } } else { - TRACE_ARITH("decodeFloatInt s: " + (sgn * (s|8388608)) + " e: " + (exp-150)); + TRACE_ARITH("decodeFloatInt s: " + (sgn * (s|8388608)) + " e: " + (exp-150)) RETURN_UBX_TUP2(sgn * (s|8388608), exp - 150); } } function h$decodeDouble2Int(d) { - TRACE_ARITH("decodeDouble2Int: " + d); + TRACE_ARITH("decodeDouble2Int: " + d) if(isNaN(d)) { RETURN_UBX_TUP4(1, -1572864, 0, 972); } h$convertDouble[0] = d; - TRACE_ARITH("decodeDouble2Int binary: " + h$convertInt[0].toString(2) + " " + h$convertInt[1].toString(2)); + TRACE_ARITH("decodeDouble2Int binary: " + h$convertInt[0].toString(2) + " " + h$convertInt[1].toString(2)) var i1 = h$convertInt[1]; var ret1, ret2 = h$convertInt[0], ret3; var exp = (i1&2146435072)>>>20; @@ -392,7 +388,7 @@ function h$decodeDouble2Int(d) { ret3 = exp-1075; ret1 = (i1&1048575)|1048576; } - TRACE_ARITH("decodeDouble2Int: exp: " + ret3 + " significand: " + ret1 + " " + ret2); + TRACE_ARITH("decodeDouble2Int: exp: " + ret3 + " significand: " + ret1 + " " + ret2) RETURN_UBX_TUP4(i1<0?-1:1,ret1,ret2,ret3); } @@ -527,7 +523,7 @@ function h$ctz64(x1,x2) { } function h$decodeDoubleInt64(d) { - TRACE_ARITH("decodeDoubleInt64: " + d); + TRACE_ARITH("decodeDoubleInt64: " + d) if(isNaN(d)) { RETURN_UBX_TUP3(972, -1572864, 0); } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52f69c3807ac6096553cb27dec0d1d2fdc89f029 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52f69c3807ac6096553cb27dec0d1d2fdc89f029 You're receiving 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 Oct 14 13:39:14 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 09:39:14 -0400 Subject: [Git][ghc/ghc][wip/js-staging] RTS: remove more dangling semicolons Message-ID: <63496682eb0a_8b90f514287344c@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: af7f81f8 by Sylvain Henry at 2022-10-14T15:42:24+02:00 RTS: remove more dangling semicolons - - - - - 9 changed files: - rts/js/compact.js - rts/js/environment.js - rts/js/gc.js - rts/js/hscore.js - rts/js/mem.js - rts/js/stableptr.js - rts/js/stm.js - rts/js/thread.js - rts/js/weak.js Changes: ===================================== rts/js/compact.js ===================================== @@ -8,43 +8,43 @@ function h$logCompact() { h$log.apply(h$log,arguments); } #endif function h$compactNew(size) { - TRACE_COMPACT("compactNew" + size); + TRACE_COMPACT("compactNew" + size) throw new Error("not implemented"); } function h$compactResize(compact, size) { - TRACE_COMPACT("compactResize" + size); + TRACE_COMPACT("compactResize" + size) } function h$compactContains(compact, obj) { - TRACE_COMPACT("compactContains"); + TRACE_COMPACT("compactContains") return 0; } function h$compactContainsAny(obj) { - TRACE_COMPACT("compactContainsAny"); + TRACE_COMPACT("compactContainsAny") return 0; } function h$compactGetFirstBlock(compact) { - TRACE_COMPACT("compactGetFirstBlock"); + TRACE_COMPACT("compactGetFirstBlock") RETURN_UBX_TUP2(null, 0); } function h$compactGetNextBlock(compact, blocka, blokco) { - TRACE_COMPACT("compactGetNextBlock"); + TRACE_COMPACT("compactGetNextBlock") RETURN_UBX_TUP2(null, 0); } function h$compactAllocateBlock(size, suggesta, suggesto) { - TRACE_COMPACT("compactAllocateBlock" + size); + TRACE_COMPACT("compactAllocateBlock" + size) throw new Error("not implemented"); // returns new root address RETURN_UBX_TUP2(null, 0); } function h$compactFixupPointers(blocka, blocko, roota, rooto) { - TRACE_COMPACT("compactFixupPointers"); + TRACE_COMPACT("compactFixupPointers") throw new Error("not implemented"); // returns new root address and new Compact# RETURN_UBX_TUP3(null, null, 0); @@ -52,18 +52,18 @@ function h$compactFixupPointers(blocka, blocko, roota, rooto) { function h$compactAdd(compact, obj) { - TRACE_COMPACT("compactAdd"); + TRACE_COMPACT("compactAdd") throw new Error("not implemented"); } function h$compactAddWithSharing(compact, obj) { - TRACE_COMPACT("compactAddWithSharing"); + TRACE_COMPACT("compactAddWithSharing") throw new Error("not implemented"); } function h$compactCompactSize(compact) { - TRACE_COMPACT("compactSize"); + TRACE_COMPACT("compactSize") return 0; } ===================================== rts/js/environment.js ===================================== @@ -151,7 +151,7 @@ function h$initArgs() { } function h$getProgArgv(argc_v,argc_off,argv_v,argv_off) { - TRACE_ENV("getProgArgV"); + TRACE_ENV("getProgArgV") var c = h$programArgs().length; if(c === 0) { argc_v.dv.setInt32(argc_off, 0, true); @@ -195,25 +195,25 @@ function h$getCPUTime() { if(h$isNode()) { var t = process.cpuUsage(); var cput = t.user + t.system; - TRACE_ENV("getCPUTime: " + cput); + TRACE_ENV("getCPUTime: " + cput) return cput; } #endif // XXX this allows more testsuites to run // but I don't really like returning a fake value here - TRACE_ENV("getCPUTime: returning fake value"); + TRACE_ENV("getCPUTime: returning fake value") return ++h$fakeCpuTime; return -1; } function h$__hscore_environ() { - TRACE_ENV("hscore_environ"); + TRACE_ENV("hscore_environ") #ifndef GHCJS_BROWSER if(h$isNode()) { var env = [], i; for(i in process.env) { var envv = i + '=' + process.env[i]; - TRACE_ENV("hscore_environ: " + envv); + TRACE_ENV("hscore_environ: " + envv) env.push(envv); } if(env.length === 0) return null; @@ -232,13 +232,13 @@ function h$__hsbase_unsetenv(name, name_off) { } function h$getenv(name, name_off) { - TRACE_ENV("getenv"); + TRACE_ENV("getenv") #ifndef GHCJS_BROWSER if(h$isNode()) { var n = h$decodeUtf8z(name, name_off); - TRACE_ENV("getenv (node): " + n); + TRACE_ENV("getenv (node): " + n) if(typeof process.env[n] !== 'undefined') { - TRACE_ENV("getenv (node): " + n + " -> " + process.env[n]); + TRACE_ENV("getenv (node): " + n + " -> " + process.env[n]) RETURN_UBX_TUP2(h$encodeUtf8(process.env[n]), 0); } } @@ -249,7 +249,7 @@ function h$getenv(name, name_off) { function h$setenv(name, name_off, val, val_off, overwrite) { var n = h$decodeUtf8z(name, name_off); var v = h$decodeUtf8z(val, val_off); - TRACE_ENV("setenv: " + n + " -> " + v); + TRACE_ENV("setenv: " + n + " -> " + v) if(n.indexOf('=') !== -1) { h$setErrno("EINVAL"); return -1; @@ -264,7 +264,7 @@ function h$setenv(name, name_off, val, val_off, overwrite) { function h$unsetenv(name, name_off) { var n = h$decodeUtf8z(name, name_off); - TRACE_ENV("unsetenv: " + n); + TRACE_ENV("unsetenv: " + n) if(n.indexOf('=') !== -1) { h$setErrno("EINVAL"); return -1; @@ -287,14 +287,14 @@ function h$putenv(str, str_off) { #ifndef GHCJS_BROWSER var x = h$decodeUtf8z(str, str_off); var i = x.indexOf('='); - TRACE_ENV("putenv: " + x); + TRACE_ENV("putenv: " + x) if(i === -1) { // remove the value - TRACE_ENV("putenv unset: " + x); + TRACE_ENV("putenv unset: " + x) if(h$isNode()) delete process.env[x]; } else { // set the value var name = x.substring(0, i) var val = x.substring(i+1); - TRACE_ENV("putenv set: " + name + " -> " + val); + TRACE_ENV("putenv set: " + name + " -> " + val) if(h$isNode()) process.env[name] = val; } #endif ===================================== rts/js/gc.js ===================================== @@ -159,8 +159,8 @@ function h$gcQuick(t) { #ifdef GHCJS_TRACE_GC var time = Date.now() - start; h$gcTime += time; - TRACE_GC("time (quick): " + time + "ms"); - TRACE_GC("time (total): " + h$gcTime + "ms"); + TRACE_GC("time (quick): " + time + "ms") + TRACE_GC("time (total): " + h$gcTime + "ms") #endif } @@ -181,10 +181,10 @@ function h$gc(t) { if(h$currentThread !== null) throw "h$gc: GC can only be run when no thread is running"; #ifdef GHCJS_TRACE_GC h$marked = 0; - TRACE_GC("gc: " + (t!==null?h$threadString(t):"null")); + TRACE_GC("gc: " + (t!==null?h$threadString(t):"null")) var start = Date.now(); #endif - TRACE_GC("full gc of thread " + h$threadString(t)); + TRACE_GC("full gc of thread " + h$threadString(t)) h$resetRegisters(); h$resetResultVars(); h$gcMark = 5-h$gcMark; @@ -194,7 +194,7 @@ function h$gc(t) { var a = h$extensibleRetentionRoots[i](h$gcMark); if(a) h$follow(a, a.length-1); } - TRACE_GC("scanning threads, runnable: " + h$threads.length() + " blocked: " + h$blocked.size() + " t: " + t); + TRACE_GC("scanning threads, runnable: " + h$threads.length() + " blocked: " + h$blocked.size() + " t: " + t) // mark al runnable threads and the running thread if(t !== null) { @@ -218,11 +218,11 @@ function h$gc(t) { } h$resetThread(nt); } - TRACE_GC("scanning permanent retention roots"); + TRACE_GC("scanning permanent retention roots") iter = h$extraRoots.iter(); while((nt = iter.next()) !== null) h$follow(nt.root); - TRACE_GC("scanning stable pointers"); + TRACE_GC("scanning stable pointers") for(i=0;i 0) { - TRACE_GC("work length: " + work.length + " w: " + w); + TRACE_GC("work length: " + work.length + " w: " + w) c = work[--w]; - TRACE_GC("[" + work.length + "] mark step: " + typeof c); + TRACE_GC("[" + work.length + "] mark step: " + typeof c) #ifdef GHCJS_TRACE_GC if(typeof c === 'object') { if(c !== null) { - TRACE_GC("object: " + c.toString()); - TRACE_GC("object props: " + h$collectProps(c)); - TRACE_GC("object mark: " + c.m + " (" + typeof(c.m) + ") (current: " + mark + ")"); + TRACE_GC("object: " + c.toString()) + TRACE_GC("object props: " + h$collectProps(c)) + TRACE_GC("object mark: " + c.m + " (" + typeof(c.m) + ") (current: " + mark + ")") } else { - TRACE_GC("object: " + c); + TRACE_GC("object: " + c) } } #endif if(c !== null && c !== undefined && typeof c === 'object' && ((typeof c.m === 'number' && (c.m&3) !== mark) || (typeof c.m === 'object' && c.m !== null && typeof c.m.m === 'number' && (c.m.m&3) !== mark))) { var doMark = false; var cf = c.f; - TRACE_GC("first accepted"); + TRACE_GC("first accepted") if(typeof cf === 'function' && (typeof c.m === 'number' || typeof c.m === 'object')) { - TRACE_GC("marking heap object: " + c.f.n + " size: " + c.f.size); + TRACE_GC("marking heap object: " + c.f.n + " size: " + c.f.size) // only change the two least significant bits for heap objects MARK_OBJ(c); // dynamic references @@ -440,16 +440,16 @@ function h$follow(obj, sp) { // static references var s = cf.s; if(s !== null) { - TRACE_GC("adding static marks"); + TRACE_GC("adding static marks") for(var i=0;i=0;i--) { @@ -498,7 +498,7 @@ function h$follow(obj, sp) { } else if(c instanceof h$Transaction) { // - the accessed TVar values don't need to be marked // - parents are also on the stack, so they should've been marked already - TRACE_GC("marking STM transaction"); + TRACE_GC("marking STM transaction") MARK_OBJ(c); for(i=c.invariants.length-1;i>=0;i--) { ADDW(c.invariants[i].action); @@ -511,7 +511,7 @@ function h$follow(obj, sp) { } else if(c instanceof Array && c.__ghcjsArray) { // only for Haskell arrays with lifted values MARK_OBJ(c); - TRACE_GC("marking array"); + TRACE_GC("marking array") for(i=0;in;j++) { @@ -442,15 +442,15 @@ function h$initInfoTables ( depth // depth in the base chain } break; case 8: // staticEmptyList - TRACE_META("staticEmptyList"); + TRACE_META("staticEmptyList") o.f = HS_NIL_CON; break; case 9: // staticList - TRACE_META("staticList"); + TRACE_META("staticList") n = next(); var hasTail = next(); var c = (hasTail === 1) ? nextObj() : HS_NIL; - TRACE_META("list length: " + n); + TRACE_META("list length: " + n) while(n--) { c = MK_CONS(nextArg(), c); } @@ -459,51 +459,51 @@ function h$initInfoTables ( depth // depth in the base chain o.d2 = c.d2; break; case 10: // staticData n args - TRACE_META("staticData"); + TRACE_META("staticData") n = next(); - TRACE_META("args: " + n); + TRACE_META("args: " + n) o.f = nextEntry(); for(j=0;j slot:" + slot); + TRACE_STABLEPTR(" -> slot:" + slot) h$stablePtrData[slot] = v; return slot << 2; } @@ -59,7 +59,7 @@ function h$deRefStablePtr(stable_o) { function h$hs_free_stable_ptr(stable_d, stable_o) { var slot = stable_o >> 2; - TRACE_STABLEPTR("hs_free_stable_ptr"); + TRACE_STABLEPTR("hs_free_stable_ptr") if(h$stablePtrData[slot] !== null) { h$stablePtrData[slot] = null; h$stablePtrFree.push(slot); @@ -68,8 +68,8 @@ function h$hs_free_stable_ptr(stable_d, stable_o) { // not strictly stableptr, but we make it work only for stable pointers function h$addrToAny(addr_v, addr_o) { - TRACE_STABLEPTR("addrToAny"); - TRACE_STABLEPTR(addr_v === h$stablePtrBuf); + TRACE_STABLEPTR("addrToAny") + TRACE_STABLEPTR(addr_v === h$stablePtrBuf) var slot = addr_o >> 2; return h$stablePtrData[slot]; } ===================================== rts/js/stm.js ===================================== @@ -19,7 +19,7 @@ var h$stmTransactionActive = 0; var h$stmTransactionWaiting = 4; /** @constructor */ function h$Transaction(o, parent) { - TRACE_STM("h$Transaction: " + o + " -> " + parent); + TRACE_STM("h$Transaction: " + o + " -> " + parent) this.action = o; // h$TVar -> h$WrittenTVar, transaction-local changed values this.tvars = new h$Map(); @@ -42,7 +42,7 @@ function h$WrittenTVar(tv,v) { var h$TVarN = 0; /** @constructor */ function h$TVar(v) { - TRACE_STM("creating TVar, value: " + h$collectProps(v)); + TRACE_STM("creating TVar, value: " + h$collectProps(v)) this.val = v; // current value this.blocked = new h$Set(); // threads that get woken up if this TVar is updated this.m = 0; // gc mark @@ -63,7 +63,7 @@ function h$TVarsWaiting(s) { // local view of a TVar /** @constructor */ function h$LocalTVar(v) { - TRACE_STM("creating TVar view for: " + h$collectProps(v)); + TRACE_STM("creating TVar view for: " + h$collectProps(v)) this.readVal = v.val; // the value when read from environment this.val = v.val; // the current uncommitted value this.tvar = v; @@ -75,7 +75,7 @@ function h$atomically(o) { } function h$stmStartTransaction(o) { - TRACE_STM("starting transaction: " + h$collectProps(o)); + TRACE_STM("starting transaction: " + h$collectProps(o)) var t = new h$Transaction(o, null); h$currentThread.transaction = t; h$r1 = o; @@ -89,7 +89,7 @@ function h$stmCommitTransaction() { var tvs = t.tvars; var wtv, i = tvs.iter(); if(t.parent === null) { // top-level commit - TRACE_STM("committing top-level transaction"); + TRACE_STM("committing top-level transaction") // write new value to TVars and collect blocked threads var thread, threadi, blockedThreads = new h$Set(); while((wtv = i.nextVal()) !== null) { @@ -102,7 +102,7 @@ function h$stmCommitTransaction() { h$wakeupThread(thread); } } else { // commit subtransaction - TRACE_STM("committing subtransaction"); + TRACE_STM("committing subtransaction") var tpvs = t.parent.tvars; while((wtv = i.nextVal()) !== null) tpvs.put(wtv.tvar, wtv); } @@ -161,7 +161,7 @@ function h$stmSuspendRetry() { var tv, i = h$currentThread.transaction.accessed.iter(); var tvs = new h$Set(); while((tv = i.next()) !== null) { - TRACE_STM("h$stmSuspendRetry, accessed: " + h$collectProps(tv)); + TRACE_STM("h$stmSuspendRetry, accessed: " + h$collectProps(tv)) tv.blocked.add(h$currentThread); tvs.add(tv); } @@ -212,17 +212,17 @@ function h$readLocalTVar(t, tv) { while(t0 !== null) { var v = t0.tvars.get(tv); if(v !== null) { - TRACE_STM("h$readLocalTVar: found locally modified value: " + h$collectProps(v)); + TRACE_STM("h$readLocalTVar: found locally modified value: " + h$collectProps(v)) return v.val; } t0 = t0.parent; } var lv = t.accessed.get(tv); if(lv !== null) { - TRACE_STM("h$readLocalTVar: found TVar value: " + h$collectProps(lv)); + TRACE_STM("h$readLocalTVar: found TVar value: " + h$collectProps(lv)) return lv.val; } else { - TRACE_STM("h$readLocalTVar: TVar value not found, adding: " + h$collectProps(tv)); + TRACE_STM("h$readLocalTVar: TVar value not found, adding: " + h$collectProps(tv)) t.accessed.put(tv, new h$LocalTVar(tv)); return tv.val; } @@ -238,7 +238,7 @@ function h$setLocalTVar(t, tv, v) { } function h$stmCommitTVar(tv, v, threads) { - TRACE_STM("committing tvar: " + tv._key + " " + (v === tv.val)); + TRACE_STM("committing tvar: " + tv._key + " " + (v === tv.val)) if(v !== tv.val) { var thr, iter = tv.blocked.iter(); while((thr = iter.next()) !== null) threads.add(thr); ===================================== rts/js/thread.js ===================================== @@ -135,14 +135,14 @@ function h$fork(a, inherit) { function h$forkThread(a, inherit) { var t = new h$Thread(); - TRACE_SCHEDULER("sched: forking: " + h$threadString(t)); + TRACE_SCHEDULER("sched: forking: " + h$threadString(t)) if(inherit && h$currentThread) { t.mask = h$currentThread.mask; } #ifdef GHCJS_PROF t.ccs = h$CCS_MAIN; #endif - // TRACE_SCHEDULER("sched: action forked: " + a.f.n); + // TRACE_SCHEDULER("sched: action forked: " + a.f.n) t.stack[4] = h$ap_1_0; t.stack[5] = a; t.stack[6] = h$return; @@ -173,7 +173,7 @@ var h$delayed = new h$HeapSet(); function h$wakeupDelayed(now) { while(h$delayed.size() > 0 && h$delayed.peekPrio() < now) { var t = h$delayed.pop(); - TRACE_SCHEDULER("delay timeout expired: " + t.tid); + TRACE_SCHEDULER("delay timeout expired: " + t.tid) // might have been woken up early, don't wake up again in that case if(t.delayed) { t.delayed = false; @@ -193,7 +193,7 @@ function h$sleep(secs) { function h$delayThreadMs(ms) { var now = Date.now(); - TRACE_SCHEDULER("delaying " + h$threadString(h$currentThread) + " " + ms + "ms (" + (now+ms) + ")"); + TRACE_SCHEDULER("delaying " + h$threadString(h$currentThread) + " " + ms + "ms (" + (now+ms) + ")") h$delayed.add(now+ms, h$currentThread); h$currentThread.delayed = true; h$currentThread.interruptible = true; @@ -219,7 +219,7 @@ function h$yield() { // raise the async exception in the thread if not masked function h$killThread(t, ex) { - TRACE_SCHEDULER("killThread: " + h$threadString(t)); + TRACE_SCHEDULER("killThread: " + h$threadString(t)) if(t === h$currentThread) { // if target is self, then throw even if masked h$sp += 2; @@ -227,7 +227,7 @@ function h$killThread(t, ex) { h$stack[h$sp] = h$return; return h$throw(ex,true); } else { - TRACE_SCHEDULER("killThread mask: " + t.mask); + TRACE_SCHEDULER("killThread mask: " + t.mask) if(t.mask === 0 || (t.mask === 2 && t.interruptible)) { if(t.stack) { // finished threads don't have a stack anymore h$forceWakeupThread(t); @@ -252,12 +252,12 @@ function h$killThread(t, ex) { } function h$maskStatus() { - TRACE_SCHEDULER("mask status: " + h$currentThread.mask); + TRACE_SCHEDULER("mask status: " + h$currentThread.mask) return h$currentThread.mask; } function h$maskAsync(a) { - TRACE_SCHEDULER("mask: thread " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("mask: thread " + h$threadString(h$currentThread)) if(h$currentThread.mask !== 2) { if(h$currentThread.mask === 0 && h$stack[h$sp] !== h$maskFrame && h$stack[h$sp] !== h$maskUnintFrame) { h$stack[++h$sp] = h$unmaskFrame; @@ -272,7 +272,7 @@ function h$maskAsync(a) { } function h$maskUnintAsync(a) { - TRACE_SCHEDULER("mask unint: thread " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("mask unint: thread " + h$threadString(h$currentThread)) if(h$currentThread.mask !== 1) { if(h$currentThread.mask === 2) { h$stack[++h$sp] = h$maskFrame; @@ -286,7 +286,7 @@ function h$maskUnintAsync(a) { } function h$unmaskAsync(a) { - TRACE_SCHEDULER("unmask: " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("unmask: " + h$threadString(h$currentThread)) if(h$currentThread.excep.length > 0) { h$currentThread.mask = 0; h$sp += 3; @@ -320,7 +320,7 @@ function h$pendingAsync() { function h$postAsync(alreadySuspended,next) { var t = h$currentThread; var v = t.excep.shift(); - TRACE_SCHEDULER("posting async to " + h$threadString(t) + " mask status: " + t.mask + " remaining exceptions: " + t.excep.length); + TRACE_SCHEDULER("posting async to " + h$threadString(t) + " mask status: " + t.mask + " remaining exceptions: " + t.excep.length) var tposter = v[0]; // posting thread, blocked var ex = v[1]; // the exception if(v !== null && tposter !== null) { @@ -338,7 +338,7 @@ function h$postAsync(alreadySuspended,next) { // wakeup thread, thread has already been removed // from any queues it was blocked on function h$wakeupThread(t) { - TRACE_SCHEDULER("sched: waking up: " + h$threadString(t)); + TRACE_SCHEDULER("sched: waking up: " + h$threadString(t)) if(t.status === THREAD_BLOCKED) { t.blockedOn = null; t.status = THREAD_RUNNING; @@ -353,7 +353,7 @@ function h$wakeupThread(t) { // force wakeup, remove this thread from any // queue it's blocked on function h$forceWakeupThread(t) { - TRACE_SCHEDULER("forcing wakeup of: " + h$threadString(t)); + TRACE_SCHEDULER("forcing wakeup of: " + h$threadString(t)) if(t.status === THREAD_BLOCKED) { h$removeThreadBlock(t); h$wakeupThread(t); @@ -371,8 +371,8 @@ function h$removeThreadBlock(t) { h$delayed.remove(t); t.delayed = false; } else if(o instanceof h$MVar) { - TRACE_SCHEDULER("blocked on MVar"); - TRACE_SCHEDULER("MVar before: " + o.readers.length() + " " + o.writers.length() + " " + o.waiters.length); + TRACE_SCHEDULER("blocked on MVar") + TRACE_SCHEDULER("MVar before: " + o.readers.length() + " " + o.writers.length() + " " + o.waiters.length) // fixme this is rather inefficient var r, rq = new h$Queue(); while((r = o.readers.dequeue()) !== null) { @@ -392,13 +392,13 @@ function h$removeThreadBlock(t) { } o.waiters = wa; } - TRACE_SCHEDULER("MVar after: " + o.readers.length() + " " + o.writers.length() + " " + o.waiters.length); + TRACE_SCHEDULER("MVar after: " + o.readers.length() + " " + o.writers.length() + " " + o.waiters.length) /* } else if(o instanceof h$Fd) { - TRACE_SCHEDULER("blocked on fd"); + TRACE_SCHEDULER("blocked on fd") h$removeFromArray(o.waitRead,t); h$removeFromArray(o.waitWrite,t); */ } else if(o instanceof h$Thread) { - TRACE_SCHEDULER("blocked on async exception"); + TRACE_SCHEDULER("blocked on async exception") // set thread (first in pair) to null, exception will still be delivered // but this thread not woken up again // fixme: are these the correct semantics? @@ -411,7 +411,7 @@ function h$removeThreadBlock(t) { } else if (o instanceof h$TVarsWaiting) { h$stmRemoveBlockedThread(o, t) } else if(IS_BLACKHOLE(o)) { - TRACE_SCHEDULER("blocked on blackhole"); + TRACE_SCHEDULER("blocked on blackhole") h$removeFromArray(BLACKHOLE_QUEUE(o),t); } else { throw ("h$removeThreadBlock: blocked on unknown object: " + h$collectProps(o)); @@ -432,7 +432,7 @@ function h$removeFromArray(a,o) { } function h$finishThread(t) { - TRACE_SCHEDULER("sched: finishing: " + h$threadString(t)); + TRACE_SCHEDULER("sched: finishing: " + h$threadString(t)) t.status = THREAD_FINISHED; h$blocked.remove(t); t.stack = null; @@ -448,7 +448,7 @@ function h$finishThread(t) { } function h$blockThread(t,o,resume) { - TRACE_SCHEDULER("sched: blocking: " + h$threadString(t)); + TRACE_SCHEDULER("sched: blocking: " + h$threadString(t)) if(t !== h$currentThread) { throw "h$blockThread: blocked thread is not the current thread"; } @@ -469,7 +469,7 @@ function h$blockThread(t,o,resume) { var h$lastGc = Date.now(); var h$gcInterval = GHCJS_GC_INTERVAL; // ms function h$scheduler(next) { - TRACE_SCHEDULER("sched: scheduler: " + h$sp); + TRACE_SCHEDULER("sched: scheduler: " + h$sp) // if we have a running synchronous thread, the only thing we can do is continue if(h$currentThread && h$currentThread.isSynchronous && @@ -481,7 +481,7 @@ function h$scheduler(next) { // find the next runnable thread in the run queue // remove non-runnable threads if(h$currentThread && h$pendingAsync()) { - TRACE_SCHEDULER("sched: received async exception, continuing thread"); + TRACE_SCHEDULER("sched: received async exception, continuing thread") if(h$currentThread.status !== THREAD_RUNNING) { h$forceWakeupThread(h$currentThread); h$currentThread.status = THREAD_RUNNING; @@ -495,7 +495,7 @@ function h$scheduler(next) { } // if no other runnable threads, just continue current (if runnable) if(t === null) { - TRACE_SCHEDULER("sched: no other runnable threads"); + TRACE_SCHEDULER("sched: no other runnable threads") if(h$currentThread && h$currentThread.status === THREAD_RUNNING) { // do gc after a while if(now - h$lastGc > h$gcInterval) { @@ -518,10 +518,10 @@ function h$scheduler(next) { h$stack = h$currentThread.stack; h$sp = h$currentThread.sp } - TRACE_SCHEDULER("sched: continuing: " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("sched: continuing: " + h$threadString(h$currentThread)) return (next===h$reschedule || next === null)?h$stack[h$sp]:next; // just continue } else { - TRACE_SCHEDULER("sched: pausing"); + TRACE_SCHEDULER("sched: pausing") h$currentThread = null; #ifdef GHCJS_PROF h$reportCurrentCcs(); @@ -534,23 +534,23 @@ function h$scheduler(next) { return null; // pause the haskell runner } } else { // runnable thread in t, switch to it - TRACE_SCHEDULER("sched: switching to: " + h$threadString(t)); + TRACE_SCHEDULER("sched: switching to: " + h$threadString(t)) if(h$currentThread !== null) { if(h$currentThread.status === THREAD_RUNNING) { h$threads.enqueue(h$currentThread); } // if h$reschedule called, thread takes care of suspend if(next !== h$reschedule && next !== null) { - TRACE_SCHEDULER("sched: suspending: " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("sched: suspending: " + h$threadString(h$currentThread)) // suspend thread: push h$restoreThread stack frame h$suspendCurrentThread(next); } else { - TRACE_SCHEDULER("sched: no suspend needed, reschedule called from: " + h$threadString(h$currentThread)); + TRACE_SCHEDULER("sched: no suspend needed, reschedule called from: " + h$threadString(h$currentThread)) h$currentThread.sp = h$sp; } if(h$pendingAsync()) h$postAsync(true, next); } else { - TRACE_SCHEDULER("sched: no suspend needed, no running thread"); + TRACE_SCHEDULER("sched: no suspend needed, no running thread") } // gc if needed if(now - h$lastGc > h$gcInterval) { @@ -567,22 +567,22 @@ function h$scheduler(next) { #ifdef GHCJS_PROF h$reportCurrentCcs(); #endif - TRACE_SCHEDULER("sched: scheduling " + h$threadString(t) + " sp: " + h$sp); - // TRACE_SCHEDULER("sp thing: " + h$stack[h$sp].n); + TRACE_SCHEDULER("sched: scheduling " + h$threadString(t) + " sp: " + h$sp) + // TRACE_SCHEDULER("sp thing: " + h$stack[h$sp].n) // h$dumpStackTop(h$stack,0,h$sp); return h$stack[h$sp]; } } function h$scheduleMainLoop() { - TRACE_SCHEDULER("scheduling next main loop wakeup"); + TRACE_SCHEDULER("scheduling next main loop wakeup") if(h$mainLoopImmediate) return; h$clearScheduleMainLoop(); if(h$delayed.size() === 0) { #ifndef GHCJS_BROWSER if(typeof setTimeout !== 'undefined') { #endif - TRACE_SCHEDULER("scheduling main loop wakeup in " + h$gcInterval + "ms"); + TRACE_SCHEDULER("scheduling main loop wakeup in " + h$gcInterval + "ms") h$mainLoopTimeout = setTimeout(h$mainLoop, h$gcInterval); #ifndef GHCJS_BROWSER } @@ -595,7 +595,7 @@ function h$scheduleMainLoop() { if(typeof setTimeout !== 'undefined') { #endif if(delay >= 1) { - TRACE_SCHEDULER("scheduling main loop wakeup in " + delay + "ms"); + TRACE_SCHEDULER("scheduling main loop wakeup in " + delay + "ms") // node.js 0.10.30 has trouble with non-integral delays h$mainLoopTimeout = setTimeout(h$mainLoop, Math.round(delay)); } else { @@ -627,7 +627,7 @@ function h$clearScheduleMainLoop() { } function h$startMainLoop() { - TRACE_SCHEDULER("start main loop: " + h$running); + TRACE_SCHEDULER("start main loop: " + h$running) if(h$running) return; #ifndef GHCJS_BROWSER if(typeof setTimeout !== 'undefined') { @@ -706,7 +706,7 @@ function h$actualMainLoop() { } // yield to js after h$busyYield (default value GHCJS_BUSY_YIELD) if(!h$currentThread.isSynchronous && Date.now() - start > h$busyYield) { - TRACE_SCHEDULER("yielding to js"); + TRACE_SCHEDULER("yielding to js") if(c !== h$reschedule) h$suspendCurrentThread(c); h$nextThread = h$currentThread; h$currentThread = null; @@ -821,7 +821,7 @@ function h$reportMainLoopException(e, isMainThread) { function h$handleBlockedSyncThread(c) { - TRACE_SCHEDULER("handling blocked sync thread"); + TRACE_SCHEDULER("handling blocked sync thread") /* if we have a blocked synchronous/non-preemptible thread, and it's blocked on a black hole, first try to clear @@ -831,7 +831,7 @@ function h$handleBlockedSyncThread(c) { if(h$currentThread.status === THREAD_BLOCKED && IS_BLACKHOLE(bo) && h$runBlackholeThreadSync(bo)) { - TRACE_SCHEDULER("blackhole succesfully removed"); + TRACE_SCHEDULER("blackhole succesfully removed") c = h$stack[h$sp]; } /* @@ -843,7 +843,7 @@ function h$handleBlockedSyncThread(c) { h$currentThread.isSynchronous = false; h$currentThread.continueAsync = false; } else if(h$currentThread.isSynchronous) { - TRACE_SCHEDULER("blocking synchronous thread: exception"); + TRACE_SCHEDULER("blocking synchronous thread: exception") h$sp += 2; h$currentThread.sp = h$sp; h$stack[h$sp-1] = h$baseZCGHCziJSziPrimziInternalziwouldBlock; @@ -858,7 +858,7 @@ function h$handleBlockedSyncThread(c) { // run the supplied IO action in a new thread // returns immediately, thread is started in background function h$run(a) { - TRACE_SCHEDULER("sched: starting thread"); + TRACE_SCHEDULER("sched: starting thread") var t = h$forkThread(a, false); h$startMainLoop(); return t; @@ -917,7 +917,7 @@ function h$setCurrentThreadResultValue(v) { */ function h$runSyncReturn(a, cont) { var t = new h$Thread(); - TRACE_SCHEDULER("h$runSyncReturn created thread: " + h$threadString(t)); + TRACE_SCHEDULER("h$runSyncReturn created thread: " + h$threadString(t)) var aa = MK_AP1(h$baseZCGHCziJSziPrimziInternalzisetCurrentThreadResultValue, a); h$runSyncAction(t, aa, cont); if(t.status === THREAD_FINISHED) { @@ -946,7 +946,7 @@ function h$runSyncReturn(a, cont) { */ function h$runSync(a, cont) { var t = new h$Thread(); - TRACE_SCHEDULER("h$runSync created thread: " + h$threadString(t)); + TRACE_SCHEDULER("h$runSync created thread: " + h$threadString(t)) h$runSyncAction(t, a, cont); if(t.resultIsException) { if(t.result instanceof h$WouldBlock) { @@ -1017,7 +1017,7 @@ function h$runSyncAction(t, a, cont) { // run other threads synchronously until the blackhole is 'freed' // returns true for success, false for failure, a thread blocks function h$runBlackholeThreadSync(bh) { - TRACE_SCHEDULER("trying to remove black hole"); + TRACE_SCHEDULER("trying to remove black hole") var ct = h$currentThread; var sp = h$sp; var success = false; @@ -1026,7 +1026,7 @@ function h$runBlackholeThreadSync(bh) { // we don't handle async exceptions here, // don't run threads with pending exceptions if(BLACKHOLE_TID(bh).excep.length > 0) { - TRACE_SCHEDULER("aborting due to queued async exceptions"); + TRACE_SCHEDULER("aborting due to queued async exceptions") return false; } h$currentThread = BLACKHOLE_TID(bh); @@ -1036,7 +1036,7 @@ function h$runBlackholeThreadSync(bh) { h$reportCurrentCcs(); #endif var c = (h$currentThread.status === THREAD_RUNNING)?h$stack[h$sp]:h$reschedule; - TRACE_SCHEDULER("switched thread status running: " + (h$currentThread.status === THREAD_RUNNING)); + TRACE_SCHEDULER("switched thread status running: " + (h$currentThread.status === THREAD_RUNNING)) try { while(true) { while(c !== h$reschedule && IS_BLACKHOLE(currentBh)) { @@ -1050,7 +1050,7 @@ function h$runBlackholeThreadSync(bh) { // perhaps new blackhole, then continue with that thread, // otherwise fail if(IS_BLACKHOLE(h$currentThread.blockedOn)) { - TRACE_SCHEDULER("following another black hole"); + TRACE_SCHEDULER("following another black hole") bhs.push(currentBh); currentBh = h$currentThread.blockedOn; h$currentThread = BLACKHOLE_TID(h$currentThread.blockedOn); @@ -1064,15 +1064,15 @@ function h$runBlackholeThreadSync(bh) { #endif c = (h$currentThread.status === THREAD_RUNNING)?h$stack[h$sp]:h$reschedule; } else { - TRACE_SCHEDULER("thread blocked on something that's not a black hole, failing"); + TRACE_SCHEDULER("thread blocked on something that's not a black hole, failing") break; } } else { // blackhole updated: suspend thread and pick up the old one - TRACE_SCHEDULER("blackhole updated, switching back (" + h$sp + ")"); - TRACE_SCHEDULER("next: " + c.toString()); + TRACE_SCHEDULER("blackhole updated, switching back (" + h$sp + ")") + TRACE_SCHEDULER("next: " + c.toString()) h$suspendCurrentThread(c); if(bhs.length > 0) { - TRACE_SCHEDULER("to next black hole"); + TRACE_SCHEDULER("to next black hole") currentBh = bhs.pop(); h$currentThread = BLACKHOLE_TID(currentBh); h$stack = h$currentThread.stack; @@ -1081,7 +1081,7 @@ function h$runBlackholeThreadSync(bh) { h$reportCurrentCcs(); #endif } else { - TRACE_SCHEDULER("last blackhole removed, success!"); + TRACE_SCHEDULER("last blackhole removed, success!") success = true; break; } @@ -1111,7 +1111,7 @@ function h$main(a) { #ifdef GHCJS_PROF t.ccs = a.cc; #endif - //TRACE_SCHEDULER("sched: starting main thread"); + //TRACE_SCHEDULER("sched: starting main thread") t.stack[0] = h$doneMain_e; #ifndef GHCJS_BROWSER if(!h$isBrowser() && !h$isGHCJSi()) { @@ -1186,7 +1186,7 @@ function h$exitProcess(code) { var h$mvarId = 0; /** @constructor */ function h$MVar() { - TRACE_SCHEDULER("h$MVar constructor"); + TRACE_SCHEDULER("h$MVar constructor") this.val = null; this.readers = new h$Queue(); this.writers = new h$Queue(); @@ -1204,17 +1204,17 @@ function h$notifyMVarEmpty(mv) { if(w !== null) { var thread = w[0]; var val = w[1]; - TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): writer ready: " + h$threadString(thread)); + TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): writer ready: " + h$threadString(thread)) mv.val = val; // thread is null if some JavaScript outside Haskell wrote to the MVar if(thread !== null) { h$wakeupThread(thread); } } else { - TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): no writers"); + TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): no writers") mv.val = null; } - TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): " + mv.val); + TRACE_SCHEDULER("notifyMVarEmpty(" + mv.id + "): " + mv.val) } // set the MVar to val unless there are readers @@ -1222,7 +1222,7 @@ function h$notifyMVarFull(mv,val) { if(mv.waiters && mv.waiters.length > 0) { for(var i=0;i 0) { var t = new h$Thread(); @@ -41,7 +41,7 @@ function h$Weak(key, val, finalizer) { if(typeof key !== 'object') { // can't attach a StableName to objects with unboxed storage // our weak ref will be finalized soon. - TRACE_WEAK("WARNING: making weak for object with unboxed storage"); + TRACE_WEAK("WARNING: making weak for object with unboxed storage") this.keym = new h$StableName(0); } else { if(typeof key.m !== 'object') { @@ -52,7 +52,7 @@ function h$Weak(key, val, finalizer) { } this.keym = key.m; } - TRACE_WEAK("making weak of: " + h$stableNameInt(this.keym)); + TRACE_WEAK("making weak of: " + h$stableNameInt(this.keym)) this.keym = key.m; this.val = val; this.finalizer = null; @@ -68,17 +68,17 @@ function h$Weak(key, val, finalizer) { } function h$makeWeak(key, val, fin) { - TRACE_WEAK("h$makeWeak"); + TRACE_WEAK("h$makeWeak") return new h$Weak(key, val, fin) } function h$makeWeakNoFinalizer(key, val) { - TRACE_WEAK("h$makeWeakNoFinalizer"); + TRACE_WEAK("h$makeWeakNoFinalizer") return new h$Weak(key, val, null); } function h$finalizeWeak(w) { - TRACE_WEAK("finalizing weak of " + h$stableNameInt(w.keym)); + TRACE_WEAK("finalizing weak of " + h$stableNameInt(w.keym)) w.val = null; if(w.finalizer === null || w.finalizer.finalizer === null) { RETURN_UBX_TUP2(null, 0); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af7f81f8e25074070caf6cb82925f198b4eff315 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af7f81f8e25074070caf6cb82925f198b4eff315 You're receiving 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 Oct 14 13:45:37 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 09:45:37 -0400 Subject: [Git][ghc/ghc][wip/js-staging] RTS: less semicolons Message-ID: <6349680174595_8b90f514287397@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 5e13ecc8 by Sylvain Henry at 2022-10-14T15:49:01+02:00 RTS: less semicolons - - - - - 1 changed file: - rts/js/profiling.js Changes: ===================================== rts/js/profiling.js ===================================== @@ -8,13 +8,13 @@ function assert(condition, message) { console.trace(message || "Assertion failed"); } } -#define ASSERT(args...) assert(args) +#define ASSERT(args...) { assert(args); } #else #define ASSERT(args...) #endif #ifdef GHCJS_TRACE_PROF -#define TRACE(args...) h$log(args) +#define TRACE(args...) { h$log(args); } #else #define TRACE(args...) #endif @@ -64,7 +64,7 @@ var h$ccsList = []; var h$CCUnique = 0; /** @constructor */ function h$CC(label, module, srcloc, isCaf) { - //TRACE("h$CC(", label, ", ", module, ", ", srcloc, ", ", isCaf, ")"); + //TRACE("h$CC(", label, ", ", module, ", ", srcloc, ", ", isCaf, ")") this.label = label; this.module = module; this.srcloc = srcloc; @@ -80,7 +80,7 @@ function h$CC(label, module, srcloc, isCaf) { var h$CCSUnique = 0; /** @constructor */ function h$CCS(parent, cc) { - //TRACE("h$mkCCS(", parent, cc, ")"); + //TRACE("h$mkCCS(", parent, cc, ")") if (parent !== null && parent.consed.has(cc)) { return (parent.consed.get(cc)); } @@ -152,7 +152,7 @@ function h$ccsString(ccs) { #endif function h$pushRestoreCCS() { - TRACE("push restoreccs:" + h$ccsString(h$currentThread.ccs)); + TRACE("push restoreccs:" + h$ccsString(h$currentThread.ccs)) if(h$stack[h$sp] !== h$setCcs_e) { h$sp += 2; h$stack[h$sp-1] = h$currentThread.ccs; @@ -161,15 +161,15 @@ function h$pushRestoreCCS() { } function h$restoreCCS(ccs) { - TRACE("restoreccs from:", h$ccsString(h$currentThread.ccs)); - TRACE(" to:", h$ccsString(ccs)); + TRACE("restoreccs from:", h$ccsString(h$currentThread.ccs)) + TRACE(" to:", h$ccsString(ccs)) h$currentThread.ccs = ccs; h$reportCurrentCcs(); } function h$enterThunkCCS(ccsthunk) { - ASSERT(ccsthunk !== null && ccsthunk !== undefined, "ccsthunk is null or undefined"); - TRACE("entering ccsthunk:", h$ccsString(ccsthunk)); + ASSERT(ccsthunk !== null && ccsthunk !== undefined, "ccsthunk is null or undefined") + TRACE("entering ccsthunk:", h$ccsString(ccsthunk)) h$currentThread.ccs = ccsthunk; h$reportCurrentCcs(); } @@ -177,10 +177,10 @@ function h$enterThunkCCS(ccsthunk) { function h$enterFunCCS(ccsapp, // stack at call site ccsfn // stack of function ) { - ASSERT(ccsapp !== null && ccsapp !== undefined, "ccsapp is null or undefined"); - ASSERT(ccsfn !== null && ccsfn !== undefined, "ccsfn is null or undefined"); - TRACE("ccsapp:", h$ccsString(ccsapp)); - TRACE("ccsfn:", h$ccsString(ccsfn)); + ASSERT(ccsapp !== null && ccsapp !== undefined, "ccsapp is null or undefined") + ASSERT(ccsfn !== null && ccsfn !== undefined, "ccsfn is null or undefined") + TRACE("ccsapp:", h$ccsString(ccsapp)) + TRACE("ccsfn:", h$ccsString(ccsfn)) // common case 1: both stacks are the same if (ccsapp === ccsfn) { @@ -243,22 +243,22 @@ function h$appendCCS(ccs1, ccs2) { function h$enterFunCurShorter(ccsapp, ccsfn, n) { if (n === 0) { - ASSERT(ccsapp.length === ccsfn.length, "ccsapp.length !== ccsfn.length"); + ASSERT(ccsapp.length === ccsfn.length, "ccsapp.length !== ccsfn.length") return h$enterFunEqualStacks(ccsapp, ccsapp, ccsfn); } else { - ASSERT(ccsfn.depth > ccsapp.depth, "ccsfn.depth <= ccsapp.depth"); + ASSERT(ccsfn.depth > ccsapp.depth, "ccsfn.depth <= ccsapp.depth") return h$pushCostCentre(h$enterFunCurShorter(ccsapp, ccsfn.prevStack, n-1), ccsfn.cc); } } function h$enterFunEqualStacks(ccs0, ccsapp, ccsfn) { - ASSERT(ccsapp.depth === ccsfn.depth, "ccsapp.depth !== ccsfn.depth"); + ASSERT(ccsapp.depth === ccsfn.depth, "ccsapp.depth !== ccsfn.depth") if (ccsapp === ccsfn) return ccs0; return h$pushCostCentre(h$enterFunEqualStacks(ccs0, ccsapp.prevStack, ccsfn.prevStack), ccsfn.cc); } function h$pushCostCentre(ccs, cc) { - TRACE("pushing cost centre", cc.label, "to", h$ccsString(ccs)); + TRACE("pushing cost centre", cc.label, "to", h$ccsString(ccs)) if (ccs === null) { // when is ccs null? return new h$CCS(ccs, cc); @@ -297,7 +297,7 @@ var h$ccsrcloc_offset = 12; // cc->srcloc function h$buildCCPtr(o) { // last used offset is 12, so we need to allocate 20 bytes - ASSERT(o !== null); + ASSERT(o !== null) var cc = h$newByteArray(20); #ifdef GHCJS_TRACE_PROF cc.myTag = "cc pointer"; @@ -310,7 +310,7 @@ function h$buildCCPtr(o) { } function h$buildCCSPtr(o) { - ASSERT(o !== null); + ASSERT(o !== null) // last used offset is 8, allocate 16 bytes var ccs = h$newByteArray(16); #ifdef GHCJS_TRACE_PROF View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e13ecc821b25d6db937be1d8d185c4a48aadd9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e13ecc821b25d6db937be1d8d185c4a48aadd9b You're receiving 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 Oct 14 14:29:13 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 10:29:13 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Only initialize statics once! Message-ID: <6349723990c90_8b90f51428869df@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 2a95716a by Sylvain Henry at 2022-10-14T16:32:26+02:00 Only initialize statics once! - - - - - 1 changed file: - compiler/GHC/StgToJS/Linker/Linker.hs Changes: ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -66,6 +66,8 @@ import qualified GHC.Utils.Ppr as Ppr import GHC.Utils.Monad import GHC.Utils.TmpFs +import GHC.Types.Unique.Set + import qualified GHC.SysTools.Ar as Ar import GHC.Data.FastString @@ -877,14 +879,16 @@ linkModules mods = (compact_mods, meta) -- - rename local variables into shorter ones -- - compress initialization data -- but we haven't ported it (yet). - compact m = CompactedModuleCode { cmc_js_code = mc_js_code m , cmc_module = mc_module m , cmc_exports = mc_exports m } - statics = concatMap mc_statics mods + -- common up statics: different bindings may reference the same statics, we + -- filter them here to initialize them once + statics = nubStaticInfo (concatMap mc_statics mods) + infos = concatMap mc_closures mods meta = mconcat -- render metadata as individual statements @@ -893,6 +897,20 @@ linkModules mods = (compact_mods, meta) , mconcat (map (closureInfoStat True) infos) ] +-- | Only keep a single StaticInfo with a given name +nubStaticInfo :: [StaticInfo] -> [StaticInfo] +nubStaticInfo = go emptyUniqSet + where + go us = \case + [] -> [] + (x:xs) -> + -- only match on siVar. There is no reason for the initializing value to + -- be different for the same global name. + let name = siVar x + in if elementOfUniqSet name us + then go us xs + else x : go (addOneToUniqSet us name) xs + -- | Initialize a global object. -- -- All global objects have to be declared (staticInfoDecl) first. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a95716a5c4133e3fe6c9e1552295823c17e3b49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a95716a5c4133e3fe6c9e1552295823c17e3b49 You're receiving 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 Oct 14 15:09:08 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Fri, 14 Oct 2022 11:09:08 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] 2 commits: alternate prototype of typechecked call translation Message-ID: <63497b942e84b_8b90f517709018c@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: 5cb2aedd by Norman Ramsey at 2022-10-14T10:21:07-04:00 alternate prototype of typechecked call translation - - - - - d18a6b28 by Norman Ramsey at 2022-10-14T11:08:47-04:00 relatively clean type-preserving translation - - - - - 2 changed files: - compiler/GHC/Wasm/IR.hs - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/IR.hs ===================================== @@ -17,10 +17,17 @@ module GHC.Wasm.IR , WasmType(..), WasmTypeTag(..) , TypeList(..) - , RevAppend, Reverse , WasmFunctionType(..) + , RevAppend, Reverse + , revappTags, reverseTags + + , SymName(..) + + , WasmCall(..) + , wasmCallResultTypesReversed + , wasmCallArgTypesReversed ) where @@ -150,6 +157,12 @@ data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where -> TypeList restys -> SymName -> WasmIR bool (RevAppend argtys '[]) (RevAppend restys '[]) + -- if '[] is generalized to a variable, then the type fails + -- the ambiguity check (RevAppend is non-injective) + + WasmCall' :: WasmCall bool pre post -> WasmIR bool pre post + + WasmCallIndirect :: WasmTypeTag t -- type of function value on stack @@ -160,6 +173,35 @@ data WasmIR :: WasmType -> [WasmType] -> [WasmType] -> Type where WasmNop :: WasmIR bool stack stack -- translation of empty list of expressions +data WasmCall :: WasmType -> [WasmType] -> [WasmType] -> Type where + WasmCallDirect :: SymName -> WasmCall bool stack stack + WasmCallAddResult :: WasmTypeTag t + -> WasmCall bool pre post + -> WasmCall bool pre (t : post) + WasmCallAddArg :: WasmTypeTag t + -> WasmCall bool pre post + -> WasmCall bool (t : pre) post + +wasmCallResultTypesReversed :: WasmCall bool pre post + -> (forall ts . TypeList ts -> a) + -> a +wasmCallResultTypesReversed (WasmCallDirect _) k = k TypeListNil +wasmCallResultTypesReversed (WasmCallAddArg _ call) k = wasmCallResultTypesReversed call k +wasmCallResultTypesReversed (WasmCallAddResult t call) k = + wasmCallResultTypesReversed call $ \ ts -> k (TypeListCons t ts) + +wasmCallArgTypesReversed :: WasmCall bool pre post + -> (forall ts . TypeList ts -> a) + -> a +wasmCallArgTypesReversed (WasmCallDirect _) k = k TypeListNil +wasmCallArgTypesReversed (WasmCallAddResult _ call) k = wasmCallArgTypesReversed call k +wasmCallArgTypesReversed (WasmCallAddArg t call) k = + wasmCallArgTypesReversed call $ \ ts -> k (TypeListCons t ts) + + +data WasmLocals :: [WasmType] -> Type where + WasmNoLocals :: WasmLocals '[] + WasmPopLocal :: WasmTypeTag t -> WasmLocal -> WasmLocals ts -> WasmLocals (t : ts) type RevAppend :: forall a. [a] -> [a] -> [a] type family RevAppend xs ys where @@ -171,7 +213,12 @@ type family Reverse xs where Reverse xs = RevAppend xs '[] +revappTags :: TypeList ts -> TypeList us -> TypeList (RevAppend ts us) +revappTags TypeListNil ys = ys +revappTags (TypeListCons t ts) ys = revappTags ts (TypeListCons t ys) +reverseTags :: TypeList ts -> TypeList (Reverse ts) +reverseTags ts = revappTags ts TypeListNil ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -15,11 +15,16 @@ module GHC.Wasm.Tx , exprs , node + , node' , setLocals , WasmLocal(..) , WasmAction, WasmTopAction + + , addCallResults + , addCallArguments + ) where @@ -31,7 +36,7 @@ import Data.Type.Equality import qualified GHC.Cmm.Type as CT import GHC.Cmm.CLabel - import GHC.Cmm.Expr hiding (node) +import GHC.Cmm.Expr hiding (node) import GHC.Cmm.Node import GHC.Platform import GHC.Utils.Outputable hiding ((<>)) @@ -129,9 +134,22 @@ expr expr k = CmmMachOp (MO_S_Ge w) es -> wasmCompare w es WasmS_Ge k - _ -> panic "unimplemented" + _ -> panic "`expr` is just a demo; only a few cases are implemented" + + +-- | Translate a list of Cmm expressions +exprs :: CG bool codegen + => [CmmExpr] + -> (forall ts . TypeList ts -> WasmExprs bool ts -> codegen bool a) + -> codegen bool a +exprs [] k = k TypeListNil WasmNop +exprs (e:es) k = -- first expression is oldest on stack + exprs es $ \ts codes -> + expr e $ \t code -> + k (TypeListCons t ts) (code <> codes) + ------- Types of all the translation functions +------ Types of all the other translation functions -- | Cmm integer and floating-point literals (with zero operands) @@ -179,7 +197,6 @@ wasmCompare :: wasmNullaryInt w operator k = withIntWidthTag w $ \tag -> k tag (operator tag) - wasmNullaryFloat w operator k = withFloatWidthTag w $ \tag -> k tag (operator tag) @@ -237,40 +254,51 @@ withFloatWidthTag CT.W64 k = k TagF64 withFloatWidthTag w _ = panic $ "width " ++ show w ++ " not supported on wasm target" ----------------------------------------------------------------- --- new and experimental +--------------------------------------------------------------- +-- +-- two different prototypes for calling unsafe C functions -type WasmExprs bool ts = (forall stack . WasmIR bool stack (RevAppend ts stack)) --- | Translate a list of Cmm expressions -exprs :: CG bool codegen - => [CmmExpr] - -> (forall ts . TypeList ts -> WasmExprs bool ts -> codegen bool a) - -> codegen bool a -exprs [] k = k TypeListNil WasmNop -exprs (e:es) k = -- first expression is oldest on stack - exprs es $ \ts codes -> - expr e $ \t code -> - k (TypeListCons t ts) (code <> codes) +-- Prototype 1: Call instruction is limited to empty stack, but +-- the representation of calls is relatively simple + + +-- more special cases of the IR: + +type WasmExprs bool ts = forall stack . WasmIR bool stack (RevAppend ts stack) + +type WasmAction bool = forall stack . WasmIR bool stack stack +type WasmTopAction bool = WasmIR bool '[] '[] -type WasmAction bool = (forall stack . WasmIR bool stack stack) -type WasmTopAction bool = (WasmIR bool '[] '[]) -- | Translate an open-open Cmm node (action) node :: CG bool codegen => CmmNode O O -> (WasmTopAction bool -> codegen bool a) - -- using WasmAction here, I can't get the code to typecheck + -- has to be WasmTopAction, not WasmAction, because the + -- type of the WasmCall instruction would be ambiguous otherwise -- (non-injectivity of RevAppend) -> codegen bool a node (CmmUnsafeForeignCall (ForeignTarget target _cconv) results arguments) k = - -- ran out of time to deal with result registers exprs arguments $ \argtys arg_codes -> localRegs results $ \restys xs -> wasmCall argtys restys target $ \code -> k (arg_codes <> code <> setLocals restys xs) -node _ _ = panic "more cases needed" +node _ _ = panic "`node` is just a demo; only a few cases are implemented" + + +-- | use the CG monad to find the types and locations of local registers + +localRegs :: CG bool codegen + => [LocalReg] + -> (forall ts . TypeList ts -> [WasmLocal] -> codegen bool a) + -> codegen bool a +localRegs [] k = k TypeListNil [] +localRegs (r:rs) k = + localRegs rs $ \ts xs -> + cpsLocalReg r $ \t x -> + k (TypeListCons t ts) (x:xs) -- | Generate a Wasm call to a Cmm expression wasmCall :: CG bool codegen @@ -289,22 +317,93 @@ wasmCall argtypes restypes e k = setLocals :: TypeList ts -> [WasmLocal] -> WasmIR bool (RevAppend ts stack) stack setLocals TypeListNil [] = WasmNop setLocals (TypeListCons t ts) (x:xs) = setLocals ts xs <> WasmSetLocal t x -setLocals _ _ = panic "this can't happen -- rewrite code to make it obvious?" +setLocals _ _ = + panic "this can't happen -- rewrite code to make it obvious to the type checker?" --- | use the CG monad to find the types and locations of local registers -localRegs :: CG bool codegen - => [LocalReg] - -> (forall ts . TypeList ts -> [WasmLocal] -> codegen bool a) - -> codegen bool a -localRegs [] k = k TypeListNil [] -localRegs (r:rs) k = - localRegs rs $ \ts xs -> - cpsLocalReg r $ \t x -> - k (TypeListCons t ts) (x:xs) +---------------------------------------------------------------- +-- +-- Prototype 2: Call instruction has a more complicated +-- representation, but it has a fully general type which is +-- established by the translation. + +node' :: CG bool codegen + => CmmNode O O + -> (forall stack . WasmIR bool stack stack -> codegen bool a) + -> codegen bool a +node' (CmmUnsafeForeignCall (ForeignTarget target _cconv) results arguments) k = + case target of + CmmLit (CmmLabel callee) -> call (symNameFromCLabel callee) arguments results k + _ -> panic "indirect calls aren't implemented yet" +node' _ _ = panic "`node'` is just a demo; only a few cases are implemented" + +-- Here's the idea: start with a "bare" call, then build up the call's +-- argument types and result types incrementally. As each result type +-- is accumulated, the code that pops the result is accumulated as +-- well. Likewise the argument types. This one-for-one matching is +-- what enables the code to typecheck. + +-- | Given a call target and a list of result registers, call a +-- given continuation with an augmented call and a sequence of pops. +-- The `mid` stack is the original stack plus all the results pushed +-- by the call. The `pre` stack is the state of the stack before the +-- first argument is pushed, which is also the state of the stack +-- after the last results is popped. + +addCallResults :: CG bool codegen + => WasmCall bool pre pre + -> [LocalReg] + -> (forall stack mid . + WasmCall bool stack mid -> WasmIR bool mid stack -> codegen bool a) + -> codegen bool a + +addCallResults target [] k = k target WasmNop +addCallResults target (reg:regs) k = + cpsLocalReg reg $ \t x -> + addCallResults target regs $ \call pops -> + k (WasmCallAddResult t call) (WasmSetLocal t x <> pops) + +-- | Given a call that has its result types but not its argument +-- types, and a sequence of pops, and a list of actual parameters +-- (expressions), call a given continuation with a sequence of pushes, +-- an augmented call, and a sequence of pops. As before, the `mid` +-- stack is the original stack plus all the results pushed by the +-- call. + +addCallArguments :: CG bool codegen + => [CmmExpr] + -> WasmCall bool stack mid + -> WasmIR bool mid stack + -> (forall stack stack_with_args stack_with_results . + WasmIR bool stack stack_with_args -> + WasmCall bool stack_with_args stack_with_results -> + WasmIR bool stack_with_results stack -> + codegen bool a) + -> codegen bool a +addCallArguments [] call pops k = k WasmNop call pops +addCallArguments (e : es) call pops k = + addCallArguments es call pops $ \ pushes call pops -> + expr e $ \t push -> + k (pushes <> push) (WasmCallAddArg t call) pops + +-- | Given a call's target, its actual parameters, and its results +-- registers, translate the call into a sequence of Wasm instructions, +-- ultimately leaving the stack unchanged. (CPS as usual.) + +call :: CG bool codegen + => SymName + -> [CmmExpr] + -> [LocalReg] + -> (forall stack . WasmIR bool stack stack -> codegen bool a) + -> codegen bool a +call target es regs k = + addCallResults (WasmCallDirect target) regs $ \call pops -> + addCallArguments es call pops $ \ pushes call pops -> + k $ pushes <> WasmCall' call <> pops +---------------------------------------------------------------- symNameFromCLabel :: CLabel -> SymName symNameFromCLabel lbl = fromString $ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fedf7e7a9f2854d1d8990a94c14eb62759a9dc09...d18a6b28ed5e1da8fae660858943663211935da7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fedf7e7a9f2854d1d8990a94c14eb62759a9dc09...d18a6b28ed5e1da8fae660858943663211935da7 You're receiving 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 Oct 14 15:28:33 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 14 Oct 2022 11:28:33 -0400 Subject: [Git][ghc/ghc][wip/T22241] 2 commits: DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Message-ID: <6349802198da0_8b90f517d4956d1@gitlab.mail> Sebastian Graf pushed to branch wip/T22241 at Glasgow Haskell Compiler / GHC Commits: 9c5882cf by Sebastian Graf at 2022-10-14T17:28:24+02:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, we failed to detect that `f` can unbox `y` in the following program (T22241) ```hs data D = D !Int f :: Bool -> Int -> D f x y = D (go x) where go False = y go True = go False {-# NOINLINE f #-} ``` That is because the demand signature for `$WD` is computed upfront and didn't include any boxity information, yet provides useful information to other passes such as the Simplifier. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but keep the signatures for other passes. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - fba8a684 by Sebastian Graf at 2022-10-14T17:28:24+02:00 Tweaks to postIU - - - - - 7 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -553,13 +553,16 @@ analysing their unfolding. A few reasons for the change: *workers*, because their transformers need to adapt to CPR for their arguments in 'cprTransformDataConWork' to enable Note [Nested CPR]. Better keep it all in this module! The alternative would be that - 'GHC.Types.Id.Make' depends on DmdAnal. + 'GHC.Types.Id.Make' depends on CprAnal. 3. In the future, Nested CPR could take a better account of incoming args in cprAnalApp and do some beta-reduction on the fly, like !1866 did. If any of those args had the CPR property, then we'd even get Nested CPR for DataCon wrapper calls, for free. Not so if we simply give the wrapper a single CPR sig in 'GHC.Types.Id.Make.mkDataConRep'! +DmdAnal also looks through the wrapper's unfolding: +See Note [DmdAnal for DataCon wrappers]. + Note [Trimming to mAX_CPR_SIZE] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We do not treat very big tuples as CPR-ish: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,10 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + -- See Note [CPR for DataCon wrappers] + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1388,6 +1392,37 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +Note [DmdAnal for DataCon wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We give DataCon wrappers a (necessarily flat) demand signature in +'GHC.Types.Id.Make.mkDataConRep', so that passes such as the Simplifier can +exploit it. But during DmdAnal, we *ignore* the demand signature of DataCon +wrappers and analyse their unfolding instead. + +Part of the reason is that the ad-hoc signatures in mkDataConRep don't have +accurate Boxity information. +It's pretty similar to the situation in Note [CPR for DataCon wrappers]. + +Another reason is that DataCon *worker*s have very precise demand transformers, +computed by 'dmdTransformDataConSig'. It would be awkward if DataCon *wrappers* +would behave much less precisely during DmdAnal. Example: + + data T = MkT { get_x :: Int, get_y :: !Bool } + let t = join j x = $WMkT x True in ... j (f 13) ... j (f 14) ... + in ... get_y t ... get_y t ... + +Here, we would like to detect that `x` is absent, so that we can completely +discard the `f 13` and `f 14` arguments of `j`. With a single-point demand +signature computed for top sub-demand L, we would be out of luck. But if we push +the P(A,1L) sub-demand into the unfolding of `$WMkT`, we see its action on the +DataCon worker's demand transformer and see that `get_x` is absent. + +Besides, DataCon wrappers are generally inlined in the Final phase (so before +DmdAnal), all leftover occurrences are in a boring context like +`f x y = $WMkT y x`. The arguments will be pretty simple, so analysing the +unfolding will be cheap to analyse, too. Also DataCon wrappers occur seldom +enough that performance-wise it doesn't matter. + Note [Boxity for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider (A) ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1454,44 +1454,43 @@ postInlineUnconditionally env bind_cxt bndr occ_info rhs | exprIsTrivial rhs = True | BC_Join {} <- bind_cxt -- See point (1) of Note [Duplicating join points] , not (phase == FinalPhase) = False -- in Simplify.hs - | otherwise - = case occ_info of - OneOcc { occ_in_lam = in_lam, occ_int_cxt = int_cxt, occ_n_br = n_br } - -- See Note [Inline small things to avoid creating a thunk] - - -> n_br < 100 -- See Note [Suppress exponential blowup] + | IAmDead <- occ_info = True -- This happens; for example, the case_bndr during case of + -- known constructor: case (a,b) of x { (p,q) -> ... } + -- Here x isn't mentioned in the RHS, so we don't want to + -- create the (dead) let-binding let x = (a,b) in ... + + -- See Note [Inline small things to avoid creating a thunk] + | OneOcc{occ_in_lam=in_lam, occ_int_cxt=int_cxt, occ_n_br=n_br} <- occ_info + , n_br < 100 -- See Note [Suppress exponential blowup] + , BC_Let {} <- bind_cxt + -- Inlining a join point does not avoid a thunk + , smallEnoughToInline uf_opts unfolding + -- Small enough to dup + -- ToDo: consider discount on smallEnoughToInline if int_cxt is true + -- + -- NB: Do NOT inline arbitrarily big things, even if occ_n_br=1 + -- Reason: doing so risks exponential behaviour. We simplify a big + -- expression, inline it, and simplify it again. But if the + -- very same thing happens in the big expression, we get + -- exponential cost! + -- PRINCIPLE: when we've already simplified an expression once, + -- make sure that we only inline it if it's reasonably small. + , in_lam == NotInsideLam + -- Outside a lambda, we want to be reasonably aggressive + -- about inlining into multiple branches of case + -- e.g. let x = + -- in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... } + -- Inlining can be a big win if C3 is the hot-spot, even if + -- the uses in C1, C2 are not 'interesting' + -- An example that gets worse if you add int_cxt here is 'clausify' + || (isCheapUnfolding unfolding && int_cxt == IsInteresting) + -- isCheap => acceptable work duplication; in_lam may be true + -- int_cxt to prevent us inlining inside a lambda without some + -- good reason. See the notes on int_cxt in preInlineUnconditionally + = True - && smallEnoughToInline uf_opts unfolding -- Small enough to dup - -- ToDo: consider discount on smallEnoughToInline if int_cxt is true - -- - -- NB: Do NOT inline arbitrarily big things, even if occ_n_br=1 - -- Reason: doing so risks exponential behaviour. We simplify a big - -- expression, inline it, and simplify it again. But if the - -- very same thing happens in the big expression, we get - -- exponential cost! - -- PRINCIPLE: when we've already simplified an expression once, - -- make sure that we only inline it if it's reasonably small. - - && (in_lam == NotInsideLam || - -- Outside a lambda, we want to be reasonably aggressive - -- about inlining into multiple branches of case - -- e.g. let x = - -- in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... } - -- Inlining can be a big win if C3 is the hot-spot, even if - -- the uses in C1, C2 are not 'interesting' - -- An example that gets worse if you add int_cxt here is 'clausify' - - (isCheapUnfolding unfolding && int_cxt == IsInteresting)) - -- isCheap => acceptable work duplication; in_lam may be true - -- int_cxt to prevent us inlining inside a lambda without some - -- good reason. See the notes on int_cxt in preInlineUnconditionally - - IAmDead -> True -- This happens; for example, the case_bndr during case of - -- known constructor: case (a,b) of x { (p,q) -> ... } - -- Here x isn't mentioned in the RHS, so we don't want to - -- create the (dead) let-binding let x = (a,b) in ... - - _ -> False + | otherwise + = False -- Here's an example that we don't handle well: -- let f = if b then Left (\x.BIG) else Right (\y.BIG) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -477,9 +477,9 @@ mkDictSelId name clas -- See Note [Type classes and linear types] base_info = noCafIdInfo - `setArityInfo` 1 - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` 1 + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig info | new_tycon = base_info `setInlinePragInfo` alwaysInlinePragma @@ -697,6 +697,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + -- The signature is purely for passes like the Simplifier, not for + -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv wrap_arg_dmds = @@ -1321,9 +1323,9 @@ mkFCallId uniq fcall ty name = mkFCallName uniq occ_str info = noCafIdInfo - `setArityInfo` arity - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` arity + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty arity = count isAnonTyCoBinder bndrs ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,31 @@ +module T22241 where + +data D = D { unD :: !Int } + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} + + + +data T a = T Int !a +get (T _ x) = x + +-- Here, the goal is to discard `unD (f True z)` and thus `z` as absent by +-- looking through $WT in `j` *during the first pass of DmdAnal*! +g :: Bool -> Int -> Int -> Bool +g x y z | even y = get (fst t) + | y > 13 = not (get (fst t)) + | otherwise = False + where + t | x = j (unD (f True z)) + | otherwise = j (unD (f False z)) + where + j a = (T a x, True) + {-# NOINLINE j #-} +{-# NOINLINE g #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,24 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + + +==================== Cpr signatures ==================== +T22241.f: 1 +T22241.g: +T22241.get: +T22241.unD: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88955c825dba0b546d91110ec35366548a4b586b...fba8a684b348cec5565d06c26479b2f6e3a58cd8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88955c825dba0b546d91110ec35366548a4b586b...fba8a684b348cec5565d06c26479b2f6e3a58cd8 You're receiving 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 Oct 14 15:28:40 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 14 Oct 2022 11:28:40 -0400 Subject: [Git][ghc/ghc][wip/T22241] Deleted 1 commit: Tweaks to postIU Message-ID: <6349802840e11_8b90f5143c96038@gitlab.mail> Sebastian Graf pushed to branch wip/T22241 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: fba8a684 by Sebastian Graf at 2022-10-14T17:28:24+02:00 Tweaks to postIU - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify/Utils.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1454,44 +1454,43 @@ postInlineUnconditionally env bind_cxt bndr occ_info rhs | exprIsTrivial rhs = True | BC_Join {} <- bind_cxt -- See point (1) of Note [Duplicating join points] , not (phase == FinalPhase) = False -- in Simplify.hs - | otherwise - = case occ_info of - OneOcc { occ_in_lam = in_lam, occ_int_cxt = int_cxt, occ_n_br = n_br } - -- See Note [Inline small things to avoid creating a thunk] - - -> n_br < 100 -- See Note [Suppress exponential blowup] + | IAmDead <- occ_info = True -- This happens; for example, the case_bndr during case of + -- known constructor: case (a,b) of x { (p,q) -> ... } + -- Here x isn't mentioned in the RHS, so we don't want to + -- create the (dead) let-binding let x = (a,b) in ... + + -- See Note [Inline small things to avoid creating a thunk] + | OneOcc{occ_in_lam=in_lam, occ_int_cxt=int_cxt, occ_n_br=n_br} <- occ_info + , n_br < 100 -- See Note [Suppress exponential blowup] + , BC_Let {} <- bind_cxt + -- Inlining a join point does not avoid a thunk + , smallEnoughToInline uf_opts unfolding + -- Small enough to dup + -- ToDo: consider discount on smallEnoughToInline if int_cxt is true + -- + -- NB: Do NOT inline arbitrarily big things, even if occ_n_br=1 + -- Reason: doing so risks exponential behaviour. We simplify a big + -- expression, inline it, and simplify it again. But if the + -- very same thing happens in the big expression, we get + -- exponential cost! + -- PRINCIPLE: when we've already simplified an expression once, + -- make sure that we only inline it if it's reasonably small. + , in_lam == NotInsideLam + -- Outside a lambda, we want to be reasonably aggressive + -- about inlining into multiple branches of case + -- e.g. let x = + -- in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... } + -- Inlining can be a big win if C3 is the hot-spot, even if + -- the uses in C1, C2 are not 'interesting' + -- An example that gets worse if you add int_cxt here is 'clausify' + || (isCheapUnfolding unfolding && int_cxt == IsInteresting) + -- isCheap => acceptable work duplication; in_lam may be true + -- int_cxt to prevent us inlining inside a lambda without some + -- good reason. See the notes on int_cxt in preInlineUnconditionally + = True - && smallEnoughToInline uf_opts unfolding -- Small enough to dup - -- ToDo: consider discount on smallEnoughToInline if int_cxt is true - -- - -- NB: Do NOT inline arbitrarily big things, even if occ_n_br=1 - -- Reason: doing so risks exponential behaviour. We simplify a big - -- expression, inline it, and simplify it again. But if the - -- very same thing happens in the big expression, we get - -- exponential cost! - -- PRINCIPLE: when we've already simplified an expression once, - -- make sure that we only inline it if it's reasonably small. - - && (in_lam == NotInsideLam || - -- Outside a lambda, we want to be reasonably aggressive - -- about inlining into multiple branches of case - -- e.g. let x = - -- in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... } - -- Inlining can be a big win if C3 is the hot-spot, even if - -- the uses in C1, C2 are not 'interesting' - -- An example that gets worse if you add int_cxt here is 'clausify' - - (isCheapUnfolding unfolding && int_cxt == IsInteresting)) - -- isCheap => acceptable work duplication; in_lam may be true - -- int_cxt to prevent us inlining inside a lambda without some - -- good reason. See the notes on int_cxt in preInlineUnconditionally - - IAmDead -> True -- This happens; for example, the case_bndr during case of - -- known constructor: case (a,b) of x { (p,q) -> ... } - -- Here x isn't mentioned in the RHS, so we don't want to - -- create the (dead) let-binding let x = (a,b) in ... - - _ -> False + | otherwise + = False -- Here's an example that we don't handle well: -- let f = if b then Left (\x.BIG) else Right (\y.BIG) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fba8a684b348cec5565d06c26479b2f6e3a58cd8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fba8a684b348cec5565d06c26479b2f6e3a58cd8 You're receiving 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 Oct 14 15:29:39 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 14 Oct 2022 11:29:39 -0400 Subject: [Git][ghc/ghc][wip/T22241] 42 commits: chore: extend `.editorconfig` for C files Message-ID: <63498063389bc_8b90f514289812c@gitlab.mail> Sebastian Graf pushed to branch wip/T22241 at Glasgow Haskell Compiler / GHC Commits: 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - 1a6ea360 by Sebastian Graf at 2022-10-14T15:29:36+00:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, we failed to detect that `f` can unbox `y` in the following program (T22241) ```hs data D = D !Int f :: Bool -> Int -> D f x y = D (go x) where go False = y go True = go False {-# NOINLINE f #-} ``` That is because the demand signature for `$WD` is computed upfront and didn't include any boxity information, yet provides useful information to other passes such as the Simplifier. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but keep the signatures for other passes. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 30 changed files: - .editorconfig - README.md - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Recomp.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c5882cf1eb8a1fc655ceb88f1b53f65db0ada15...1a6ea360234175ebbb15db7c1d6158c26b3d66fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c5882cf1eb8a1fc655ceb88f1b53f65db0ada15...1a6ea360234175ebbb15db7c1d6158c26b3d66fe You're receiving 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 Oct 14 15:29:44 2022 From: gitlab at gitlab.haskell.org (Norman Ramsey (@nrnrnr)) Date: Fri, 14 Oct 2022 11:29:44 -0400 Subject: [Git][ghc/ghc][wip/nr/wasm-translation-prototypes] simplify call translation; improve doco Message-ID: <634980681614_8b90f5179898373@gitlab.mail> Norman Ramsey pushed to branch wip/nr/wasm-translation-prototypes at Glasgow Haskell Compiler / GHC Commits: 7b85cdb7 by Norman Ramsey at 2022-10-14T11:29:27-04:00 simplify call translation; improve doco - - - - - 1 changed file: - compiler/GHC/Wasm/Tx.hs Changes: ===================================== compiler/GHC/Wasm/Tx.hs ===================================== @@ -346,16 +346,17 @@ node' _ _ = panic "`node'` is just a demo; only a few cases are implemented" -- | Given a call target and a list of result registers, call a -- given continuation with an augmented call and a sequence of pops. --- The `mid` stack is the original stack plus all the results pushed --- by the call. The `pre` stack is the state of the stack before the +-- The `pre` stack is the state of the stack before the -- first argument is pushed, which is also the state of the stack -- after the last results is popped. addCallResults :: CG bool codegen => WasmCall bool pre pre -> [LocalReg] - -> (forall stack mid . - WasmCall bool stack mid -> WasmIR bool mid stack -> codegen bool a) + -> (forall stack stack_with_results . + WasmCall bool stack stack_with_results -> + WasmIR bool stack_with_results stack -> + codegen bool a) -> codegen bool a addCallResults target [] k = k target WasmNop @@ -365,27 +366,22 @@ addCallResults target (reg:regs) k = k (WasmCallAddResult t call) (WasmSetLocal t x <> pops) -- | Given a call that has its result types but not its argument --- types, and a sequence of pops, and a list of actual parameters --- (expressions), call a given continuation with a sequence of pushes, --- an augmented call, and a sequence of pops. As before, the `mid` --- stack is the original stack plus all the results pushed by the --- call. +-- types, and a list of actual parameters (expressions), call a given +-- continuation with a sequence of pushes and an augmented call. addCallArguments :: CG bool codegen - => [CmmExpr] - -> WasmCall bool stack mid - -> WasmIR bool mid stack - -> (forall stack stack_with_args stack_with_results . + => WasmCall bool stack stack_with_results + -> [CmmExpr] + -> (forall stack_with_args . WasmIR bool stack stack_with_args -> WasmCall bool stack_with_args stack_with_results -> - WasmIR bool stack_with_results stack -> codegen bool a) -> codegen bool a -addCallArguments [] call pops k = k WasmNop call pops -addCallArguments (e : es) call pops k = - addCallArguments es call pops $ \ pushes call pops -> +addCallArguments call [] k = k WasmNop call +addCallArguments call (e : es) k = + addCallArguments call es $ \ pushes call -> expr e $ \t push -> - k (pushes <> push) (WasmCallAddArg t call) pops + k (pushes <> push) (WasmCallAddArg t call) -- | Given a call's target, its actual parameters, and its results -- registers, translate the call into a sequence of Wasm instructions, @@ -399,7 +395,7 @@ call :: CG bool codegen -> codegen bool a call target es regs k = addCallResults (WasmCallDirect target) regs $ \call pops -> - addCallArguments es call pops $ \ pushes call pops -> + addCallArguments call es $ \ pushes call -> k $ pushes <> WasmCall' call <> pops View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b85cdb7b4e3a6aa1c7e853adc9c5c21a50ff7f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b85cdb7b4e3a6aa1c7e853adc9c5c21a50ff7f1 You're receiving 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 Oct 14 19:49:37 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 15:49:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <6349bd51ca427_8b90f51428129053@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - a1b742b0 by Ben Gamari at 2022-10-14T15:49:14-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - cadc565c by Ben Gamari at 2022-10-14T15:49:14-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - eb334f8e by Ben Gamari at 2022-10-14T15:49:14-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 19 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/posix/OSThreads.c - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -140,6 +140,11 @@ Runtime system - Updated to `Unicode 15.0.0 `_. +- Add standard Unicode case predicates :base-ref:`Data.Char.isUpperCase` and + :base-ref:`Data.Char.isLowerCase`. These predicates use the standard Unicode + case properties and are more intuitive than :base-ref:`Data.Char.isUpper` and + :base-ref:`Data.Char.isLower`. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/Data/Char.hs ===================================== @@ -6,7 +6,7 @@ -- Module : Data.Char -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : stable -- Portability : portable @@ -24,7 +24,7 @@ module Data.Char -- punctuation, symbols, separators (including spaces) and others -- (including control characters). , isControl, isSpace - , isLower, isUpper, isAlpha, isAlphaNum, isPrint + , isLower, isLowerCase, isUpper, isUpperCase, isAlpha, isAlphaNum, isPrint , isDigit, isOctDigit, isHexDigit , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator ===================================== libraries/base/Data/OldList.hs ===================================== @@ -1249,6 +1249,7 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs at . +-- -- This function is productive on infinite inputs: -- -- >>> take 6 $ map (take 3) $ permutations ['a'..] @@ -1259,21 +1260,25 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] -- -permutations :: [a] -> [[a]] +permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation. -- Related discussions: -- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html -- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html -permutations xs0 = xs0 : perms xs0 [] +permutations xs0 = xs0 : perms xs0 [] where + perms :: forall a. [a] -> [a] -> [[a]] perms [] _ = [] perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) - where interleave xs r = let (_,zs) = interleave' id xs r in zs - interleave' _ [] r = (ts, r) - interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r - in (y:us, f (t:y:us) : zs) - + where + interleave :: [a] -> [[a]] -> [[a]] + interleave xs r = let (_,zs) = interleave' id xs r in zs + + interleave' :: ([a] -> b) -> [a] -> [b] -> ([a], [b]) + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) ------------------------------------------------------------------------------ -- Quick Sort algorithm taken from HBC's QSort library. ===================================== libraries/base/GHC/Unicode.hs ===================================== @@ -24,8 +24,8 @@ module GHC.Unicode ( GeneralCategory (..), generalCategory, isAscii, isLatin1, isControl, isAsciiUpper, isAsciiLower, - isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, + isPrint, isSpace, isUpper, isUpperCase, + isLower, isLowerCase, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, isPunctuation, isSymbol, toUpper, toLower, toTitle @@ -37,6 +37,7 @@ import GHC.Enum ( Enum (..), Bounded (..) ) import GHC.Ix ( Ix (..) ) import GHC.Num import GHC.Unicode.Internal.Version +import qualified GHC.Unicode.Internal.Char.DerivedCoreProperties as DCP import qualified GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory as GC import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping as C import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping as C @@ -236,18 +237,68 @@ isSpace c -- | Selects upper-case or title-case alphabetic Unicode characters (letters). -- Title case is used by a small number of letter ligatures like the -- single-character form of /Lj/. +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'UppercaseLetter' or 'TitlecaseLetter'. +-- +-- See 'isUpperCase' for a more intuitive predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). isUpper :: Char -> Bool isUpper c = case generalCategory c of UppercaseLetter -> True TitlecaseLetter -> True _ -> False +-- | Selects upper-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Uppercase@, which include letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). +-- +-- See 'isUpper' for the legacy predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). +-- +-- @since 4.18.0.0 +{-# INLINE isUpperCase #-} +isUpperCase :: Char -> Bool +isUpperCase = DCP.isUppercase + -- | Selects lower-case alphabetic Unicode characters (letters). +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'LowercaseLetter'. +-- +-- See 'isLowerCase' for a more intuitive predicate. isLower :: Char -> Bool isLower c = case generalCategory c of LowercaseLetter -> True _ -> False +-- | Selects lower-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Lowercase@, which includes letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). +-- +-- See 'isLower' for the legacy predicate. +-- +-- @since 4.18.0.0 +{-# INLINE isLowerCase #-} +isLowerCase :: Char -> Bool +isLowerCase = DCP.isLowercase + -- | Selects alphabetic Unicode characters (lower-case, upper-case and -- title-case letters, plus letters of caseless scripts and modifiers letters). -- This function is equivalent to 'Data.Char.isLetter'. ===================================== libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs ===================================== @@ -0,0 +1,35 @@ +-- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell, +-- with data from: https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt. + +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Unicode.Internal.Char.DerivedCoreProperties +-- Copyright : (c) 2020 Composewell Technologies and Contributors +-- License : BSD-3-Clause +-- Maintainer : streamly at composewell.com +-- Stability : internal +----------------------------------------------------------------------------- + +module GHC.Unicode.Internal.Char.DerivedCoreProperties +(isUppercase , isLowercase) +where + +import GHC.Base (Bool, Char, Ord(..), (&&), ord) +import GHC.Unicode.Internal.Bits (lookupBit64) + +{-# INLINE isUppercase #-} +isUppercase :: Char -> Bool +isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\2\65\1\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"# + +{-# INLINE isLowercase #-} +isLowercase :: Char -> Bool +isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\5\170\2\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"# + ===================================== libraries/base/base.cabal ===================================== @@ -352,6 +352,7 @@ Library GHC.Event.Unique -- GHC.IOPort -- TODO: hide again after debug GHC.Unicode.Internal.Bits + GHC.Unicode.Internal.Char.DerivedCoreProperties GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping ===================================== libraries/base/changelog.md ===================================== @@ -30,6 +30,10 @@ for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). + * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to + `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode + case properties and are more intuitive than `isUpper` and `isLower`. See + [CLC proposal #90](https://github.com/haskell/core-libraries-committee/issues/90). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tests/unicode001.hs ===================================== @@ -16,17 +16,45 @@ main = do f True = "X " f False = " " -strs = ["upper","lower","alpha","alnum","digit","print","space","cntrl"] +strs = + [ "upper", + "uppr2", + "lower", + "lowr2", + "alpha", + "alnum", + "digit", + "print", + "space", + "cntrl" ] -functions = [isUpper,isLower,isAlpha,isAlphaNum,isDigit,isPrint,isSpace,isControl] +functions = + [ isUpper, + isUpperCase, + isLower, + isLowerCase, + isAlpha, + isAlphaNum, + isDigit, + isPrint, + isSpace, + isControl ] chars = [backspace,tab,space,zero,lower_a,upper_a,delete, right_pointing_double_angle_quotation_mark, + latin_capital_letter_l_with_small_letter_j, + latin_small_letter_i_with_caron, + combining_acute_accent, greek_capital_letter_alpha, bengali_digit_zero, en_space, + roman_numeral_one, + small_roman_numeral_one, + circled_latin_capital_letter_a, + circled_latin_small_letter_a, gothic_letter_ahsa, - monospaced_digit_zero + monospaced_digit_zero, + squared_latin_capital_letter_a ] backspace = '\x08' @@ -37,10 +65,16 @@ lower_a = 'a' upper_a = 'A' delete = '\x7f' right_pointing_double_angle_quotation_mark = '\xBB' +latin_capital_letter_l_with_small_letter_j = '\x01C8' latin_small_letter_i_with_caron = '\x1D0' combining_acute_accent = '\x301' greek_capital_letter_alpha = '\x0391' bengali_digit_zero = '\x09E6' en_space = '\x2002' +roman_numeral_one = '\x2160' +small_roman_numeral_one = '\x2170' +circled_latin_capital_letter_a = '\x24B6' +circled_latin_small_letter_a = '\x24D6' gothic_letter_ahsa = '\x10330' monospaced_digit_zero = '\x1D7F6' +squared_latin_capital_letter_a = '\x1F130' ===================================== libraries/base/tests/unicode001.stdout ===================================== @@ -1,14 +1,22 @@ - upper lower alpha alnum digit print space cntrl -'\b' X -'\t' X X -' ' X X -'0' X X X -'a' X X X X -'A' X X X X -'\DEL' X -'\187' X -'\913' X X X X -'\2534' X X -'\8194' X X -'\66352' X X X -'\120822' X X + upper uppr2 lower lowr2 alpha alnum digit print space cntrl +'\b' X +'\t' X X +' ' X X +'0' X X X +'a' X X X X X +'A' X X X X X +'\DEL' X +'\187' X +'\456' X X X X +'\464' X X X X X +'\769' X +'\913' X X X X X +'\2534' X X +'\8194' X X +'\8544' X X X +'\8560' X X X +'\9398' X X +'\9430' X X +'\66352' X X X +'\120822' X X +'\127280' X X ===================================== libraries/base/tools/ucd2haskell/exe/Parser/Text.hs ===================================== @@ -22,12 +22,12 @@ module Parser.Text (genModules) where import Control.Exception (catch, IOException) import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO)) --- import Data.Bits (Bits(..)) [NOTE] Used by disabled generator +import Data.Bits (Bits(..)) import Data.Word (Word8) -import Data.Char (chr, ord {-, isSpace-}) +import Data.Char (chr, ord, isSpace) import Data.Functor ((<&>)) import Data.Function ((&)) --- import Data.List (unfoldr, intersperse) [NOTE] Used by disabled generator +import Data.List (intersperse, unfoldr) import Data.List.Split (splitWhen) import Numeric (showHex) import Streamly.Data.Fold (Fold) @@ -132,7 +132,6 @@ readCodePointM :: String -> Maybe Char readCodePointM "" = Nothing readCodePointM u = Just (readCodePoint u) -{- [NOTE] Used by disabled generator genSignature :: String -> String genSignature = (<> " :: Char -> Bool") @@ -189,7 +188,6 @@ bitMapToAddrLiteral bs cs = foldr encode cs (unfoldr mkChunks bs) toByte :: [Bool] -> Int toByte xs = sum $ map (\i -> if xs !! i then 1 `shiftL` i else 0) [0..7] --} genEnumBitmap :: forall a. (Bounded a, Enum a, Show a) => @@ -642,8 +640,6 @@ genSimpleCaseMappingModule moduleName funcName field = showHexChar c = showHex (ord c) -{- [NOTE] Disabled generator - genCorePropertiesModule :: Monad m => String -> (String -> Bool) -> Fold m (String, [Int]) String genCorePropertiesModule moduleName isProp = @@ -674,7 +670,6 @@ genCorePropertiesModule moduleName isProp = , "import GHC.Unicode.Internal.Bits (lookupBit64)" , "" ] --} {- [NOTE] Disabled generator genUnicode002TestResults :: Monad m => Fold m DetailedChar String @@ -778,8 +773,6 @@ genUnicode002TestResults = done <$> Fold.foldl' step initial -- Parsing property files ------------------------------------------------------------------------------- -{- [NOTE] Used by disabled generator - type PropertyLine = (String, [Int]) trim :: String -> String @@ -826,7 +819,6 @@ parsePropertyLines = Stream.splitOn isDivider $ Fold.lmap parsePropertyLine $ Fold.foldl' combinePropertyLines emptyPropertyLine --} -- | A range entry in @UnicodeData.txt at . data UnicodeDataRange @@ -1014,7 +1006,7 @@ runGenerator indir file transformLines outdir recipes = combinedFld = void $ Fold.distribute generatedFolds genModules :: String -> String -> [String] -> IO () -genModules indir outdir _props = do +genModules indir outdir props = do genUnicodeVersion outdir -- [NOTE] Disabled generator @@ -1060,13 +1052,12 @@ genModules indir outdir _props = do -- outdir -- [ uncurry ModuleRecipe propList ] - -- [NOTE] Disabled generator - -- runGenerator - -- indir - -- "DerivedCoreProperties.txt" - -- parsePropertyLines - -- outdir - -- [ uncurry ModuleRecipe derivedCoreProperties ] + runGenerator + indir + "DerivedCoreProperties.txt" + parsePropertyLines + outdir + [ uncurry ModuleRecipe derivedCoreProperties ] where @@ -1075,10 +1066,9 @@ genModules indir outdir _props = do -- ("GHC.Unicode.Internal.Char.PropList" -- , (`genCorePropertiesModule` (`elem` props))) - -- [NOTE] Disabled generator - -- derivedCoreProperties = - -- ("GHC.Unicode.Internal.Char.DerivedCoreProperties" - -- , (`genCorePropertiesModule` (`elem` props))) + derivedCoreProperties = + ("GHC.Unicode.Internal.Char.DerivedCoreProperties" + , (`genCorePropertiesModule` (`elem` props))) -- [NOTE] Disabled generator -- compositions exc non0 = ===================================== libraries/base/tools/ucd2haskell/tests/check_all_chars.py ===================================== @@ -10,6 +10,15 @@ from operator import methodcaller def parse_codepoint(s: str, base=16): return chr(int(s, base)) +def parse_bool(s: str): + match(s): + case "True": + return True + case "False": + return False + case _: + raise ValueError(s) + def general_category(c: str): match(unicodedata.category(c)): case "Lu": @@ -107,6 +116,11 @@ def check_case_mapping(case_mapping: str, char: str, raw_expected: str, verbosit f"“{expected}” (1 char)." ) +def check_case_predicate(case_predicate: str, char: str, raw_expected: str, verbosity: int): + got = methodcaller(case_predicate)(char) + expected = parse_bool(raw_expected) + check(got == expected, (char, got, expected)) + if __name__ == "__main__": parser = make_parser() @@ -125,10 +139,12 @@ if __name__ == "__main__": next(fp) reader = csv.reader(fp) for row in reader: - raw_code, gc, raw_lower, raw_upper, raw_title = row + raw_code, gc, raw_lower, raw_upper, raw_title, raw_islower, raw_isupper = row char = parse_codepoint(raw_code) codepoint = f"U+{raw_code.upper():0>4}" check(gc == general_category(char), (char, gc, general_category(char))) check_case_mapping("lower", char, raw_lower, verbosity) check_case_mapping("upper", char, raw_upper, verbosity) check_case_mapping("title", char, raw_title, verbosity) + check_case_predicate("islower", char, raw_islower, verbosity) + check_case_predicate("isupper", char, raw_isupper, verbosity) ===================================== libraries/base/tools/ucd2haskell/tests/export_all_chars.hs ===================================== @@ -26,7 +26,7 @@ main = do -- | File header header :: String -header = "Char,General Category,Lower Case,Upper Case,Title Case" +header = "Char,General Category,Lower Case,Upper Case,Title Case,isLowerCase,isUpperCase" -- | Convert a character to its (short) hexadecimal Unicode codepoint. mkCodePointHex :: Char -> String @@ -43,4 +43,8 @@ addEntry c = do putChar ',' putStr (mkCodePointHex (toUpper c)) putChar ',' - putStrLn (mkCodePointHex (toTitle c)) + putStr (mkCodePointHex (toTitle c)) + putChar ',' + putStr (show (isLowerCase c)) + putChar ',' + putStrLn (show (isUpperCase c)) ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,6 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ + ucd/DerivedCoreProperties.txt:d367290bc0867e6b484c68370530bdd1a08b6b32404601b8c7accaf83e05628d \ ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -58,10 +59,10 @@ run_generator() { # Compile and run ucd2haskell cabal run exe:ucd2haskell -- \ --input "$SCRIPT_DIR/ucd/" \ - --output "$GHC_MODULE_PATH/" - # [NOTE] disabled generaor - # --core-prop Uppercase \ - # --core-prop Lowercase \ + --output "$GHC_MODULE_PATH/" \ + --core-prop Uppercase \ + --core-prop Lowercase + # [NOTE] disabled generator # --core-prop Alphabetic # --core-prop White_Space \ # --core-prop ID_Start \ ===================================== rts/posix/OSThreads.c ===================================== @@ -186,22 +186,48 @@ shutdownThread(void) pthread_exit(NULL); } -int -createOSThread (OSThreadId* pId, char *name STG_UNUSED, - OSThreadProc *startProc, void *param) +struct ThreadDesc { + OSThreadProc *startProc; + void *param; + char *name; +}; + +// N.B. Darwin's pthread_setname_np only allows the name of the +// calling thread to be set. Consequently we must use this +// trampoline. +static void * +start_thread (void *param) { - int result = pthread_create(pId, NULL, startProc, param); - if (!result) { - pthread_detach(*pId); + struct ThreadDesc desc = *(struct ThreadDesc *) param; + stgFree(param); + #if defined(HAVE_PTHREAD_SET_NAME_NP) - pthread_set_name_np(*pId, name); + pthread_set_name_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP) - pthread_setname_np(*pId, name); + pthread_setname_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) - pthread_setname_np(name); + pthread_setname_np(desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) - pthread_setname_np(*pId, "%s", name); + pthread_setname_np(pthread_self(), "%s", desc.name); #endif + + return desc.startProc(desc.param); +} + +int +createOSThread (OSThreadId* pId, char *name STG_UNUSED, + OSThreadProc *startProc, void *param) +{ + struct ThreadDesc *desc = stgMallocBytes(sizeof(struct ThreadDesc), "createOSThread"); + desc->startProc = startProc; + desc->param = param; + desc->name = name; + + int result = pthread_create(pId, NULL, start_thread, desc); + if (!result) { + pthread_detach(*pId); + } else { + stgFree(desc); } return result; } ===================================== testsuite/tests/numeric/should_run/T22282.hs ===================================== @@ -0,0 +1,3 @@ +import T22282A + +main = print $ testF 217 161 ===================================== testsuite/tests/numeric/should_run/T22282.stdout ===================================== @@ -0,0 +1,2 @@ +217 + ===================================== testsuite/tests/numeric/should_run/T22282A.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE MagicHash #-} +module T22282A where + +import Data.Word +import GHC.Prim +import GHC.Word + +wtestF :: GHC.Prim.Word8# -> GHC.Prim.Word8# -> GHC.Prim.Word8# +wtestF a b = case word8ToWord# b of + 0## -> a + _ -> plusWord8# (timesWord8# (quotWord8# a b) b) (remWord8# a b) +{-# NOINLINE wtestF #-} + +testF :: Word8 -> Word8 -> Word8 +testF (W8# a) (W8# b) = W8# (wtestF a b) +{-# INLINE testF #-} + ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,3 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) +test('T22282', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ef7e9ffac49d337d3b25433bf42669d3c12115b...eb334f8e669a0d7ae3f6ba3e3089af7a116d224d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ef7e9ffac49d337d3b25433bf42669d3c12115b...eb334f8e669a0d7ae3f6ba3e3089af7a116d224d You're receiving 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 Oct 14 20:24:20 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Oct 2022 16:24:20 -0400 Subject: [Git][ghc/ghc][wip/backports-9.4] 6 commits: Fix a nasty loop in Tidy Message-ID: <6349c57462f43_8b90f514281379b0@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.4 at Glasgow Haskell Compiler / GHC Commits: 2cf828e8 by Simon Peyton Jones at 2022-09-15T10:28:17+02:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] This is the 9.4 packport based on commit 4945953823620b223a0b51b2b1275a1de8f4a851 - - - - - 15c496c5 by Sebastian Graf at 2022-10-12T19:20:16-04:00 Ignore .hie-bios (cherry picked from commit 2563b95cda983cd6be23a5be01fe1f1873f1fa4f) - - - - - 26af15a0 by Sebastian Graf at 2022-10-12T19:20:16-04:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. (cherry picked from commit 94f2e92a2510a3338c5201a4dcc69666fa9575f8) - - - - - ecb6accd by Sebastian Graf at 2022-10-14T16:16:07-04:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. (cherry picked from commit b570da84b7aad5ca3f90f2d1c1a690c927e99fe9) - - - - - 1431ee96 by Sebastian Graf at 2022-10-14T16:19:30-04:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 (cherry picked from commit 49fb2f9b16ca987648d2ac57eecf1892d49852ec) - - - - - 3e4a38c8 by Ben Gamari at 2022-10-14T16:24:01-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. (cherry picked from commit cd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3) - - - - - 27 changed files: - .gitignore - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/Graph/UnVar.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Id/Info.hs - testsuite/tests/arityanal/should_compile/Arity03.stderr - + testsuite/tests/arityanal/should_run/Makefile - + testsuite/tests/arityanal/should_run/T21652.hs - + testsuite/tests/arityanal/should_run/T21652.stdout - + testsuite/tests/arityanal/should_run/all.T - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/deSugar/should_compile/T19969.stderr - + testsuite/tests/simplCore/should_compile/T22112.hs - + testsuite/tests/simplCore/should_compile/T22112.stderr - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_run/T20836.hs - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== .gitignore ===================================== @@ -57,6 +57,7 @@ _* */ghc-stage1 .shake.* .hadrian_ghci +.hie-bios # ----------------------------------------------------------------------------- # Ignore any overlapped darcs repos and back up files ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -67,7 +67,7 @@ import GHC.Utils.Logger import Data.Maybe (fromJust) import Control.Monad (ap) import Data.Char (isDigit) -import Data.List (sortBy, groupBy, intercalate) +import Data.List (sortBy, groupBy, intercalate, isPrefixOf) import Data.Ord (comparing) import qualified Data.List.NonEmpty as NE @@ -550,6 +550,12 @@ generateExternDecls = do modifyEnv $ \env -> env { envAliases = emptyUniqSet } return (concat defss, []) +-- | Is a variable one of the special @$llvm@ globals? +isBuiltinLlvmVar :: LlvmVar -> Bool +isBuiltinLlvmVar (LMGlobalVar lbl _ _ _ _ _) = + "$llvm" `isPrefixOf` unpackFS lbl +isBuiltinLlvmVar _ = False + -- | Here we take a global variable definition, rename it with a -- @$def@ suffix, and generate the appropriate alias. aliasify :: LMGlobal -> LlvmM [LMGlobal] @@ -557,8 +563,9 @@ aliasify :: LMGlobal -> LlvmM [LMGlobal] -- Here we obtain the indirectee's precise type and introduce -- fresh aliases to both the precise typed label (lbl$def) and the i8* -- typed (regular) label of it with the matching new names. -aliasify (LMGlobal (LMGlobalVar lbl ty at LMAlias{} link sect align Alias) - (Just orig)) = do +aliasify (LMGlobal var@(LMGlobalVar lbl ty at LMAlias{} link sect align Alias) + (Just orig)) + | not $ isBuiltinLlvmVar var = do let defLbl = llvmDefLabel lbl LMStaticPointer (LMGlobalVar origLbl _ oLnk Nothing Nothing Alias) = orig defOrigLbl = llvmDefLabel origLbl @@ -571,7 +578,8 @@ aliasify (LMGlobal (LMGlobalVar lbl ty at LMAlias{} link sect align Alias) pure [ LMGlobal (LMGlobalVar defLbl ty link sect align Alias) (Just defOrig) , LMGlobal (LMGlobalVar lbl i8Ptr link sect align Alias) (Just orig') ] -aliasify (LMGlobal var val) = do +aliasify (LMGlobal var val) + | not $ isBuiltinLlvmVar var = do let LMGlobalVar lbl ty link sect align const = var defLbl = llvmDefLabel lbl @@ -589,6 +597,7 @@ aliasify (LMGlobal var val) = do return [ LMGlobal defVar val , LMGlobal aliasVar (Just aliasVal) ] +aliasify global = pure [global] -- Note [Llvm Forward References] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -647,3 +656,6 @@ aliasify (LMGlobal var val) = do -- away with casting the alias to the desired type in @getSymbolPtr@ -- and instead just emit a reference to the definition symbol directly. -- This is the @Just@ case in @getSymbolPtr at . +-- +-- Note that we must take care not to turn LLVM's builtin variables into +-- aliases (e.g. $llvm.global_ctors) since this confuses LLVM. ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Types.Tickish import GHC.Builtin.Uniques import GHC.Data.FastString +import GHC.Data.Graph.UnVar import GHC.Data.Pair import GHC.Utils.Constants (debugIsOn) @@ -505,6 +506,67 @@ Suppose f = \xy. x+y Then f :: \??.T f v :: \?.T f :: T + + + +Note [Eta reduction in recursive RHSs] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the following recursive function: + f = \x. ....g (\y. f y).... +The recursive call of f in its own RHS seems like a fine opportunity for +eta-reduction because f has arity 1. And often it is! + +Alas, that is unsound in general if the eta-reduction happens in a tail context. +Making the arity visible in the RHS allows us to eta-reduce + f = \x -> f x +to + f = f +which means we optimise terminating programs like (f `seq` ()) into +non-terminating ones. Nor is this problem just for tail calls. Consider + f = id (\x -> f x) +where we have (for some reason) not yet inlined `id`. We must not eta-reduce to + f = id f +because that will then simplify to `f = f` as before. + +An immediate idea might be to look at whether the called function is a local +loopbreaker and refrain from eta-expanding. But that doesn't work for mutually +recursive function like in #21652: + f = g + g* x = f x +Here, g* is the loopbreaker but f isn't. + +What can we do? + +Fix 1: Zap `idArity` when analysing recursive RHSs and re-attach the info when + entering the let body. + Has the disadvantage that other transformations which make use of arity + (such as dropping of `seq`s when arity > 0) will no longer work in the RHS. + Plus it requires non-trivial refactorings to both the simple optimiser (in + the way `subst_opt_bndr` is used) as well as the Simplifier (in the way + `simplRecBndrs` and `simplRecJoinBndrs` is used), modifying the SimplEnv's + substitution twice in the process. A very complicated stop-gap. + +Fix 2: Pass the set of enclosing recursive binders to `tryEtaReduce`; these are + the ones we should not eta-reduce. All call-site must maintain this set. + Example: + rec { f1 = ....rec { g = ... (\x. g x)...(\y. f2 y)... }... + ; f2 = ...f1... } + when eta-reducing those inner lambdas, we need to know that we are in the + rec group for {f1, f2, g}. + This is very much like the solution in Note [Speculative evaluation] in + GHC.CoreToStg.Prep. + It is a bit tiresome to maintain this info, because it means another field + in SimplEnv and SimpleOptEnv. + +We implement Fix (2) because of it isn't as complicated to maintain as (1). +Plus, it is the correct fix to begin with. After all, the arity is correct, +but doing the transformation isn't. The moving parts are: + * A field `scRecIds` in `SimplEnv` tracks the enclosing recursive binders + * We extend the `scRecIds` set in `GHC.Core.Opt.Simplify.simplRecBind` + * We consult the set in `is_eta_reduction_sound` in `tryEtaReduce` +The situation is very similar to Note [Speculative evaluation] which has the +same fix. + -} ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -398,8 +398,10 @@ cprFix orig_env orig_pairs where init_sig id -- See Note [CPR for data structures] - | isDataStructure id = topCprSig - | otherwise = mkCprSig 0 botCpr + -- Don't set the sig to bottom in this case, because cprAnalBind won't + -- update it to something reasonable. Result: Assertion error in WW + | isDataStructure id || isDFunId id = topCprSig + | otherwise = mkCprSig 0 botCpr -- See Note [Initialising strictness] in GHC.Core.Opt.DmdAnal orig_virgin = ae_virgin orig_env init_pairs | orig_virgin = [(setIdCprSig id (init_sig id), rhs) | (id, rhs) <- orig_pairs ] @@ -464,10 +466,10 @@ cprAnalBind env id rhs | isDFunId id -- Never give DFuns the CPR property; we'll never save allocs. = (id, rhs, extendSigEnv env id topCprSig) -- See Note [CPR for data structures] - | isDataStructure id - = (id, rhs, env) -- Data structure => no code => no need to analyse rhs + | isDataStructure id -- Data structure => no code => no need to analyse rhs + = (id, rhs, env) | otherwise - = (id', rhs', env') + = (id `setIdCprSig` sig', rhs', env') where (rhs_ty, rhs') = cprAnal env rhs -- possibly trim thunk CPR info @@ -481,7 +483,6 @@ cprAnalBind env id rhs -- See Note [The OPAQUE pragma and avoiding the reboxing of results] sig' | isOpaquePragma (idInlinePragma id) = topCprSig | otherwise = sig - id' = setIdCprSig id sig' env' = extendSigEnv env id sig' -- See Note [CPR for thunks] ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -64,6 +64,7 @@ import GHC.Builtin.Names( runRWKey ) import GHC.Data.Maybe ( isNothing, orElse ) import GHC.Data.FastString import GHC.Unit.Module ( moduleName, pprModuleName ) +import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain @@ -256,9 +257,11 @@ simplRecBind :: SimplEnv -> BindContext -> [(InId, InExpr)] -> SimplM (SimplFloats, SimplEnv) simplRecBind env0 bind_cxt pairs0 - = do { (env_with_info, triples) <- mapAccumLM add_rules env0 pairs0 - ; (rec_floats, env1) <- go env_with_info triples - ; return (mkRecFloats rec_floats, env1) } + = do { (env1, triples) <- mapAccumLM add_rules env0 pairs0 + ; let new_bndrs = map sndOf3 triples + ; (rec_floats, env2) <- enterRecGroupRHSs env1 new_bndrs $ \env -> + go env triples + ; return (mkRecFloats rec_floats, env2) } where add_rules :: SimplEnv -> (InBndr,InExpr) -> SimplM (SimplEnv, (InBndr, OutBndr, InExpr)) -- Add the (substituted) rules to the binder ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -17,7 +17,7 @@ module GHC.Core.Opt.Simplify.Env ( zapSubstEnv, setSubstEnv, bumpCaseDepth, getInScope, setInScopeFromE, setInScopeFromF, setInScopeSet, modifyInScope, addNewInScopeIds, - getSimplRules, + getSimplRules, enterRecGroupRHSs, -- * Substitution results SimplSR(..), mkContEx, substId, lookupRecBndr, refineFromInScope, @@ -55,6 +55,7 @@ import GHC.Types.Var import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Data.OrdList +import GHC.Data.Graph.UnVar import GHC.Types.Id as Id import GHC.Core.Make ( mkWildValBinder ) import GHC.Driver.Session ( DynFlags ) @@ -96,6 +97,10 @@ data SimplEnv , seCvSubst :: CvSubstEnv -- InCoVar |--> OutCoercion , seIdSubst :: SimplIdSubst -- InId |--> OutExpr + -- | Fast OutVarSet tracking which recursive RHSs we are analysing. + -- See Note [Eta reduction in recursive RHSs] in GHC.Core.Opt.Arity. + , seRecIds :: !UnVarSet + ----------- Dynamic part of the environment ----------- -- Dynamic in the sense of describing the setup where -- the expression finally ends up @@ -286,6 +291,7 @@ mkSimplEnv mode , seTvSubst = emptyVarEnv , seCvSubst = emptyVarEnv , seIdSubst = emptyVarEnv + , seRecIds = emptyUnVarSet , seCaseDepth = 0 } -- The top level "enclosing CC" is "SUBSUMED". @@ -391,6 +397,13 @@ modifyInScope :: SimplEnv -> CoreBndr -> SimplEnv modifyInScope env@(SimplEnv {seInScope = in_scope}) v = env {seInScope = extendInScopeSet in_scope v} +enterRecGroupRHSs :: SimplEnv -> [OutBndr] -> (SimplEnv -> SimplM (r, SimplEnv)) + -> SimplM (r, SimplEnv) +enterRecGroupRHSs env bndrs k = do + --pprTraceM "enterRecGroupRHSs" (ppr bndrs) + (r, env'') <- k env{seRecIds = extendUnVarSetList bndrs (seRecIds env)} + return (r, env''{seRecIds = seRecIds env}) + {- Note [Setting the right in-scope set] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -886,31 +899,18 @@ seqIds (id:ids) = seqId id `seq` seqIds ids Note [Arity robustness] ~~~~~~~~~~~~~~~~~~~~~~~ We *do* transfer the arity from the in_id of a let binding to the -out_id. This is important, so that the arity of an Id is visible in -its own RHS. For example: - f = \x. ....g (\y. f y).... -We can eta-reduce the arg to g, because f is a value. But that -needs to be visible. - -This interacts with the 'state hack' too: - f :: Bool -> IO Int - f = \x. case x of - True -> f y - False -> \s -> ... -Can we eta-expand f? Only if we see that f has arity 1, and then we -take advantage of the 'state hack' on the result of -(f y) :: State# -> (State#, Int) to expand the arity one more. - -There is a disadvantage though. Making the arity visible in the RHS -allows us to eta-reduce - f = \x -> f x -to - f = f -which technically is not sound. This is very much a corner case, so -I'm not worried about it. Another idea is to ensure that f's arity -never decreases; its arity started as 1, and we should never eta-reduce -below that. - +out_id so that its arity is visible in its RHS. Examples: + + * f = \x y. let g = \p q. f (p+q) in Just (...g..g...) + Here we want to give `g` arity 3 and eta-expand. `findRhsArity` will have a + hard time figuring that out when `f` only has arity 0 in its own RHS. + * f = \x y. ....(f `seq` blah).... + We want to drop the seq. + * f = \x. g (\y. f y) + You'd think we could eta-reduce `\y. f y` to `f` here. And indeed, that is true. + Unfortunately, it is not sound in general to eta-reduce in f's RHS. + Example: `f = \x. f x`. See Note [Eta reduction in recursive RHSs] for how + we prevent that. Note [Robust OccInfo] ~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1610,6 +1610,7 @@ mkLam env bndrs body cont ; mkLam' dflags bndrs body } where mode = getMode env + rec_ids = seRecIds env mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr mkLam' dflags bndrs body@(Lam {}) @@ -1633,7 +1634,7 @@ mkLam env bndrs body cont mkLam' dflags bndrs body | gopt Opt_DoEtaReduction dflags - , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce bndrs body + , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce rec_ids bndrs body = do { tick (EtaReduction (head bndrs)) ; return etad_lam } ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -52,6 +52,7 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc import GHC.Data.Maybe ( orElse ) +import GHC.Data.Graph.UnVar import Data.List (mapAccumL) import qualified Data.ByteString as BS @@ -193,6 +194,10 @@ data SimpleOptEnv , soe_subst :: Subst -- ^ Deals with cloning; includes the InScopeSet + + , soe_rec_ids :: !UnVarSet + -- ^ Fast OutVarSet tracking which recursive RHSs we are analysing. + -- See Note [Eta reduction in recursive RHSs] } instance Outputable SimpleOptEnv where @@ -205,6 +210,7 @@ emptyEnv :: SimpleOpts -> SimpleOptEnv emptyEnv opts = SOE { soe_inl = emptyVarEnv , soe_subst = emptySubst + , soe_rec_ids = emptyUnVarSet , soe_co_opt_opts = so_co_opts opts , soe_uf_opts = so_uf_opts opts } @@ -219,6 +225,13 @@ soeSetInScope (SOE { soe_subst = subst1 }) env2@(SOE { soe_subst = subst2 }) = env2 { soe_subst = setInScope subst2 (substInScope subst1) } +enterRecGroupRHSs :: SimpleOptEnv -> [OutBndr] -> (SimpleOptEnv -> (SimpleOptEnv, r)) + -> (SimpleOptEnv, r) +enterRecGroupRHSs env bndrs k + = (env'{soe_rec_ids = soe_rec_ids env}, r) + where + (env', r) = k env{soe_rec_ids = extendUnVarSetList bndrs (soe_rec_ids env)} + --------------- simple_opt_clo :: SimpleOptEnv -> SimpleClo -> OutExpr simple_opt_clo env (e_env, e) @@ -228,6 +241,7 @@ simple_opt_expr :: HasCallStack => SimpleOptEnv -> InExpr -> OutExpr simple_opt_expr env expr = go expr where + rec_ids = soe_rec_ids env subst = soe_subst env in_scope = substInScope subst in_scope_env = (in_scope, simpleUnfoldingFun) @@ -290,13 +304,16 @@ simple_opt_expr env expr ---------------------- -- go_lam tries eta reduction + -- It is quite important that it does so. I tried removing this code and + -- got a lot of regressions, e.g., +11% ghc/alloc in T18223 and many + -- run/alloc increases. Presumably RULEs are affected. go_lam env bs' (Lam b e) = go_lam env' (b':bs') e where (env', b') = subst_opt_bndr env b go_lam env bs' e - | Just etad_e <- tryEtaReduce bs e' = etad_e - | otherwise = mkLams bs e' + | Just etad_e <- tryEtaReduce rec_ids bs e' = etad_e + | otherwise = mkLams bs e' where bs = reverse bs' e' = simple_opt_expr env e @@ -390,12 +407,13 @@ simple_opt_bind env (NonRec b r) top_level (env', mb_pr) = simple_bind_pair env b' Nothing (env,r') top_level simple_opt_bind env (Rec prs) top_level - = (env'', res_bind) + = (env2, res_bind) where res_bind = Just (Rec (reverse rev_prs')) prs' = joinPointBindings_maybe prs `orElse` prs - (env', bndrs') = subst_opt_bndrs env (map fst prs') - (env'', rev_prs') = foldl' do_pr (env', []) (prs' `zip` bndrs') + (env1, bndrs') = subst_opt_bndrs env (map fst prs') + (env2, rev_prs') = enterRecGroupRHSs env1 bndrs' $ \env -> + foldl' do_pr (env, []) (prs' `zip` bndrs') do_pr (env, prs) ((b,r), b') = (env', case mb_pr of Just pr -> pr : prs ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -10,7 +10,7 @@ The code for *top-level* bindings is in GHC.Iface.Tidy. {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Core.Tidy ( - tidyExpr, tidyRules, tidyUnfolding, tidyCbvInfoTop + tidyExpr, tidyRules, tidyCbvInfoTop, tidyBndrs ) where import GHC.Prelude @@ -345,33 +345,36 @@ tidyLetBndr rec_tidy_env env@(tidy_env, var_env) id `setUnfoldingInfo` new_unf old_unf = realUnfoldingInfo old_info - new_unf | isStableUnfolding old_unf = tidyUnfolding rec_tidy_env old_unf old_unf - | otherwise = trimUnfolding old_unf - -- See Note [Preserve evaluatedness] + new_unf = tidyNestedUnfolding rec_tidy_env old_unf in ((tidy_env', var_env'), id') } ------------ Unfolding -------------- -tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding -tidyUnfolding tidy_env df@(DFunUnfolding { df_bndrs = bndrs, df_args = args }) _ +tidyNestedUnfolding :: TidyEnv -> Unfolding -> Unfolding +tidyNestedUnfolding _ NoUnfolding = NoUnfolding +tidyNestedUnfolding _ BootUnfolding = BootUnfolding +tidyNestedUnfolding _ (OtherCon {}) = evaldUnfolding + +tidyNestedUnfolding tidy_env df@(DFunUnfolding { df_bndrs = bndrs, df_args = args }) = df { df_bndrs = bndrs', df_args = map (tidyExpr tidy_env') args } where (tidy_env', bndrs') = tidyBndrs tidy_env bndrs -tidyUnfolding tidy_env - unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src }) - unf_from_rhs +tidyNestedUnfolding tidy_env + unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src, uf_is_value = is_value }) | isStableSource src = seqIt $ unf { uf_tmpl = tidyExpr tidy_env unf_rhs } -- Preserves OccInfo - -- This seqIt avoids a space leak: otherwise the uf_is_value, - -- uf_is_conlike, ... fields may retain a reference to the - -- pre-tidied expression forever (GHC.CoreToIface doesn't look at them) - - | otherwise - = unf_from_rhs - where seqIt unf = seqUnfolding unf `seq` unf -tidyUnfolding _ unf _ = unf -- NoUnfolding or OtherCon + -- This seqIt avoids a space leak: otherwise the uf_is_value, + -- uf_is_conlike, ... fields may retain a reference to the + -- pre-tidied expression forever (GHC.CoreToIface doesn't look at them) + + -- Discard unstable unfoldings, but see Note [Preserve evaluatedness] + | is_value = evaldUnfolding + | otherwise = noUnfolding + + where + seqIt unf = seqUnfolding unf `seq` unf {- Note [Tidy IdInfo] ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -26,8 +26,8 @@ module GHC.Core.Utils ( exprIsDupable, exprIsTrivial, getIdFromTrivialExpr, exprIsDeadEnd, getIdFromTrivialExpr_maybe, exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun, - exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprIsWorkFree, - exprIsConLike, + exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprOkForSpecEval, + exprIsWorkFree, exprIsConLike, isCheapApp, isExpandableApp, isSaturatedConApp, exprIsTickedString, exprIsTickedString_maybe, exprIsTopLevelBindable, @@ -86,6 +86,7 @@ import GHC.Core.Map.Expr ( eqCoreExpr ) import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofIdKey ) import GHC.Builtin.PrimOps +import GHC.Data.Graph.UnVar import GHC.Types.Var import GHC.Types.SrcLoc import GHC.Types.Var.Env @@ -1563,45 +1564,55 @@ it's applied only to dictionaries. -- side effects, and can't diverge or raise an exception. exprOkForSpeculation, exprOkForSideEffects :: CoreExpr -> Bool -exprOkForSpeculation = expr_ok primOpOkForSpeculation -exprOkForSideEffects = expr_ok primOpOkForSideEffects - -expr_ok :: (PrimOp -> Bool) -> CoreExpr -> Bool -expr_ok _ (Lit _) = True -expr_ok _ (Type _) = True -expr_ok _ (Coercion _) = True - -expr_ok primop_ok (Var v) = app_ok primop_ok v [] -expr_ok primop_ok (Cast e _) = expr_ok primop_ok e -expr_ok primop_ok (Lam b e) - | isTyVar b = expr_ok primop_ok e +exprOkForSpeculation = expr_ok fun_always_ok primOpOkForSpeculation +exprOkForSideEffects = expr_ok fun_always_ok primOpOkForSideEffects + +fun_always_ok :: Id -> Bool +fun_always_ok _ = True + +-- | A special version of 'exprOkForSpeculation' used during +-- Note [Speculative evaluation]. When the predicate arg `fun_ok` returns False +-- for `b`, then `b` is never considered ok-for-spec. +exprOkForSpecEval :: (Id -> Bool) -> CoreExpr -> Bool +exprOkForSpecEval fun_ok = expr_ok fun_ok primOpOkForSpeculation + +expr_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> CoreExpr -> Bool +expr_ok _ _ (Lit _) = True +expr_ok _ _ (Type _) = True +expr_ok _ _ (Coercion _) = True + +expr_ok fun_ok primop_ok (Var v) = app_ok fun_ok primop_ok v [] +expr_ok fun_ok primop_ok (Cast e _) = expr_ok fun_ok primop_ok e +expr_ok fun_ok primop_ok (Lam b e) + | isTyVar b = expr_ok fun_ok primop_ok e | otherwise = True -- Tick annotations that *tick* cannot be speculated, because these -- are meant to identify whether or not (and how often) the particular -- source expression was evaluated at runtime. -expr_ok primop_ok (Tick tickish e) +expr_ok fun_ok primop_ok (Tick tickish e) | tickishCounts tickish = False - | otherwise = expr_ok primop_ok e + | otherwise = expr_ok fun_ok primop_ok e -expr_ok _ (Let {}) = False +expr_ok _ _ (Let {}) = False -- Lets can be stacked deeply, so just give up. -- In any case, the argument of exprOkForSpeculation is -- usually in a strict context, so any lets will have been -- floated away. -expr_ok primop_ok (Case scrut bndr _ alts) +expr_ok fun_ok primop_ok (Case scrut bndr _ alts) = -- See Note [exprOkForSpeculation: case expressions] - expr_ok primop_ok scrut + expr_ok fun_ok primop_ok scrut && isUnliftedType (idType bndr) -- OK to call isUnliftedType: binders always have a fixed RuntimeRep - && all (\(Alt _ _ rhs) -> expr_ok primop_ok rhs) alts + && all (\(Alt _ _ rhs) -> expr_ok fun_ok primop_ok rhs) alts && altsAreExhaustive alts -expr_ok primop_ok other_expr +expr_ok fun_ok primop_ok other_expr | (expr, args) <- collectArgs other_expr = case stripTicksTopE (not . tickishCounts) expr of - Var f -> app_ok primop_ok f args + Var f -> + app_ok fun_ok primop_ok f args -- 'LitRubbish' is the only literal that can occur in the head of an -- application and will not be matched by the above case (Var /= Lit). @@ -1615,8 +1626,11 @@ expr_ok primop_ok other_expr _ -> False ----------------------------- -app_ok :: (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool -app_ok primop_ok fun args +app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool +app_ok fun_ok primop_ok fun args + | not (fun_ok fun) + = False -- This code path is only taken for Note [Speculative evaluation] + | otherwise = case idDetails fun of DFunId new_type -> not new_type -- DFuns terminate, unless the dict is implemented @@ -1630,7 +1644,7 @@ app_ok primop_ok fun args PrimOpId op | primOpIsDiv op , [arg1, Lit lit] <- args - -> not (isZeroLit lit) && expr_ok primop_ok arg1 + -> not (isZeroLit lit) && expr_ok fun_ok primop_ok arg1 -- Special case for dividing operations that fail -- In general they are NOT ok-for-speculation -- (which primop_ok will catch), but they ARE OK @@ -1679,7 +1693,7 @@ app_ok primop_ok fun args | Just Lifted <- typeLevity_maybe (scaledThing ty) = True -- See Note [Primops with lifted arguments] | otherwise - = expr_ok primop_ok arg + = expr_ok fun_ok primop_ok arg ----------------------------- altsAreExhaustive :: [Alt b] -> Bool @@ -2415,8 +2429,8 @@ need to address that here. -- When updating this function, make sure to update -- CorePrep.tryEtaReducePrep as well! -tryEtaReduce :: [Var] -> CoreExpr -> Maybe CoreExpr -tryEtaReduce bndrs body +tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> Maybe CoreExpr +tryEtaReduce rec_ids bndrs body = go (reverse bndrs) body (mkRepReflCo (exprType body)) where incoming_arity = count isId bndrs @@ -2455,14 +2469,15 @@ tryEtaReduce bndrs body ok_fun _fun = False --------------- - ok_fun_id fun = -- There are arguments to reduce... - fun_arity fun >= incoming_arity && - -- ... and the function can be eta reduced to arity 0 - canEtaReduceToArity fun 0 0 + ok_fun_id fun = + -- Don't eta-reduce in fun in its own recursive RHSs + not (fun `elemUnVarSet` rec_ids) && -- criterion (R) + -- There are arguments to reduce... + fun_arity fun >= incoming_arity && + -- ... and the function can be eta reduced to arity 0 + canEtaReduceToArity fun 0 0 --------------- fun_arity fun -- See Note [Arity care] - | isLocalId fun - , isStrongLoopBreaker (idOccInfo fun) = 0 | arity > 0 = arity | isEvaldUnfolding (idUnfolding fun) = 1 -- See Note [Eta reduction of an eval'd function] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -49,6 +49,7 @@ import GHC.Data.Maybe import GHC.Data.OrdList import GHC.Data.FastString import GHC.Data.Pair +import GHC.Data.Graph.UnVar import GHC.Utils.Error import GHC.Utils.Misc @@ -594,7 +595,7 @@ cpeBind top_lvl env (NonRec bndr rhs) | otherwise = addFloat floats new_float - new_float = mkFloat dmd is_unlifted bndr1 rhs1 + new_float = mkFloat env dmd is_unlifted bndr1 rhs1 ; return (env2, floats1, Nothing) } @@ -608,24 +609,27 @@ cpeBind top_lvl env (NonRec bndr rhs) cpeBind top_lvl env (Rec pairs) | not (isJoinId (head bndrs)) - = do { (env', bndrs1) <- cpCloneBndrs env bndrs + = do { (env, bndrs1) <- cpCloneBndrs env bndrs + ; let env' = enterRecGroupRHSs env bndrs1 ; stuff <- zipWithM (cpePair top_lvl Recursive topDmd False env') bndrs1 rhss ; let (floats_s, rhss1) = unzip stuff all_pairs = foldrOL add_float (bndrs1 `zip` rhss1) (concatFloats floats_s) - + -- use env below, so that we reset cpe_rec_ids ; return (extendCorePrepEnvList env (bndrs `zip` bndrs1), unitFloat (FloatLet (Rec all_pairs)), Nothing) } | otherwise -- See Note [Join points and floating] - = do { (env', bndrs1) <- cpCloneBndrs env bndrs + = do { (env, bndrs1) <- cpCloneBndrs env bndrs + ; let env' = enterRecGroupRHSs env bndrs1 ; pairs1 <- zipWithM (cpeJoinPair env') bndrs1 rhss ; let bndrs2 = map fst pairs1 - ; return (extendCorePrepEnvList env' (bndrs `zip` bndrs2), + -- use env below, so that we reset cpe_rec_ids + ; return (extendCorePrepEnvList env (bndrs `zip` bndrs2), emptyFloats, Just (Rec pairs1)) } where @@ -657,7 +661,7 @@ cpePair top_lvl is_rec dmd is_unlifted env bndr rhs else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] (do { v <- newVar (idType bndr) - ; let float = mkFloat topDmd False v rhs2 + ; let float = mkFloat env topDmd False v rhs2 ; return ( addFloat floats2 float , cpeEtaExpand arity (Var v)) }) @@ -1464,7 +1468,7 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 - arg_float = mkFloat dmd is_unlifted v arg3 + arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } @@ -1669,6 +1673,66 @@ to allocate a thunk for it, whose closure must be retained as long as the callee might evaluate it. And if it is evaluated on most code paths anyway, we get to turn the unknown eval in the callee into a known call at the call site. + +However, we must be very careful not to speculate recursive calls! +Doing so might well change termination behavior. + +That comes up in practice for DFuns, which are considered ok-for-spec, +because they always immediately return a constructor. +Not so if you speculate the recursive call, as #20836 shows: + + class Foo m => Foo m where + runFoo :: m a -> m a + newtype Trans m a = Trans { runTrans :: m a } + instance Monad m => Foo (Trans m) where + runFoo = id + +(NB: class Foo m => Foo m` looks weird and needs -XUndecidableSuperClasses. The +example in #20836 is more compelling, but boils down to the same thing.) +This program compiles to the following DFun for the `Trans` instance: + + Rec { + $fFooTrans + = \ @m $dMonad -> C:Foo ($fFooTrans $dMonad) (\ @a -> id) + end Rec } + +Note that the DFun immediately terminates and produces a dictionary, just +like DFuns ought to, but it calls itself recursively to produce the `Foo m` +dictionary. But alas, if we treat `$fFooTrans` as always-terminating, so +that we can speculate its calls, and hence use call-by-value, we get: + + $fFooTrans + = \ @m $dMonad -> case ($fFooTrans $dMonad) of sc -> + C:Foo sc (\ @a -> id) + +and that's an infinite loop! +Note that this bad-ness only happens in `$fFooTrans`'s own RHS. In the +*body* of the letrec, it's absolutely fine to use call-by-value on +`foo ($fFooTrans d)`. + +Our solution is this: we track in cpe_rec_ids the set of enclosing +recursively-bound Ids, the RHSs of which we are currently transforming and then +in 'exprOkForSpecEval' (a special entry point to 'exprOkForSpeculation', +basically) we'll say that any binder in this set is not ok-for-spec. + +Note if we have a letrec group `Rec { f1 = rhs1; ...; fn = rhsn }`, and we +prep up `rhs1`, we have to include not only `f1`, but all binders of the group +`f1..fn` in this set, otherwise our fix is not robust wrt. mutual recursive +DFuns. + +NB: If at some point we decide to have a termination analysis for general +functions (#8655, !1866), we need to take similar precautions for (guarded) +recursive functions: + + repeat x = x : repeat x + +Same problem here: As written, repeat evaluates rapidly to WHNF. So `repeat x` +is a cheap call that we are willing to speculate, but *not* in repeat's RHS. +Fortunately, pce_rec_ids already has all the information we need in that case. + +The problem is very similar to Note [Eta reduction in recursive RHSs]. +Here as well as there it is *unsound* to change the termination properties +of the very function whose termination properties we are exploiting. -} data FloatingBind @@ -1715,8 +1779,8 @@ data OkToSpec -- ok-to-speculate unlifted bindings | NotOkToSpec -- Some not-ok-to-speculate unlifted bindings -mkFloat :: Demand -> Bool -> Id -> CpeRhs -> FloatingBind -mkFloat dmd is_unlifted bndr rhs +mkFloat :: CorePrepEnv -> Demand -> Bool -> Id -> CpeRhs -> FloatingBind +mkFloat env dmd is_unlifted bndr rhs | is_strict || ok_for_spec -- See Note [Speculative evaluation] , not is_hnf = FloatCase rhs bndr DEFAULT [] ok_for_spec -- Don't make a case for a HNF binding, even if it's strict @@ -1743,7 +1807,8 @@ mkFloat dmd is_unlifted bndr rhs where is_hnf = exprIsHNF rhs is_strict = isStrUsedDmd dmd - ok_for_spec = exprOkForSpeculation rhs + ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + is_rec_call = (`elemUnVarSet` cpe_rec_ids env) emptyFloats :: Floats emptyFloats = Floats OkToSpec nilOL @@ -1941,6 +2006,7 @@ data CorePrepEnv , cpe_convertNumLit :: LitNumType -> Integer -> Maybe CoreExpr -- ^ Convert some numeric literals (Integer, Natural) into their -- final Core form + , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } mkInitialCorePrepEnv :: HscEnv -> IO CorePrepEnv @@ -1951,6 +2017,7 @@ mkInitialCorePrepEnv hsc_env = do , cpe_env = emptyVarEnv , cpe_tyco_env = Nothing , cpe_convertNumLit = convertNumLit + , cpe_rec_ids = emptyUnVarSet } extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv @@ -1972,6 +2039,10 @@ lookupCorePrepEnv cpe id Nothing -> Var id Just exp -> exp +enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv +enterRecGroupRHSs env grp + = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } + ------------------------------------------------------------------------------ -- CpeTyCoEnv -- --------------------------------------------------------------------------- ===================================== compiler/GHC/Data/Graph/UnVar.hs ===================================== @@ -17,7 +17,7 @@ equal to g, but twice as expensive and large. module GHC.Data.Graph.UnVar ( UnVarSet , emptyUnVarSet, mkUnVarSet, varEnvDom, unionUnVarSet, unionUnVarSets - , extendUnVarSet, delUnVarSet + , extendUnVarSet, extendUnVarSetList, delUnVarSet, delUnVarSetList , elemUnVarSet, isEmptyUnVarSet , UnVarGraph , emptyUnVarGraph @@ -63,6 +63,9 @@ isEmptyUnVarSet (UnVarSet s) = S.null s delUnVarSet :: UnVarSet -> Var -> UnVarSet delUnVarSet (UnVarSet s) v = UnVarSet $ k v `S.delete` s +delUnVarSetList :: UnVarSet -> [Var] -> UnVarSet +delUnVarSetList s vs = s `minusUnVarSet` mkUnVarSet vs + minusUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet minusUnVarSet (UnVarSet s) (UnVarSet s') = UnVarSet $ s `S.difference` s' @@ -78,6 +81,9 @@ varEnvDom ae = UnVarSet $ ufmToSet_Directly ae extendUnVarSet :: Var -> UnVarSet -> UnVarSet extendUnVarSet v (UnVarSet s) = UnVarSet $ S.insert (k v) s +extendUnVarSetList :: [Var] -> UnVarSet -> UnVarSet +extendUnVarSetList vs s = s `unionUnVarSet` mkUnVarSet vs + unionUnVarSet :: UnVarSet -> UnVarSet -> UnVarSet unionUnVarSet (UnVarSet set1) (UnVarSet set2) = UnVarSet (set1 `S.union` set2) ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -24,13 +24,12 @@ import GHC.Tc.Utils.Env import GHC.Core import GHC.Core.Unfold -import GHC.Core.Unfold.Make import GHC.Core.FVs import GHC.Core.Tidy import GHC.Core.Seq (seqBinds) -import GHC.Core.Opt.Arity ( exprArity, exprBotStrictness_maybe ) +import GHC.Core.Opt.Arity ( exprArity, exprBotStrictness_maybe, typeArity ) import GHC.Core.InstEnv -import GHC.Core.Type ( tidyTopType ) +import GHC.Core.Type ( tidyTopType, Type ) import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Core.Class @@ -74,6 +73,7 @@ import Data.Function import Data.List ( sortBy, mapAccumL ) import qualified Data.Set as S import GHC.Types.CostCentre +import GHC.Core.Opt.OccurAnal (occurAnalyseExpr) {- Constructing the TypeEnv, Instances, Rules from which the @@ -384,8 +384,7 @@ tidyProgram opts (ModGuts { mg_module = mod (unfold_env, tidy_occ_env) <- chooseExternalIds opts mod binds implicit_binds imp_rules let (trimmed_binds, trimmed_rules) = findExternalRules opts binds imp_rules unfold_env - let uf_opts = opt_unfolding_opts opts - (tidy_env, tidy_binds) <- tidyTopBinds uf_opts unfold_env boot_exports tidy_occ_env trimmed_binds + (tidy_env, tidy_binds) <- tidyTopBinds unfold_env boot_exports tidy_occ_env trimmed_binds -- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable. (spt_entries, mcstub, tidy_binds') <- case opt_static_ptr_opts opts of @@ -1146,60 +1145,49 @@ tidyTopName mod name_cache maybe_ref occ_env id -- -- * subst_env: A Var->Var mapping that substitutes the new Var for the old -tidyTopBinds :: UnfoldingOpts - -> UnfoldEnv +tidyTopBinds :: UnfoldEnv -> NameSet -> TidyOccEnv -> CoreProgram -> IO (TidyEnv, CoreProgram) -tidyTopBinds uf_opts unfold_env boot_exports init_occ_env binds +tidyTopBinds unfold_env boot_exports init_occ_env binds = do let result = tidy init_env binds seqBinds (snd result) `seq` return result -- This seqBinds avoids a spike in space usage (see #13564) where init_env = (init_occ_env, emptyVarEnv) - tidy = mapAccumL (tidyTopBind uf_opts unfold_env boot_exports) + tidy = mapAccumL (tidyTopBind unfold_env boot_exports) ------------------------ -tidyTopBind :: UnfoldingOpts - -> UnfoldEnv +tidyTopBind :: UnfoldEnv -> NameSet -> TidyEnv -> CoreBind -> (TidyEnv, CoreBind) -tidyTopBind uf_opts unfold_env boot_exports +tidyTopBind unfold_env boot_exports (occ_env,subst1) (NonRec bndr rhs) = (tidy_env2, NonRec bndr' rhs') where - Just (name',show_unfold) = lookupVarEnv unfold_env bndr - (bndr', rhs') = tidyTopPair uf_opts show_unfold boot_exports tidy_env2 name' (bndr, rhs) + (bndr', rhs') = tidyTopPair unfold_env boot_exports tidy_env2 (bndr, rhs) subst2 = extendVarEnv subst1 bndr bndr' tidy_env2 = (occ_env, subst2) -tidyTopBind uf_opts unfold_env boot_exports (occ_env, subst1) (Rec prs) +tidyTopBind unfold_env boot_exports (occ_env, subst1) (Rec prs) = (tidy_env2, Rec prs') where - prs' = [ tidyTopPair uf_opts show_unfold boot_exports tidy_env2 name' (id,rhs) - | (id,rhs) <- prs, - let (name',show_unfold) = - expectJust "tidyTopBind" $ lookupVarEnv unfold_env id - ] - - subst2 = extendVarEnvList subst1 (bndrs `zip` map fst prs') + prs' = map (tidyTopPair unfold_env boot_exports tidy_env2) prs + subst2 = extendVarEnvList subst1 (map fst prs `zip` map fst prs') tidy_env2 = (occ_env, subst2) - - bndrs = map fst prs + -- This is where we "tie the knot": tidy_env2 is fed into tidyTopPair ----------------------------------------------------------- -tidyTopPair :: UnfoldingOpts - -> Bool -- show unfolding +tidyTopPair :: UnfoldEnv -> NameSet -> TidyEnv -- The TidyEnv is used to tidy the IdInfo -- It is knot-tied: don't look at it! - -> Name -- New name -> (Id, CoreExpr) -- Binder and RHS before tidying -> (Id, CoreExpr) -- This function is the heart of Step 2 @@ -1208,18 +1196,19 @@ tidyTopPair :: UnfoldingOpts -- group, a variable late in the group might be mentioned -- in the IdInfo of one early in the group -tidyTopPair uf_opts show_unfold boot_exports rhs_tidy_env name' (bndr, rhs) +tidyTopPair unfold_env boot_exports rhs_tidy_env (bndr, rhs) = -- pprTrace "tidyTop" (ppr name' <+> ppr details <+> ppr rhs) $ (bndr1, rhs1) where + Just (name',show_unfold) = lookupVarEnv unfold_env bndr !cbv_bndr = tidyCbvInfoTop boot_exports bndr rhs bndr1 = mkGlobalId details name' ty' idinfo' details = idDetails cbv_bndr -- Preserve the IdDetails ty' = tidyTopType (idType cbv_bndr) rhs1 = tidyExpr rhs_tidy_env rhs - idinfo' = tidyTopIdInfo uf_opts rhs_tidy_env name' rhs rhs1 (idInfo cbv_bndr) - show_unfold + idinfo' = tidyTopIdInfo rhs_tidy_env name' ty' + rhs rhs1 (idInfo cbv_bndr) show_unfold -- tidyTopIdInfo creates the final IdInfo for top-level -- binders. The delicate piece: @@ -1228,9 +1217,9 @@ tidyTopPair uf_opts show_unfold boot_exports rhs_tidy_env name' (bndr, rhs) -- Indeed, CorePrep must eta expand where necessary to make -- the manifest arity equal to the claimed arity. -- -tidyTopIdInfo :: UnfoldingOpts -> TidyEnv -> Name -> CoreExpr -> CoreExpr +tidyTopIdInfo :: TidyEnv -> Name -> Type -> CoreExpr -> CoreExpr -> IdInfo -> Bool -> IdInfo -tidyTopIdInfo uf_opts rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold +tidyTopIdInfo rhs_tidy_env name rhs_ty orig_rhs tidy_rhs idinfo show_unfold | not is_external -- For internal Ids (not externally visible) = vanillaIdInfo -- we only need enough info for code generation -- Arity and strictness info are enough; @@ -1281,13 +1270,17 @@ tidyTopIdInfo uf_opts rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold --------- Unfolding ------------ unf_info = realUnfoldingInfo idinfo - unfold_info - | isCompulsoryUnfolding unf_info || show_unfold - = tidyUnfolding rhs_tidy_env unf_info unf_from_rhs - | otherwise - = minimal_unfold_info - minimal_unfold_info = trimUnfolding unf_info - unf_from_rhs = mkFinalUnfolding uf_opts InlineRhs final_sig tidy_rhs + !minimal_unfold_info = trimUnfolding unf_info + + !unfold_info | isCompulsoryUnfolding unf_info || show_unfold + = tidyTopUnfolding rhs_tidy_env tidy_rhs unf_info + | otherwise + = minimal_unfold_info + + -- NB: use `orig_rhs` not `tidy_rhs` in this call to mkFinalUnfolding + -- else you get a black hole (#22122). Reason: mkFinalUnfolding + -- looks at IdInfo, and that is knot-tied in tidyTopBind (the Rec case) + -- 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 @@ -1311,4 +1304,54 @@ tidyTopIdInfo uf_opts rhs_tidy_env name orig_rhs tidy_rhs idinfo show_unfold -- did was to let-bind a non-atomic argument and then float -- it to the top level. So it seems more robust just to -- fix it here. - arity = exprArity orig_rhs + arity = exprArity orig_rhs `min` (length $ typeArity rhs_ty) + + +------------ Unfolding -------------- +tidyTopUnfolding :: TidyEnv -> CoreExpr -> Unfolding -> Unfolding +tidyTopUnfolding _ _ NoUnfolding = NoUnfolding +tidyTopUnfolding _ _ BootUnfolding = BootUnfolding +tidyTopUnfolding _ _ (OtherCon {}) = evaldUnfolding + +tidyTopUnfolding tidy_env _ df@(DFunUnfolding { df_bndrs = bndrs, df_args = args }) + = df { df_bndrs = bndrs', df_args = map (tidyExpr tidy_env') args } + where + (tidy_env', bndrs') = tidyBndrs tidy_env bndrs + +tidyTopUnfolding tidy_env tidy_rhs + unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src }) + = -- See Note [tidyTopUnfolding: avoiding black holes] + unf { uf_tmpl = tidy_unf_rhs } + where + tidy_unf_rhs | isStableSource src + = tidyExpr tidy_env unf_rhs -- Preserves OccInfo in unf_rhs + | otherwise + = occurAnalyseExpr tidy_rhs -- Do occ-anal + +{- Note [tidyTopUnfolding: avoiding black holes] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we are exposing all unfoldings we don't want to tidy the unfolding +twice -- we just want to use the tidied RHS. That tidied RHS itself +contains fully-tidied Ids -- it is knot-tied. So the uf_tmpl for the +unfolding contains stuff we can't look at. Now consider (#22112) + foo = foo +If we freshly compute the uf_is_value field for foo's unfolding, +we'll call `exprIsValue`, which will look at foo's unfolding! +Whether or not the RHS is a value depends on whether foo is a value... +black hole. + +In the Simplifier we deal with this by not giving `foo` an unfolding +in its own RHS. And we could do that here. But it's qite nice +to common everything up to a single Id for foo, used everywhere. + +And it's not too hard: simply leave the unfolding undisturbed, except +tidy the uf_tmpl field. Hence tidyTopUnfolding does + unf { uf_tmpl = tidy_unf_rhs } + +Don't mess with uf_is_value, or guidance; in particular don't recompute +them from tidy_unf_rhs. + +And (unlike tidyNestedUnfolding) don't deep-seq the new unfolding, +because that'll cause a black hole (I /think/ because occurAnalyseExpr +looks in IdInfo). +-} \ No newline at end of file ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -834,7 +834,7 @@ zapFragileUnfolding unf trimUnfolding :: Unfolding -> Unfolding -- Squash all unfolding info, preserving only evaluated-ness trimUnfolding unf | isEvaldUnfolding unf = evaldUnfolding - | otherwise = noUnfolding + | otherwise = noUnfolding zapTailCallInfo :: IdInfo -> Maybe IdInfo zapTailCallInfo info ===================================== testsuite/tests/arityanal/should_compile/Arity03.stderr ===================================== @@ -18,20 +18,15 @@ end Rec } fac [InlPrag=[2]] :: Int -> Int [GblId, Arity=1, - Str=<1P(1L)>, - Cpr=m1, + Str=<1!P(1L)>, + Cpr=1, 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= \ (w [Occ=Once1!] :: Int) -> case w of { GHC.Types.I# ww1 [Occ=Once1] -> case F3.$wfac ww1 of ww2 [Occ=Once1] { __DEFAULT -> GHC.Types.I# ww2 } }}] -fac = \ (w :: Int) -> case w of { GHC.Types.I# ww1 -> case F3.$wfac ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } } + Tmpl= \ (x [Occ=Once1!] :: Int) -> case x of { GHC.Types.I# ww [Occ=Once1] -> case F3.$wfac ww of ww1 [Occ=Once1] { __DEFAULT -> GHC.Types.I# ww1 } }}] +fac = \ (x :: Int) -> case x of { GHC.Types.I# ww -> case F3.$wfac ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} f3 :: Int -> Int -[GblId, - Arity=1, - Str=<1P(1L)>, - Cpr=m1, - 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) - Tmpl= fac}] +[GblId, Arity=1, Str=<1!P(1L)>, Cpr=1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] f3 = fac ===================================== testsuite/tests/arityanal/should_run/Makefile ===================================== @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk ===================================== testsuite/tests/arityanal/should_run/T21652.hs ===================================== @@ -0,0 +1,10 @@ +import GHC.Exts + +f, g :: a -> a +f = g +g x = f x +{-# NOINLINE f #-} +{-# NOINLINE g #-} + +-- should print done, not <> +main = lazy g `seq` putStrLn "done" ===================================== testsuite/tests/arityanal/should_run/T21652.stdout ===================================== @@ -0,0 +1 @@ +done ===================================== testsuite/tests/arityanal/should_run/all.T ===================================== @@ -0,0 +1,2 @@ +# Regression tests +test('T21652', [ only_ways(['optasm']) ], compile_and_run, ['']) ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -1,4 +1,4 @@ -Found 282 Language.Haskell.Syntax module dependencies +Found 283 Language.Haskell.Syntax module dependencies GHC.Builtin.Names GHC.Builtin.PrimOps GHC.Builtin.PrimOps.Ids @@ -74,6 +74,7 @@ GHC.Data.FastString GHC.Data.FastString.Env GHC.Data.FiniteMap GHC.Data.Graph.Directed +GHC.Data.Graph.UnVar GHC.Data.IOEnv GHC.Data.List.SetOps GHC.Data.Maybe ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -1,4 +1,4 @@ -Found 289 GHC.Parser module dependencies +Found 290 GHC.Parser module dependencies GHC.Builtin.Names GHC.Builtin.PrimOps GHC.Builtin.PrimOps.Ids @@ -74,6 +74,7 @@ GHC.Data.FastString GHC.Data.FastString.Env GHC.Data.FiniteMap GHC.Data.Graph.Directed +GHC.Data.Graph.UnVar GHC.Data.IOEnv GHC.Data.List.SetOps GHC.Data.Maybe ===================================== testsuite/tests/deSugar/should_compile/T19969.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 12, types: 18, coercions: 0, joins: 0/0} + = {terms: 8, types: 14, coercions: 0, joins: 0/0} Rec { -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} @@ -10,7 +10,7 @@ f [Occ=LoopBreaker] :: [Int] -> [Int] f = \ (x :: [Int]) -> f x end Rec } --- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} g [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, @@ -19,10 +19,10 @@ g [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) - Tmpl= \ (x [Occ=Once1] :: [Int]) -> f x}] -g = \ (x :: [Int]) -> f x + Tmpl= f}] +g = f --- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} h [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, @@ -31,8 +31,8 @@ h [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) - Tmpl= \ (x [Occ=Once1] :: [Int]) -> f x}] -h = \ (x :: [Int]) -> f x + Tmpl= f}] +h = f ===================================== testsuite/tests/simplCore/should_compile/T22112.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE NoImplicitPrelude #-} +module Rec where + +-- This one created a black hole in Tidy, +-- when creating the tidied unfolding for foo +foo :: () -> () +foo = foo ===================================== testsuite/tests/simplCore/should_compile/T22112.stderr ===================================== @@ -0,0 +1,14 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 2, types: 2, coercions: 0, joins: 0/0} + +Rec { +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +foo [Occ=LoopBreaker] :: () -> () +[GblId, Str=b, Cpr=b] +foo = foo +end Rec } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -393,4 +393,5 @@ test('OpaqueNoStrictArgWW', normal, compile, ['-O -fworker-wrapper-cbv -ddump-si test('OpaqueNoWW', normal, compile, ['-O -ddump-simpl -dsuppress-uniques']) test('T21144', normal, compile, ['-O']) +test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddump-simpl']) ===================================== testsuite/tests/simplCore/should_run/T20836.hs ===================================== @@ -0,0 +1,23 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableSuperClasses #-} + +import Data.Kind (Type) + +class (Monad m, MonadFoo (FooM m)) => MonadFoo m where + type FooM m :: Type -> Type + runFoo :: FooM m a -> m a + +newtype MyMonad m a = MyMonad { runMyMonad :: m a } + deriving (Functor, Applicative, Monad) + +instance Monad m => MonadFoo (MyMonad m) where + type FooM (MyMonad m) = MyMonad m + runFoo = id + +main :: IO () +main = runMyMonad foo + +foo :: MonadFoo m => m () +foo = runFoo $ return () ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -102,3 +102,4 @@ test('T20203', normal, compile, ['-O -dsuppress-all -dsuppress-uniques -dno-type test('T19313', expect_broken(19131), compile_and_run, ['']) test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) +test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8a889a7fc670532a3bf883a3e25acba92e6e6e1...3e4a38c8b88a93cc740b7432902e46586e10eab1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8a889a7fc670532a3bf883a3e25acba92e6e6e1...3e4a38c8b88a93cc740b7432902e46586e10eab1 You're receiving 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 Oct 14 20:47:51 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Oct 2022 16:47:51 -0400 Subject: [Git][ghc/ghc][wip/backports-9.4] 5 commits: haddock docs: Fix links from identifiers to dependent packages Message-ID: <6349caf76a6b7_8b90f517d4151330@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.4 at Glasgow Haskell Compiler / GHC Commits: 9f2bda74 by Matthew Pickering at 2022-10-14T16:26:39-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 (cherry picked from commit 2361b3bc08811b0d2fb8f8fc5635b7c2fec157c6) - - - - - 235996c2 by Ryan Scott at 2022-10-14T16:31:32-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. (cherry picked from commit 8a666ad2a89a8ad2aa24a6406b88f516afaec671) - - - - - 09521b70 by Ryan Scott at 2022-10-14T16:33:56-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. (cherry picked from commit 3a815f30bcba5672085e823aeef90863253b0b1a) - - - - - 7d269ec1 by Cheng Shao at 2022-10-14T16:37:50-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh (cherry picked from commit ee471dfb8a4a4bb5131a5baa61d1d0d22c933d5f) - - - - - f3f737a7 by Matthew Pickering at 2022-10-14T16:47:12-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 (cherry picked from commit 7f0decd5063a853fc8f38a8944b2c91995cd5e48) - - - - - 17 changed files: - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Utils/Binary.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Settings/Builders/Haddock.hs - m4/fp_setup_windows_toolchain.m4 - rts/PrimOps.cmm - + testsuite/tests/deriving/should_compile/T22167.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/ffi/should_run/Makefile - + testsuite/tests/ffi/should_run/T22159.hs - + testsuite/tests/ffi/should_run/T22159.stdout - + testsuite/tests/ffi/should_run/T22159_c.c - testsuite/tests/ffi/should_run/all.T Changes: ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -781,5 +781,5 @@ toHieName name | isKnownKeyName name = KnownKeyName (nameUnique name) | isExternalName name = ExternalName (nameModule name) (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) + (removeBufSpan $ nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (removeBufSpan $ nameSrcSpan name) ===================================== compiler/GHC/Tc/Deriv/Functor.hs ===================================== @@ -538,8 +538,36 @@ functorLikeTraverse var (FT { ft_triv = caseTrivial, ft_var = caseVar go _ _ = (caseTrivial,False) --- Return all syntactic subterms of ty that contain var somewhere --- These are the things that should appear in instance constraints +-- | Return all syntactic subterms of a 'Type' that are applied to the 'TyVar' +-- argument. This determines what constraints should be inferred for derived +-- 'Functor', 'Foldable', and 'Traversable' instances in "GHC.Tc.Deriv.Infer". +-- For instance, if we have: +-- +-- @ +-- data Foo a = MkFoo Int a (Maybe a) (Either Int (Maybe a)) +-- @ +-- +-- Then the following would hold: +-- +-- * @'deepSubtypesContaining' a Int@ would return @[]@, since @Int@ does not +-- contain the type variable @a@ at all. +-- +-- * @'deepSubtypesContaining' a a@ would return @[]@. Although the type @a@ +-- contains the type variable @a@, it is not /applied/ to @a@, which is the +-- criterion that 'deepSubtypesContaining' checks for. +-- +-- * @'deepSubtypesContaining' a (Maybe a)@ would return @[Maybe]@, as @Maybe@ +-- is applied to @a at . +-- +-- * @'deepSubtypesContaining' a (Either Int (Maybe a))@ would return +-- @[Either Int, Maybe]@. Both of these types are applied to @a@ through +-- composition. +-- +-- As used in "GHC.Tc.Deriv.Infer", the 'Type' argument will always come from +-- 'derivDataConInstArgTys', so it is important that the 'TyVar' comes from +-- 'dataConUnivTyVars' to match. Make sure /not/ to take the 'TyVar' from +-- 'tyConTyVars', as these differ from the 'dataConUnivTyVars' when the data +-- type is a GADT. (See #22167 for what goes wrong if 'tyConTyVars' is used.) deepSubtypesContaining :: TyVar -> Type -> [TcType] deepSubtypesContaining tv = functorLikeTraverse tv ===================================== compiler/GHC/Tc/Deriv/Generics.hs ===================================== @@ -91,10 +91,25 @@ gen_Generic_binds gk loc dit = do ************************************************************************ -} +-- | Called by 'GHC.Tc.Deriv.Infer.inferConstraints'; generates a list of +-- types, each of which must be a 'Functor' in order for the 'Generic1' +-- instance to work. For instance, if we have: +-- +-- @ +-- data Foo a = MkFoo Int a (Maybe a) (Either Int (Maybe a)) +-- @ +-- +-- Then @'get_gen1_constrained_tys' a (f (g a))@ would return @[Either Int]@, +-- as a derived 'Generic1' instance would need to call 'fmap' at that type. +-- Invoking @'get_gen1_constrained_tys' a@ on any of the other fields would +-- return @[]@. +-- +-- 'get_gen1_constrained_tys' is very similar in spirit to +-- 'deepSubtypesContaining' in "GHC.Tc.Deriv.Functor". Just like with +-- 'deepSubtypesContaining', it is important that the 'TyVar' argument come +-- from 'dataConUnivTyVars'. (See #22167 for what goes wrong if 'tyConTyVars' +-- is used.) get_gen1_constrained_tys :: TyVar -> Type -> [Type] --- called by GHC.Tc.Deriv.Infer.inferConstraints; generates a list of --- types, each of which must be a Functor in order for the Generic1 instance to --- work. get_gen1_constrained_tys argVar = argTyFold argVar $ ArgTyAlg { ata_rec0 = const [] , ata_par1 = [], ata_rec1 = const [] ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -176,9 +176,10 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys -- Constraints arising from the arguments of each constructor con_arg_constraints - :: (CtOrigin -> TypeOrKind - -> Type - -> [(ThetaSpec, Maybe TCvSubst)]) + :: ([TyVar] -> CtOrigin + -> TypeOrKind + -> Type + -> [(ThetaSpec, Maybe TCvSubst)]) -> (ThetaSpec, [TyVar], [TcType], DerivInstTys) con_arg_constraints get_arg_constraints = let -- Constraints from the fields of each data constructor. @@ -193,7 +194,8 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys , not (isUnliftedType arg_ty) , let orig = DerivOriginDC data_con arg_n wildcard , preds_and_mbSubst - <- get_arg_constraints orig arg_t_or_k arg_ty + <- get_arg_constraints (dataConUnivTyVars data_con) + orig arg_t_or_k arg_ty ] -- Stupid constraints from DatatypeContexts. Note that we -- must gather these constraints from the data constructors, @@ -235,21 +237,39 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys is_functor_like = tcTypeKind inst_ty `tcEqKind` typeToTypeKind || is_generic1 - get_gen1_constraints :: Class -> CtOrigin -> TypeOrKind -> Type - -> [(ThetaSpec, Maybe TCvSubst)] - get_gen1_constraints functor_cls orig t_or_k ty + get_gen1_constraints :: + Class + -> [TyVar] -- The universally quantified type variables for the + -- data constructor + -> CtOrigin -> TypeOrKind -> Type + -> [(ThetaSpec, Maybe TCvSubst)] + get_gen1_constraints functor_cls dc_univs orig t_or_k ty = mk_functor_like_constraints orig t_or_k functor_cls $ - get_gen1_constrained_tys last_tv ty - - get_std_constrained_tys :: CtOrigin -> TypeOrKind -> Type - -> [(ThetaSpec, Maybe TCvSubst)] - get_std_constrained_tys orig t_or_k ty + get_gen1_constrained_tys last_dc_univ ty + where + -- If we are deriving an instance of 'Generic1' and have made + -- it this far, then there should be at least one universal type + -- variable, making this use of 'last' safe. + last_dc_univ = assert (not (null dc_univs)) $ + last dc_univs + + get_std_constrained_tys :: + [TyVar] -- The universally quantified type variables for the + -- data constructor + -> CtOrigin -> TypeOrKind -> Type + -> [(ThetaSpec, Maybe TCvSubst)] + get_std_constrained_tys dc_univs orig t_or_k ty | is_functor_like = mk_functor_like_constraints orig t_or_k main_cls $ - deepSubtypesContaining last_tv ty + deepSubtypesContaining last_dc_univ ty | otherwise = [( [mk_cls_pred orig t_or_k main_cls ty] , Nothing )] + where + -- If 'is_functor_like' holds, then there should be at least one + -- universal type variable, making this use of 'last' safe. + last_dc_univ = assert (not (null dc_univs)) $ + last dc_univs mk_functor_like_constraints :: CtOrigin -> TypeOrKind -> Class -> [Type] @@ -277,9 +297,6 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys , tcUnifyTy ki typeToTypeKind ) - rep_tc_tvs = tyConTyVars rep_tc - last_tv = last rep_tc_tvs - -- Extra Data constraints -- The Data class (only) requires that for -- instance (...) => Data (T t1 t2) @@ -318,7 +335,7 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys -- Generic1 needs Functor -- See Note [Getting base classes] | is_generic1 - -> assert (rep_tc_tvs `lengthExceeds` 0) $ + -> assert (tyConTyVars rep_tc `lengthExceeds` 0) $ -- Generic1 has a single kind variable assert (cls_tys `lengthIs` 1) $ do { functorClass <- lift $ tcLookupClass functorClassName ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -68,6 +68,7 @@ module GHC.Types.SrcLoc ( getBufPos, BufSpan(..), getBufSpan, + removeBufSpan, -- * Located Located, @@ -398,6 +399,10 @@ data UnhelpfulSpanReason | UnhelpfulOther !FastString deriving (Eq, Show) +removeBufSpan :: SrcSpan -> SrcSpan +removeBufSpan (RealSrcSpan s _) = RealSrcSpan s Strict.Nothing +removeBufSpan s = s + {- Note [Why Maybe BufPos] ~~~~~~~~~~~~~~~~~~~~~~~~~~ In SrcLoc we store (Maybe BufPos); in SrcSpan we store (Maybe BufSpan). ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -1306,19 +1306,6 @@ instance Binary RealSrcSpan where return (mkRealSrcSpan (mkRealSrcLoc f sl sc) (mkRealSrcLoc f el ec)) -instance Binary BufPos where - put_ bh (BufPos i) = put_ bh i - get bh = BufPos <$> get bh - -instance Binary BufSpan where - put_ bh (BufSpan start end) = do - put_ bh start - put_ bh end - get bh = do - start <- get bh - end <- get bh - return (BufSpan start end) - instance Binary UnhelpfulSpanReason where put_ bh r = case r of UnhelpfulNoLocationInfo -> putByte bh 0 @@ -1337,10 +1324,11 @@ instance Binary UnhelpfulSpanReason where _ -> UnhelpfulOther <$> get bh instance Binary SrcSpan where - put_ bh (RealSrcSpan ss sb) = do + put_ bh (RealSrcSpan ss _sb) = do putByte bh 0 + -- BufSpan doesn't ever get serialised because the positions depend + -- on build location. put_ bh ss - put_ bh sb put_ bh (UnhelpfulSpan s) = do putByte bh 1 @@ -1350,8 +1338,7 @@ instance Binary SrcSpan where h <- getByte bh case h of 0 -> do ss <- get bh - sb <- get bh - return (RealSrcSpan ss sb) + return (RealSrcSpan ss Strict.Nothing) _ -> do s <- get bh return (UnhelpfulSpan s) ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -249,7 +249,7 @@ buildPackageDocumentation = do vanillaSrcs <- hsSources context let srcs = vanillaSrcs `union` generatedSrcs - need $ srcs ++ haddocks + need $ srcs ++ (map snd haddocks) -- Build Haddock documentation -- TODO: Pass the correct way from Rules via Context. @@ -364,8 +364,8 @@ buildManPage = do copyFileUntracked (dir -/- "ghc.1") file -- | Find the Haddock files for the dependencies of the current library. -haddockDependencies :: Context -> Action [FilePath] +haddockDependencies :: Context -> Action [(Package, FilePath)] haddockDependencies context = do depNames <- interpretInContext context (getContextData depNames) - sequence [ pkgHaddockFile $ vanillaContext Stage1 depPkg + sequence [ (,) <$> pure depPkg <*> (pkgHaddockFile $ vanillaContext Stage1 depPkg) | Just depPkg <- map findPackageByName depNames, depPkg /= rts ] ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -43,9 +43,8 @@ haddockBuilderArgs = mconcat context <- getContext version <- expr $ pkgVersion pkg synopsis <- expr $ pkgSynopsis pkg - trans_deps <- expr $ contextDependencies context - pkgs <- expr $ mapM (pkgIdentifier . C.package) $ trans_deps haddocks <- expr $ haddockDependencies context + haddocks_with_versions <- expr $ sequence $ [(,h) <$> pkgIdentifier p | (p, h) <- haddocks] hVersion <- expr $ pkgVersion haddock statsDir <- expr $ haddockStatsFilesDir baseUrlTemplate <- expr (docsBaseUrl <$> userSetting defaultDocArgs) @@ -69,7 +68,7 @@ haddockBuilderArgs = mconcat , map ("--hide=" ++) <$> getContextData otherModules , pure [ "--read-interface=../" ++ p ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," - ++ haddock | (p, haddock) <- zip pkgs haddocks ] + ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] , getInputs , arg "+RTS" ===================================== m4/fp_setup_windows_toolchain.m4 ===================================== @@ -82,7 +82,11 @@ AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ CC="${mingwbin}clang.exe" CXX="${mingwbin}clang++.exe" - cflags="--rtlib=compiler-rt" + + # Signal that we are linking against UCRT with the _UCRT macro. This is + # necessary to ensure correct behavior when MinGW-w64 headers are in the + # header include path (#22159). + cflags="--rtlib=compiler-rt -D_UCRT" CFLAGS="$cflags" CONF_CC_OPTS_STAGE1="$cflags" CONF_CC_OPTS_STAGE2="$cflags" ===================================== rts/PrimOps.cmm ===================================== @@ -2226,7 +2226,7 @@ loop: if (q == stg_END_TSO_QUEUE_closure) { /* No takes, the IOPort is now full. */ if (info == stg_MVAR_CLEAN_info) { - ccall dirty_MVAR(BaseReg "ptr", ioport "ptr"); + ccall dirty_MVAR(BaseReg "ptr", ioport "ptr", StgMVar_value(ioport) "ptr"); } StgMVar_value(ioport) = val; ===================================== testsuite/tests/deriving/should_compile/T22167.hs ===================================== @@ -0,0 +1,24 @@ +module T22167 where + +import GHC.Generics (Generic1) + +data T1 f a = MkT1 (f a) + deriving (Functor, Foldable, Traversable) + +data T2 f a where + MkT2 :: f a -> T2 f a + deriving (Functor, Foldable, Traversable) + +-- A slightly more complicated example from the `syntactic` library +data (sym1 :+: sym2) sig + where + InjL :: sym1 a -> (sym1 :+: sym2) a + InjR :: sym2 a -> (sym1 :+: sym2) a + deriving (Functor, Foldable, Traversable) + +-- Test Generic1 instances with inferred Functor constraints +data G1 f g a = MkG1 (f (g a)) deriving Generic1 + +data G2 f g a where + MkG2 :: f (g a) -> G2 f g a + deriving Generic1 ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -139,3 +139,4 @@ test('T20387', normal, compile, ['']) test('T20501', normal, compile, ['']) test('T20719', normal, compile, ['']) test('T20994', normal, compile, ['']) +test('T22167', normal, compile, ['']) ===================================== testsuite/tests/ffi/should_run/Makefile ===================================== @@ -49,3 +49,10 @@ T15933: '$(TEST_HC)' $(TEST_HC_OPTS) -c T15933.hs '$(TEST_HC)' $(TEST_HC_OPTS) T15933_c.o T15933.o -o T15933 ./T15933 + +.PHONY: T22159 +T22159: + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) -c T22159.hs + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) -c T22159_c.c + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) T22159.o T22159_c.o -o T22159 + ./T22159 ===================================== testsuite/tests/ffi/should_run/T22159.hs ===================================== @@ -0,0 +1,23 @@ +{-# LANGUAGE CPP #-} +module Main (main) where + +#if defined(i386_HOST_ARCH) +# define WINDOWS_CCONV stdcall +#elif defined(x86_64_HOST_ARCH) +# define WINDOWS_CCONV ccall +#else +# error Unknown mingw32 arch +#endif + +import Foreign.C.String (peekCWString) +import Foreign.C.Types (CWchar) +import Foreign.Marshal.Alloc (allocaBytes) +import Foreign.Ptr (Ptr) + +foreign import WINDOWS_CCONV "hello" c_hello :: Ptr CWchar -> IO () + +main :: IO () +main = allocaBytes 12 $ \buf -> do + c_hello buf + str <- peekCWString buf + putStrLn str ===================================== testsuite/tests/ffi/should_run/T22159.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/ffi/should_run/T22159_c.c ===================================== @@ -0,0 +1,6 @@ +#include +#include + +void hello(wchar_t *buf) { + swprintf_s(buf, 12, L"hello"); +} ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -224,3 +224,8 @@ test('IncallAffinity', ['IncallAffinity_c.c -no-hs-main']) test('T19237', normal, compile_and_run, ['T19237_c.c']) + +test('T22159', + [unless(opsys('mingw32'), skip), + extra_files(['T22159_c.c'])], + makefile_test, ['T22159']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3e4a38c8b88a93cc740b7432902e46586e10eab1...f3f737a70763a3264dbc0888dca384d147e6b31f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3e4a38c8b88a93cc740b7432902e46586e10eab1...f3f737a70763a3264dbc0888dca384d147e6b31f You're receiving 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 Oct 14 21:10:41 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Oct 2022 17:10:41 -0400 Subject: [Git][ghc/ghc][wip/backports-9.4] 7 commits: Simplify: Take care with eta reduction in recursive RHSs (#21652) Message-ID: <6349d05121ee4_8b90f517701574df@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.4 at Glasgow Haskell Compiler / GHC Commits: c0b5736c by Sebastian Graf at 2022-10-14T17:10:27-04:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 (cherry picked from commit 49fb2f9b16ca987648d2ac57eecf1892d49852ec) - - - - - ccdaa83c by Ben Gamari at 2022-10-14T17:10:27-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. (cherry picked from commit cd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3) - - - - - 671491cc by Matthew Pickering at 2022-10-14T17:10:27-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 (cherry picked from commit 2361b3bc08811b0d2fb8f8fc5635b7c2fec157c6) - - - - - 6bf992e6 by Ryan Scott at 2022-10-14T17:10:27-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. (cherry picked from commit 8a666ad2a89a8ad2aa24a6406b88f516afaec671) - - - - - 3eace272 by Ryan Scott at 2022-10-14T17:10:27-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. (cherry picked from commit 3a815f30bcba5672085e823aeef90863253b0b1a) - - - - - 9ae4865b by Cheng Shao at 2022-10-14T17:10:27-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh (cherry picked from commit ee471dfb8a4a4bb5131a5baa61d1d0d22c933d5f) - - - - - 6af677a9 by Matthew Pickering at 2022-10-14T17:10:27-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 (cherry picked from commit 7f0decd5063a853fc8f38a8944b2c91995cd5e48) - - - - - 30 changed files: - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Utils/Binary.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Settings/Builders/Haddock.hs - m4/fp_setup_windows_toolchain.m4 - rts/PrimOps.cmm - testsuite/tests/arityanal/should_compile/Arity03.stderr - + testsuite/tests/arityanal/should_run/Makefile - + testsuite/tests/arityanal/should_run/T21652.hs - + testsuite/tests/arityanal/should_run/T21652.stdout - + testsuite/tests/arityanal/should_run/all.T - testsuite/tests/deSugar/should_compile/T19969.stderr - + testsuite/tests/deriving/should_compile/T22167.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/ffi/should_run/Makefile - + testsuite/tests/ffi/should_run/T22159.hs - + testsuite/tests/ffi/should_run/T22159.stdout - + testsuite/tests/ffi/should_run/T22159_c.c - testsuite/tests/ffi/should_run/all.T Changes: ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -67,7 +67,7 @@ import GHC.Utils.Logger import Data.Maybe (fromJust) import Control.Monad (ap) import Data.Char (isDigit) -import Data.List (sortBy, groupBy, intercalate) +import Data.List (sortBy, groupBy, intercalate, isPrefixOf) import Data.Ord (comparing) import qualified Data.List.NonEmpty as NE @@ -550,6 +550,12 @@ generateExternDecls = do modifyEnv $ \env -> env { envAliases = emptyUniqSet } return (concat defss, []) +-- | Is a variable one of the special @$llvm@ globals? +isBuiltinLlvmVar :: LlvmVar -> Bool +isBuiltinLlvmVar (LMGlobalVar lbl _ _ _ _ _) = + "$llvm" `isPrefixOf` unpackFS lbl +isBuiltinLlvmVar _ = False + -- | Here we take a global variable definition, rename it with a -- @$def@ suffix, and generate the appropriate alias. aliasify :: LMGlobal -> LlvmM [LMGlobal] @@ -557,8 +563,9 @@ aliasify :: LMGlobal -> LlvmM [LMGlobal] -- Here we obtain the indirectee's precise type and introduce -- fresh aliases to both the precise typed label (lbl$def) and the i8* -- typed (regular) label of it with the matching new names. -aliasify (LMGlobal (LMGlobalVar lbl ty at LMAlias{} link sect align Alias) - (Just orig)) = do +aliasify (LMGlobal var@(LMGlobalVar lbl ty at LMAlias{} link sect align Alias) + (Just orig)) + | not $ isBuiltinLlvmVar var = do let defLbl = llvmDefLabel lbl LMStaticPointer (LMGlobalVar origLbl _ oLnk Nothing Nothing Alias) = orig defOrigLbl = llvmDefLabel origLbl @@ -571,7 +578,8 @@ aliasify (LMGlobal (LMGlobalVar lbl ty at LMAlias{} link sect align Alias) pure [ LMGlobal (LMGlobalVar defLbl ty link sect align Alias) (Just defOrig) , LMGlobal (LMGlobalVar lbl i8Ptr link sect align Alias) (Just orig') ] -aliasify (LMGlobal var val) = do +aliasify (LMGlobal var val) + | not $ isBuiltinLlvmVar var = do let LMGlobalVar lbl ty link sect align const = var defLbl = llvmDefLabel lbl @@ -589,6 +597,7 @@ aliasify (LMGlobal var val) = do return [ LMGlobal defVar val , LMGlobal aliasVar (Just aliasVal) ] +aliasify global = pure [global] -- Note [Llvm Forward References] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -647,3 +656,6 @@ aliasify (LMGlobal var val) = do -- away with casting the alias to the desired type in @getSymbolPtr@ -- and instead just emit a reference to the definition symbol directly. -- This is the @Just@ case in @getSymbolPtr at . +-- +-- Note that we must take care not to turn LLVM's builtin variables into +-- aliases (e.g. $llvm.global_ctors) since this confuses LLVM. ===================================== compiler/GHC/Core/Opt/Arity.hs ===================================== @@ -505,6 +505,67 @@ Suppose f = \xy. x+y Then f :: \??.T f v :: \?.T f :: T + + + +Note [Eta reduction in recursive RHSs] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the following recursive function: + f = \x. ....g (\y. f y).... +The recursive call of f in its own RHS seems like a fine opportunity for +eta-reduction because f has arity 1. And often it is! + +Alas, that is unsound in general if the eta-reduction happens in a tail context. +Making the arity visible in the RHS allows us to eta-reduce + f = \x -> f x +to + f = f +which means we optimise terminating programs like (f `seq` ()) into +non-terminating ones. Nor is this problem just for tail calls. Consider + f = id (\x -> f x) +where we have (for some reason) not yet inlined `id`. We must not eta-reduce to + f = id f +because that will then simplify to `f = f` as before. + +An immediate idea might be to look at whether the called function is a local +loopbreaker and refrain from eta-expanding. But that doesn't work for mutually +recursive function like in #21652: + f = g + g* x = f x +Here, g* is the loopbreaker but f isn't. + +What can we do? + +Fix 1: Zap `idArity` when analysing recursive RHSs and re-attach the info when + entering the let body. + Has the disadvantage that other transformations which make use of arity + (such as dropping of `seq`s when arity > 0) will no longer work in the RHS. + Plus it requires non-trivial refactorings to both the simple optimiser (in + the way `subst_opt_bndr` is used) as well as the Simplifier (in the way + `simplRecBndrs` and `simplRecJoinBndrs` is used), modifying the SimplEnv's + substitution twice in the process. A very complicated stop-gap. + +Fix 2: Pass the set of enclosing recursive binders to `tryEtaReduce`; these are + the ones we should not eta-reduce. All call-site must maintain this set. + Example: + rec { f1 = ....rec { g = ... (\x. g x)...(\y. f2 y)... }... + ; f2 = ...f1... } + when eta-reducing those inner lambdas, we need to know that we are in the + rec group for {f1, f2, g}. + This is very much like the solution in Note [Speculative evaluation] in + GHC.CoreToStg.Prep. + It is a bit tiresome to maintain this info, because it means another field + in SimplEnv and SimpleOptEnv. + +We implement Fix (2) because of it isn't as complicated to maintain as (1). +Plus, it is the correct fix to begin with. After all, the arity is correct, +but doing the transformation isn't. The moving parts are: + * A field `scRecIds` in `SimplEnv` tracks the enclosing recursive binders + * We extend the `scRecIds` set in `GHC.Core.Opt.Simplify.simplRecBind` + * We consult the set in `is_eta_reduction_sound` in `tryEtaReduce` +The situation is very similar to Note [Speculative evaluation] which has the +same fix. + -} ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -64,6 +64,7 @@ import GHC.Builtin.Names( runRWKey ) import GHC.Data.Maybe ( isNothing, orElse ) import GHC.Data.FastString import GHC.Unit.Module ( moduleName, pprModuleName ) +import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain @@ -256,9 +257,11 @@ simplRecBind :: SimplEnv -> BindContext -> [(InId, InExpr)] -> SimplM (SimplFloats, SimplEnv) simplRecBind env0 bind_cxt pairs0 - = do { (env_with_info, triples) <- mapAccumLM add_rules env0 pairs0 - ; (rec_floats, env1) <- go env_with_info triples - ; return (mkRecFloats rec_floats, env1) } + = do { (env1, triples) <- mapAccumLM add_rules env0 pairs0 + ; let new_bndrs = map sndOf3 triples + ; (rec_floats, env2) <- enterRecGroupRHSs env1 new_bndrs $ \env -> + go env triples + ; return (mkRecFloats rec_floats, env2) } where add_rules :: SimplEnv -> (InBndr,InExpr) -> SimplM (SimplEnv, (InBndr, OutBndr, InExpr)) -- Add the (substituted) rules to the binder ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -17,7 +17,7 @@ module GHC.Core.Opt.Simplify.Env ( zapSubstEnv, setSubstEnv, bumpCaseDepth, getInScope, setInScopeFromE, setInScopeFromF, setInScopeSet, modifyInScope, addNewInScopeIds, - getSimplRules, + getSimplRules, enterRecGroupRHSs, -- * Substitution results SimplSR(..), mkContEx, substId, lookupRecBndr, refineFromInScope, @@ -55,6 +55,7 @@ import GHC.Types.Var import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Data.OrdList +import GHC.Data.Graph.UnVar import GHC.Types.Id as Id import GHC.Core.Make ( mkWildValBinder ) import GHC.Driver.Session ( DynFlags ) @@ -96,6 +97,10 @@ data SimplEnv , seCvSubst :: CvSubstEnv -- InCoVar |--> OutCoercion , seIdSubst :: SimplIdSubst -- InId |--> OutExpr + -- | Fast OutVarSet tracking which recursive RHSs we are analysing. + -- See Note [Eta reduction in recursive RHSs] in GHC.Core.Opt.Arity. + , seRecIds :: !UnVarSet + ----------- Dynamic part of the environment ----------- -- Dynamic in the sense of describing the setup where -- the expression finally ends up @@ -286,6 +291,7 @@ mkSimplEnv mode , seTvSubst = emptyVarEnv , seCvSubst = emptyVarEnv , seIdSubst = emptyVarEnv + , seRecIds = emptyUnVarSet , seCaseDepth = 0 } -- The top level "enclosing CC" is "SUBSUMED". @@ -391,6 +397,13 @@ modifyInScope :: SimplEnv -> CoreBndr -> SimplEnv modifyInScope env@(SimplEnv {seInScope = in_scope}) v = env {seInScope = extendInScopeSet in_scope v} +enterRecGroupRHSs :: SimplEnv -> [OutBndr] -> (SimplEnv -> SimplM (r, SimplEnv)) + -> SimplM (r, SimplEnv) +enterRecGroupRHSs env bndrs k = do + --pprTraceM "enterRecGroupRHSs" (ppr bndrs) + (r, env'') <- k env{seRecIds = extendUnVarSetList bndrs (seRecIds env)} + return (r, env''{seRecIds = seRecIds env}) + {- Note [Setting the right in-scope set] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -886,31 +899,18 @@ seqIds (id:ids) = seqId id `seq` seqIds ids Note [Arity robustness] ~~~~~~~~~~~~~~~~~~~~~~~ We *do* transfer the arity from the in_id of a let binding to the -out_id. This is important, so that the arity of an Id is visible in -its own RHS. For example: - f = \x. ....g (\y. f y).... -We can eta-reduce the arg to g, because f is a value. But that -needs to be visible. - -This interacts with the 'state hack' too: - f :: Bool -> IO Int - f = \x. case x of - True -> f y - False -> \s -> ... -Can we eta-expand f? Only if we see that f has arity 1, and then we -take advantage of the 'state hack' on the result of -(f y) :: State# -> (State#, Int) to expand the arity one more. - -There is a disadvantage though. Making the arity visible in the RHS -allows us to eta-reduce - f = \x -> f x -to - f = f -which technically is not sound. This is very much a corner case, so -I'm not worried about it. Another idea is to ensure that f's arity -never decreases; its arity started as 1, and we should never eta-reduce -below that. - +out_id so that its arity is visible in its RHS. Examples: + + * f = \x y. let g = \p q. f (p+q) in Just (...g..g...) + Here we want to give `g` arity 3 and eta-expand. `findRhsArity` will have a + hard time figuring that out when `f` only has arity 0 in its own RHS. + * f = \x y. ....(f `seq` blah).... + We want to drop the seq. + * f = \x. g (\y. f y) + You'd think we could eta-reduce `\y. f y` to `f` here. And indeed, that is true. + Unfortunately, it is not sound in general to eta-reduce in f's RHS. + Example: `f = \x. f x`. See Note [Eta reduction in recursive RHSs] for how + we prevent that. Note [Robust OccInfo] ~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1610,6 +1610,7 @@ mkLam env bndrs body cont ; mkLam' dflags bndrs body } where mode = getMode env + rec_ids = seRecIds env mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr mkLam' dflags bndrs body@(Lam {}) @@ -1633,7 +1634,7 @@ mkLam env bndrs body cont mkLam' dflags bndrs body | gopt Opt_DoEtaReduction dflags - , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce bndrs body + , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce rec_ids bndrs body = do { tick (EtaReduction (head bndrs)) ; return etad_lam } ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -52,6 +52,7 @@ import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc import GHC.Data.Maybe ( orElse ) +import GHC.Data.Graph.UnVar import Data.List (mapAccumL) import qualified Data.ByteString as BS @@ -193,6 +194,10 @@ data SimpleOptEnv , soe_subst :: Subst -- ^ Deals with cloning; includes the InScopeSet + + , soe_rec_ids :: !UnVarSet + -- ^ Fast OutVarSet tracking which recursive RHSs we are analysing. + -- See Note [Eta reduction in recursive RHSs] } instance Outputable SimpleOptEnv where @@ -205,6 +210,7 @@ emptyEnv :: SimpleOpts -> SimpleOptEnv emptyEnv opts = SOE { soe_inl = emptyVarEnv , soe_subst = emptySubst + , soe_rec_ids = emptyUnVarSet , soe_co_opt_opts = so_co_opts opts , soe_uf_opts = so_uf_opts opts } @@ -219,6 +225,13 @@ soeSetInScope (SOE { soe_subst = subst1 }) env2@(SOE { soe_subst = subst2 }) = env2 { soe_subst = setInScope subst2 (substInScope subst1) } +enterRecGroupRHSs :: SimpleOptEnv -> [OutBndr] -> (SimpleOptEnv -> (SimpleOptEnv, r)) + -> (SimpleOptEnv, r) +enterRecGroupRHSs env bndrs k + = (env'{soe_rec_ids = soe_rec_ids env}, r) + where + (env', r) = k env{soe_rec_ids = extendUnVarSetList bndrs (soe_rec_ids env)} + --------------- simple_opt_clo :: SimpleOptEnv -> SimpleClo -> OutExpr simple_opt_clo env (e_env, e) @@ -228,6 +241,7 @@ simple_opt_expr :: HasCallStack => SimpleOptEnv -> InExpr -> OutExpr simple_opt_expr env expr = go expr where + rec_ids = soe_rec_ids env subst = soe_subst env in_scope = substInScope subst in_scope_env = (in_scope, simpleUnfoldingFun) @@ -290,13 +304,16 @@ simple_opt_expr env expr ---------------------- -- go_lam tries eta reduction + -- It is quite important that it does so. I tried removing this code and + -- got a lot of regressions, e.g., +11% ghc/alloc in T18223 and many + -- run/alloc increases. Presumably RULEs are affected. go_lam env bs' (Lam b e) = go_lam env' (b':bs') e where (env', b') = subst_opt_bndr env b go_lam env bs' e - | Just etad_e <- tryEtaReduce bs e' = etad_e - | otherwise = mkLams bs e' + | Just etad_e <- tryEtaReduce rec_ids bs e' = etad_e + | otherwise = mkLams bs e' where bs = reverse bs' e' = simple_opt_expr env e @@ -390,12 +407,13 @@ simple_opt_bind env (NonRec b r) top_level (env', mb_pr) = simple_bind_pair env b' Nothing (env,r') top_level simple_opt_bind env (Rec prs) top_level - = (env'', res_bind) + = (env2, res_bind) where res_bind = Just (Rec (reverse rev_prs')) prs' = joinPointBindings_maybe prs `orElse` prs - (env', bndrs') = subst_opt_bndrs env (map fst prs') - (env'', rev_prs') = foldl' do_pr (env', []) (prs' `zip` bndrs') + (env1, bndrs') = subst_opt_bndrs env (map fst prs') + (env2, rev_prs') = enterRecGroupRHSs env1 bndrs' $ \env -> + foldl' do_pr (env, []) (prs' `zip` bndrs') do_pr (env, prs) ((b,r), b') = (env', case mb_pr of Just pr -> pr : prs ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -2429,8 +2429,8 @@ need to address that here. -- When updating this function, make sure to update -- CorePrep.tryEtaReducePrep as well! -tryEtaReduce :: [Var] -> CoreExpr -> Maybe CoreExpr -tryEtaReduce bndrs body +tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> Maybe CoreExpr +tryEtaReduce rec_ids bndrs body = go (reverse bndrs) body (mkRepReflCo (exprType body)) where incoming_arity = count isId bndrs @@ -2469,14 +2469,15 @@ tryEtaReduce bndrs body ok_fun _fun = False --------------- - ok_fun_id fun = -- There are arguments to reduce... - fun_arity fun >= incoming_arity && - -- ... and the function can be eta reduced to arity 0 - canEtaReduceToArity fun 0 0 + ok_fun_id fun = + -- Don't eta-reduce in fun in its own recursive RHSs + not (fun `elemUnVarSet` rec_ids) && -- criterion (R) + -- There are arguments to reduce... + fun_arity fun >= incoming_arity && + -- ... and the function can be eta reduced to arity 0 + canEtaReduceToArity fun 0 0 --------------- fun_arity fun -- See Note [Arity care] - | isLocalId fun - , isStrongLoopBreaker (idOccInfo fun) = 0 | arity > 0 = arity | isEvaldUnfolding (idUnfolding fun) = 1 -- See Note [Eta reduction of an eval'd function] ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -781,5 +781,5 @@ toHieName name | isKnownKeyName name = KnownKeyName (nameUnique name) | isExternalName name = ExternalName (nameModule name) (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) + (removeBufSpan $ nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (removeBufSpan $ nameSrcSpan name) ===================================== compiler/GHC/Tc/Deriv/Functor.hs ===================================== @@ -538,8 +538,36 @@ functorLikeTraverse var (FT { ft_triv = caseTrivial, ft_var = caseVar go _ _ = (caseTrivial,False) --- Return all syntactic subterms of ty that contain var somewhere --- These are the things that should appear in instance constraints +-- | Return all syntactic subterms of a 'Type' that are applied to the 'TyVar' +-- argument. This determines what constraints should be inferred for derived +-- 'Functor', 'Foldable', and 'Traversable' instances in "GHC.Tc.Deriv.Infer". +-- For instance, if we have: +-- +-- @ +-- data Foo a = MkFoo Int a (Maybe a) (Either Int (Maybe a)) +-- @ +-- +-- Then the following would hold: +-- +-- * @'deepSubtypesContaining' a Int@ would return @[]@, since @Int@ does not +-- contain the type variable @a@ at all. +-- +-- * @'deepSubtypesContaining' a a@ would return @[]@. Although the type @a@ +-- contains the type variable @a@, it is not /applied/ to @a@, which is the +-- criterion that 'deepSubtypesContaining' checks for. +-- +-- * @'deepSubtypesContaining' a (Maybe a)@ would return @[Maybe]@, as @Maybe@ +-- is applied to @a at . +-- +-- * @'deepSubtypesContaining' a (Either Int (Maybe a))@ would return +-- @[Either Int, Maybe]@. Both of these types are applied to @a@ through +-- composition. +-- +-- As used in "GHC.Tc.Deriv.Infer", the 'Type' argument will always come from +-- 'derivDataConInstArgTys', so it is important that the 'TyVar' comes from +-- 'dataConUnivTyVars' to match. Make sure /not/ to take the 'TyVar' from +-- 'tyConTyVars', as these differ from the 'dataConUnivTyVars' when the data +-- type is a GADT. (See #22167 for what goes wrong if 'tyConTyVars' is used.) deepSubtypesContaining :: TyVar -> Type -> [TcType] deepSubtypesContaining tv = functorLikeTraverse tv ===================================== compiler/GHC/Tc/Deriv/Generics.hs ===================================== @@ -91,10 +91,25 @@ gen_Generic_binds gk loc dit = do ************************************************************************ -} +-- | Called by 'GHC.Tc.Deriv.Infer.inferConstraints'; generates a list of +-- types, each of which must be a 'Functor' in order for the 'Generic1' +-- instance to work. For instance, if we have: +-- +-- @ +-- data Foo a = MkFoo Int a (Maybe a) (Either Int (Maybe a)) +-- @ +-- +-- Then @'get_gen1_constrained_tys' a (f (g a))@ would return @[Either Int]@, +-- as a derived 'Generic1' instance would need to call 'fmap' at that type. +-- Invoking @'get_gen1_constrained_tys' a@ on any of the other fields would +-- return @[]@. +-- +-- 'get_gen1_constrained_tys' is very similar in spirit to +-- 'deepSubtypesContaining' in "GHC.Tc.Deriv.Functor". Just like with +-- 'deepSubtypesContaining', it is important that the 'TyVar' argument come +-- from 'dataConUnivTyVars'. (See #22167 for what goes wrong if 'tyConTyVars' +-- is used.) get_gen1_constrained_tys :: TyVar -> Type -> [Type] --- called by GHC.Tc.Deriv.Infer.inferConstraints; generates a list of --- types, each of which must be a Functor in order for the Generic1 instance to --- work. get_gen1_constrained_tys argVar = argTyFold argVar $ ArgTyAlg { ata_rec0 = const [] , ata_par1 = [], ata_rec1 = const [] ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -176,9 +176,10 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys -- Constraints arising from the arguments of each constructor con_arg_constraints - :: (CtOrigin -> TypeOrKind - -> Type - -> [(ThetaSpec, Maybe TCvSubst)]) + :: ([TyVar] -> CtOrigin + -> TypeOrKind + -> Type + -> [(ThetaSpec, Maybe TCvSubst)]) -> (ThetaSpec, [TyVar], [TcType], DerivInstTys) con_arg_constraints get_arg_constraints = let -- Constraints from the fields of each data constructor. @@ -193,7 +194,8 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys , not (isUnliftedType arg_ty) , let orig = DerivOriginDC data_con arg_n wildcard , preds_and_mbSubst - <- get_arg_constraints orig arg_t_or_k arg_ty + <- get_arg_constraints (dataConUnivTyVars data_con) + orig arg_t_or_k arg_ty ] -- Stupid constraints from DatatypeContexts. Note that we -- must gather these constraints from the data constructors, @@ -235,21 +237,39 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys is_functor_like = tcTypeKind inst_ty `tcEqKind` typeToTypeKind || is_generic1 - get_gen1_constraints :: Class -> CtOrigin -> TypeOrKind -> Type - -> [(ThetaSpec, Maybe TCvSubst)] - get_gen1_constraints functor_cls orig t_or_k ty + get_gen1_constraints :: + Class + -> [TyVar] -- The universally quantified type variables for the + -- data constructor + -> CtOrigin -> TypeOrKind -> Type + -> [(ThetaSpec, Maybe TCvSubst)] + get_gen1_constraints functor_cls dc_univs orig t_or_k ty = mk_functor_like_constraints orig t_or_k functor_cls $ - get_gen1_constrained_tys last_tv ty - - get_std_constrained_tys :: CtOrigin -> TypeOrKind -> Type - -> [(ThetaSpec, Maybe TCvSubst)] - get_std_constrained_tys orig t_or_k ty + get_gen1_constrained_tys last_dc_univ ty + where + -- If we are deriving an instance of 'Generic1' and have made + -- it this far, then there should be at least one universal type + -- variable, making this use of 'last' safe. + last_dc_univ = assert (not (null dc_univs)) $ + last dc_univs + + get_std_constrained_tys :: + [TyVar] -- The universally quantified type variables for the + -- data constructor + -> CtOrigin -> TypeOrKind -> Type + -> [(ThetaSpec, Maybe TCvSubst)] + get_std_constrained_tys dc_univs orig t_or_k ty | is_functor_like = mk_functor_like_constraints orig t_or_k main_cls $ - deepSubtypesContaining last_tv ty + deepSubtypesContaining last_dc_univ ty | otherwise = [( [mk_cls_pred orig t_or_k main_cls ty] , Nothing )] + where + -- If 'is_functor_like' holds, then there should be at least one + -- universal type variable, making this use of 'last' safe. + last_dc_univ = assert (not (null dc_univs)) $ + last dc_univs mk_functor_like_constraints :: CtOrigin -> TypeOrKind -> Class -> [Type] @@ -277,9 +297,6 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys , tcUnifyTy ki typeToTypeKind ) - rep_tc_tvs = tyConTyVars rep_tc - last_tv = last rep_tc_tvs - -- Extra Data constraints -- The Data class (only) requires that for -- instance (...) => Data (T t1 t2) @@ -318,7 +335,7 @@ inferConstraintsStock dit@(DerivInstTys { dit_cls_tys = cls_tys -- Generic1 needs Functor -- See Note [Getting base classes] | is_generic1 - -> assert (rep_tc_tvs `lengthExceeds` 0) $ + -> assert (tyConTyVars rep_tc `lengthExceeds` 0) $ -- Generic1 has a single kind variable assert (cls_tys `lengthIs` 1) $ do { functorClass <- lift $ tcLookupClass functorClassName ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -68,6 +68,7 @@ module GHC.Types.SrcLoc ( getBufPos, BufSpan(..), getBufSpan, + removeBufSpan, -- * Located Located, @@ -398,6 +399,10 @@ data UnhelpfulSpanReason | UnhelpfulOther !FastString deriving (Eq, Show) +removeBufSpan :: SrcSpan -> SrcSpan +removeBufSpan (RealSrcSpan s _) = RealSrcSpan s Strict.Nothing +removeBufSpan s = s + {- Note [Why Maybe BufPos] ~~~~~~~~~~~~~~~~~~~~~~~~~~ In SrcLoc we store (Maybe BufPos); in SrcSpan we store (Maybe BufSpan). ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -1306,19 +1306,6 @@ instance Binary RealSrcSpan where return (mkRealSrcSpan (mkRealSrcLoc f sl sc) (mkRealSrcLoc f el ec)) -instance Binary BufPos where - put_ bh (BufPos i) = put_ bh i - get bh = BufPos <$> get bh - -instance Binary BufSpan where - put_ bh (BufSpan start end) = do - put_ bh start - put_ bh end - get bh = do - start <- get bh - end <- get bh - return (BufSpan start end) - instance Binary UnhelpfulSpanReason where put_ bh r = case r of UnhelpfulNoLocationInfo -> putByte bh 0 @@ -1337,10 +1324,11 @@ instance Binary UnhelpfulSpanReason where _ -> UnhelpfulOther <$> get bh instance Binary SrcSpan where - put_ bh (RealSrcSpan ss sb) = do + put_ bh (RealSrcSpan ss _sb) = do putByte bh 0 + -- BufSpan doesn't ever get serialised because the positions depend + -- on build location. put_ bh ss - put_ bh sb put_ bh (UnhelpfulSpan s) = do putByte bh 1 @@ -1350,8 +1338,7 @@ instance Binary SrcSpan where h <- getByte bh case h of 0 -> do ss <- get bh - sb <- get bh - return (RealSrcSpan ss sb) + return (RealSrcSpan ss Strict.Nothing) _ -> do s <- get bh return (UnhelpfulSpan s) ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -249,7 +249,7 @@ buildPackageDocumentation = do vanillaSrcs <- hsSources context let srcs = vanillaSrcs `union` generatedSrcs - need $ srcs ++ haddocks + need $ srcs ++ (map snd haddocks) -- Build Haddock documentation -- TODO: Pass the correct way from Rules via Context. @@ -364,8 +364,8 @@ buildManPage = do copyFileUntracked (dir -/- "ghc.1") file -- | Find the Haddock files for the dependencies of the current library. -haddockDependencies :: Context -> Action [FilePath] +haddockDependencies :: Context -> Action [(Package, FilePath)] haddockDependencies context = do depNames <- interpretInContext context (getContextData depNames) - sequence [ pkgHaddockFile $ vanillaContext Stage1 depPkg + sequence [ (,) <$> pure depPkg <*> (pkgHaddockFile $ vanillaContext Stage1 depPkg) | Just depPkg <- map findPackageByName depNames, depPkg /= rts ] ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -43,9 +43,8 @@ haddockBuilderArgs = mconcat context <- getContext version <- expr $ pkgVersion pkg synopsis <- expr $ pkgSynopsis pkg - trans_deps <- expr $ contextDependencies context - pkgs <- expr $ mapM (pkgIdentifier . C.package) $ trans_deps haddocks <- expr $ haddockDependencies context + haddocks_with_versions <- expr $ sequence $ [(,h) <$> pkgIdentifier p | (p, h) <- haddocks] hVersion <- expr $ pkgVersion haddock statsDir <- expr $ haddockStatsFilesDir baseUrlTemplate <- expr (docsBaseUrl <$> userSetting defaultDocArgs) @@ -69,7 +68,7 @@ haddockBuilderArgs = mconcat , map ("--hide=" ++) <$> getContextData otherModules , pure [ "--read-interface=../" ++ p ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," - ++ haddock | (p, haddock) <- zip pkgs haddocks ] + ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] , getInputs , arg "+RTS" ===================================== m4/fp_setup_windows_toolchain.m4 ===================================== @@ -82,7 +82,11 @@ AC_DEFUN([FP_SETUP_WINDOWS_TOOLCHAIN],[ CC="${mingwbin}clang.exe" CXX="${mingwbin}clang++.exe" - cflags="--rtlib=compiler-rt" + + # Signal that we are linking against UCRT with the _UCRT macro. This is + # necessary to ensure correct behavior when MinGW-w64 headers are in the + # header include path (#22159). + cflags="--rtlib=compiler-rt -D_UCRT" CFLAGS="$cflags" CONF_CC_OPTS_STAGE1="$cflags" CONF_CC_OPTS_STAGE2="$cflags" ===================================== rts/PrimOps.cmm ===================================== @@ -2226,7 +2226,7 @@ loop: if (q == stg_END_TSO_QUEUE_closure) { /* No takes, the IOPort is now full. */ if (info == stg_MVAR_CLEAN_info) { - ccall dirty_MVAR(BaseReg "ptr", ioport "ptr"); + ccall dirty_MVAR(BaseReg "ptr", ioport "ptr", StgMVar_value(ioport) "ptr"); } StgMVar_value(ioport) = val; ===================================== testsuite/tests/arityanal/should_compile/Arity03.stderr ===================================== @@ -18,20 +18,15 @@ end Rec } fac [InlPrag=[2]] :: Int -> Int [GblId, Arity=1, - Str=<1P(1L)>, - Cpr=m1, + Str=<1!P(1L)>, + Cpr=1, 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= \ (w [Occ=Once1!] :: Int) -> case w of { GHC.Types.I# ww1 [Occ=Once1] -> case F3.$wfac ww1 of ww2 [Occ=Once1] { __DEFAULT -> GHC.Types.I# ww2 } }}] -fac = \ (w :: Int) -> case w of { GHC.Types.I# ww1 -> case F3.$wfac ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } } + Tmpl= \ (x [Occ=Once1!] :: Int) -> case x of { GHC.Types.I# ww [Occ=Once1] -> case F3.$wfac ww of ww1 [Occ=Once1] { __DEFAULT -> GHC.Types.I# ww1 } }}] +fac = \ (x :: Int) -> case x of { GHC.Types.I# ww -> case F3.$wfac ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} f3 :: Int -> Int -[GblId, - Arity=1, - Str=<1P(1L)>, - Cpr=m1, - 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) - Tmpl= fac}] +[GblId, Arity=1, Str=<1!P(1L)>, Cpr=1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] f3 = fac ===================================== testsuite/tests/arityanal/should_run/Makefile ===================================== @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk ===================================== testsuite/tests/arityanal/should_run/T21652.hs ===================================== @@ -0,0 +1,10 @@ +import GHC.Exts + +f, g :: a -> a +f = g +g x = f x +{-# NOINLINE f #-} +{-# NOINLINE g #-} + +-- should print done, not <> +main = lazy g `seq` putStrLn "done" ===================================== testsuite/tests/arityanal/should_run/T21652.stdout ===================================== @@ -0,0 +1 @@ +done ===================================== testsuite/tests/arityanal/should_run/all.T ===================================== @@ -0,0 +1,2 @@ +# Regression tests +test('T21652', [ only_ways(['optasm']) ], compile_and_run, ['']) ===================================== testsuite/tests/deSugar/should_compile/T19969.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 12, types: 18, coercions: 0, joins: 0/0} + = {terms: 8, types: 14, coercions: 0, joins: 0/0} Rec { -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} @@ -10,7 +10,7 @@ f [Occ=LoopBreaker] :: [Int] -> [Int] f = \ (x :: [Int]) -> f x end Rec } --- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} g [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, @@ -19,10 +19,10 @@ g [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) - Tmpl= \ (x [Occ=Once1] :: [Int]) -> f x}] -g = \ (x :: [Int]) -> f x + Tmpl= f}] +g = f --- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} h [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, @@ -31,8 +31,8 @@ h [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) - Tmpl= \ (x [Occ=Once1] :: [Int]) -> f x}] -h = \ (x :: [Int]) -> f x + Tmpl= f}] +h = f ===================================== testsuite/tests/deriving/should_compile/T22167.hs ===================================== @@ -0,0 +1,24 @@ +module T22167 where + +import GHC.Generics (Generic1) + +data T1 f a = MkT1 (f a) + deriving (Functor, Foldable, Traversable) + +data T2 f a where + MkT2 :: f a -> T2 f a + deriving (Functor, Foldable, Traversable) + +-- A slightly more complicated example from the `syntactic` library +data (sym1 :+: sym2) sig + where + InjL :: sym1 a -> (sym1 :+: sym2) a + InjR :: sym2 a -> (sym1 :+: sym2) a + deriving (Functor, Foldable, Traversable) + +-- Test Generic1 instances with inferred Functor constraints +data G1 f g a = MkG1 (f (g a)) deriving Generic1 + +data G2 f g a where + MkG2 :: f (g a) -> G2 f g a + deriving Generic1 ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -139,3 +139,4 @@ test('T20387', normal, compile, ['']) test('T20501', normal, compile, ['']) test('T20719', normal, compile, ['']) test('T20994', normal, compile, ['']) +test('T22167', normal, compile, ['']) ===================================== testsuite/tests/ffi/should_run/Makefile ===================================== @@ -49,3 +49,10 @@ T15933: '$(TEST_HC)' $(TEST_HC_OPTS) -c T15933.hs '$(TEST_HC)' $(TEST_HC_OPTS) T15933_c.o T15933.o -o T15933 ./T15933 + +.PHONY: T22159 +T22159: + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) -c T22159.hs + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) -c T22159_c.c + C_INCLUDE_PATH=/mingw64/include '$(TEST_HC)' $(TEST_HC_OPTS) T22159.o T22159_c.o -o T22159 + ./T22159 ===================================== testsuite/tests/ffi/should_run/T22159.hs ===================================== @@ -0,0 +1,23 @@ +{-# LANGUAGE CPP #-} +module Main (main) where + +#if defined(i386_HOST_ARCH) +# define WINDOWS_CCONV stdcall +#elif defined(x86_64_HOST_ARCH) +# define WINDOWS_CCONV ccall +#else +# error Unknown mingw32 arch +#endif + +import Foreign.C.String (peekCWString) +import Foreign.C.Types (CWchar) +import Foreign.Marshal.Alloc (allocaBytes) +import Foreign.Ptr (Ptr) + +foreign import WINDOWS_CCONV "hello" c_hello :: Ptr CWchar -> IO () + +main :: IO () +main = allocaBytes 12 $ \buf -> do + c_hello buf + str <- peekCWString buf + putStrLn str ===================================== testsuite/tests/ffi/should_run/T22159.stdout ===================================== @@ -0,0 +1 @@ +hello ===================================== testsuite/tests/ffi/should_run/T22159_c.c ===================================== @@ -0,0 +1,6 @@ +#include +#include + +void hello(wchar_t *buf) { + swprintf_s(buf, 12, L"hello"); +} ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -224,3 +224,8 @@ test('IncallAffinity', ['IncallAffinity_c.c -no-hs-main']) test('T19237', normal, compile_and_run, ['T19237_c.c']) + +test('T22159', + [unless(opsys('mingw32'), skip), + extra_files(['T22159_c.c'])], + makefile_test, ['T22159']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f3f737a70763a3264dbc0888dca384d147e6b31f...6af677a99fb8a5992897928b6fbb4e68879467ec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f3f737a70763a3264dbc0888dca384d147e6b31f...6af677a99fb8a5992897928b6fbb4e68879467ec You're receiving 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 Oct 14 21:32:23 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Oct 2022 17:32:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/mark-trace-9.2 Message-ID: <6349d567b63b_8b90f514281578a5@gitlab.mail> Ben Gamari pushed new branch wip/gc/mark-trace-9.2 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/mark-trace-9.2 You're receiving 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 Oct 14 22:29:35 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 18:29:35 -0400 Subject: [Git][ghc/ghc][master] rts: Use pthread_setname_np correctly on Darwin Message-ID: <6349e2cfa09a4_8b90f5143c167278@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 1 changed file: - rts/posix/OSThreads.c Changes: ===================================== rts/posix/OSThreads.c ===================================== @@ -186,22 +186,48 @@ shutdownThread(void) pthread_exit(NULL); } -int -createOSThread (OSThreadId* pId, char *name STG_UNUSED, - OSThreadProc *startProc, void *param) +struct ThreadDesc { + OSThreadProc *startProc; + void *param; + char *name; +}; + +// N.B. Darwin's pthread_setname_np only allows the name of the +// calling thread to be set. Consequently we must use this +// trampoline. +static void * +start_thread (void *param) { - int result = pthread_create(pId, NULL, startProc, param); - if (!result) { - pthread_detach(*pId); + struct ThreadDesc desc = *(struct ThreadDesc *) param; + stgFree(param); + #if defined(HAVE_PTHREAD_SET_NAME_NP) - pthread_set_name_np(*pId, name); + pthread_set_name_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP) - pthread_setname_np(*pId, name); + pthread_setname_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) - pthread_setname_np(name); + pthread_setname_np(desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) - pthread_setname_np(*pId, "%s", name); + pthread_setname_np(pthread_self(), "%s", desc.name); #endif + + return desc.startProc(desc.param); +} + +int +createOSThread (OSThreadId* pId, char *name STG_UNUSED, + OSThreadProc *startProc, void *param) +{ + struct ThreadDesc *desc = stgMallocBytes(sizeof(struct ThreadDesc), "createOSThread"); + desc->startProc = startProc; + desc->param = param; + desc->name = name; + + int result = pthread_create(pId, NULL, start_thread, desc); + if (!result) { + pthread_detach(*pId); + } else { + stgFree(desc); } return result; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 You're receiving 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 Oct 14 22:29:52 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 14 Oct 2022 18:29:52 -0400 Subject: [Git][ghc/ghc][wip/T21623] Add isCovertGadtDataCon, fixing build Message-ID: <6349e2e02c348_8b90f5143c1674f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: 292f4f89 by Simon Peyton Jones at 2022-10-14T23:29:02+01:00 Add isCovertGadtDataCon, fixing build - - - - - 2 changed files: - compiler/GHC/Core/DataCon.hs - compiler/GHC/Tc/Errors/Ppr.hs Changes: ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -55,7 +55,7 @@ module GHC.Core.DataCon ( -- ** Predicates on DataCons isNullarySrcDataCon, isNullaryRepDataCon, isTupleDataCon, isBoxedTupleDataCon, isUnboxedTupleDataCon, - isUnboxedSumDataCon, + isUnboxedSumDataCon, isCovertGadtDataCon, isVanillaDataCon, isNewDataCon, isTypeDataCon, classDataCon, dataConCannotMatch, dataConUserTyVarsNeedWrapper, checkDataConTyVars, @@ -422,7 +422,7 @@ data DataCon -- syntax, provided its type looks like the above. -- The declaration format is held in the TyCon (algTcGadtSyntax) - -- Universally-quantified type vars [a,b,c] + -- dcUnivTyVars: Universally-quantified type vars [a,b,c] -- INVARIANT: length matches arity of the dcRepTyCon -- INVARIANT: result type of data con worker is exactly (T a b c) -- COROLLARY: The dcUnivTyVars are always in one-to-one correspondence with @@ -875,8 +875,7 @@ data StrictnessMark = MarkedStrict | NotMarkedStrict -- | An 'EqSpec' is a tyvar/type pair representing an equality made in -- rejigging a GADT constructor -data EqSpec = EqSpec TyVar - Type +data EqSpec = EqSpec TyVar Type -- | Make a non-dependent 'EqSpec' mkEqSpec :: TyVar -> Type -> EqSpec @@ -1711,6 +1710,53 @@ isNewDataCon dc = isNewTyCon (dataConTyCon dc) isTypeDataCon :: DataCon -> Bool isTypeDataCon dc = isTcClsNameSpace (nameNameSpace (getName dc)) +isCovertGadtDataCon :: DataCon -> Bool +-- See Note [isCovertGadtDataCon] +isCovertGadtDataCon (MkData { dcUnivTyVars = univ_tvs + , dcEqSpec = eq_spec + , dcRepTyCon = rep_tc }) + = not (null eq_spec) -- There are some constraints + && not (any is_visible_spec eq_spec) -- But none of them are visible + where + visible_univ_tvs :: [TyVar] -- Visible arguments in result type + visible_univ_tvs + = [ univ_tv | (univ_tv, tcb) <- univ_tvs `zip` tyConBinders rep_tc + , isVisibleTyConBinder tcb ] + + is_visible_spec :: EqSpec -> Bool + is_visible_spec (EqSpec univ_tv _) = univ_tv `elem` visible_univ_tvs + +{- Note [isCovertGadtDataCon] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(isCovertGadtDataCon K) returns True if K is a GADT data constructor, but +does not /look/ like it. Consider (#21447) + type T :: TYPE r -> Type + data T a where { MkT :: b -> T b } +Here MkT doesn't look GADT-like, but it is. If we make the kind applications +explicit we'd see: + data T a where { MkT :: b -> T @LiftedRep b } + +The test for covert-ness is bit tricky, because we want to see if + - dcEqSpec is non-empty + - none of the universal type variables that it constrains is + a required argument of the TyCon + +In the example above, the DataCon for MkT will have + dcUnivTyVars: [(r::RuntimeRep), (b :: TYPE r)] + dcEqSpec: [ (r, LiftedRep) ] +So `r` is constrained by dcEqSpec, but `b` is not, so the user-visible +declaration MkT :: b -> T b +looks entirely non-GADT-ish. + +But remember: +* The visibility or otherwise is a property of the /TyCon/ binders +* The dcUnivTyVars may or may not be the same as the TyCon binders +* So we have to zip them together. +* For a data family the TyCon in question is the /representation/ TyCon + hence dcRepTyCon +-} + + -- | Should this DataCon be allowed in a type even without -XDataKinds? -- Currently, only Lifted & Unlifted specialPromotedDc :: DataCon -> Bool ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1018,7 +1018,8 @@ instance Diagnostic TcRnMessage where ppr con <+> dcolon <+> ppr (dataConDisplayType True con)) IsGADT -> (text "A newtype must not be a GADT", - ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec (ppr $ dataConDisplayType show_linear_types con)) + ppr con <+> dcolon <+> pprWithExplicitKindsWhen sneaky_eq_spec + (ppr $ dataConDisplayType show_linear_types con)) HasConstructorContext -> (text "A newtype constructor must not have a context in its type", ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) @@ -1028,12 +1029,9 @@ instance Diagnostic TcRnMessage where HasStrictnessAnnotation -> (text "A newtype constructor must not have a strictness annotation", empty) - -- Is there an EqSpec involving an invisible binder? If so, print the - -- error message with explicit kinds. - invisible_binders = filter isInvisibleTyConBinder (tyConBinders $ dataConTyCon con) - sneaky_eq_spec - = any (\eq -> any (( == eqSpecTyVar eq) . binderVar) invisible_binders) - $ dataConEqSpec con + -- Is the data con a "covert" GADT? See Note [isCovertGadtDataCon] + -- in GHC.Core.DataCon + sneaky_eq_spec = isCovertGadtDataCon con diagnosticReason = \case TcRnUnknownMessage m View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/292f4f89f310cb1ff6723e0b7952c7f069abee41 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/292f4f89f310cb1ff6723e0b7952c7f069abee41 You're receiving 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 Oct 14 22:30:22 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Oct 2022 18:30:22 -0400 Subject: [Git][ghc/ghc][master] 2 commits: testsuite: Add test for #22282 Message-ID: <6349e2fea127e_8b90f5175c17427c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 5 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. ===================================== testsuite/tests/numeric/should_run/T22282.hs ===================================== @@ -0,0 +1,3 @@ +import T22282A + +main = print $ testF 217 161 ===================================== testsuite/tests/numeric/should_run/T22282.stdout ===================================== @@ -0,0 +1,2 @@ +217 + ===================================== testsuite/tests/numeric/should_run/T22282A.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE MagicHash #-} +module T22282A where + +import Data.Word +import GHC.Prim +import GHC.Word + +wtestF :: GHC.Prim.Word8# -> GHC.Prim.Word8# -> GHC.Prim.Word8# +wtestF a b = case word8ToWord# b of + 0## -> a + _ -> plusWord8# (timesWord8# (quotWord8# a b) b) (remWord8# a b) +{-# NOINLINE wtestF #-} + +testF :: Word8 -> Word8 -> Word8 +testF (W8# a) (W8# b) = W8# (wtestF a b) +{-# INLINE testF #-} + ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,3 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) +test('T22282', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ee0deb8054da2a597fc5624469b4c44fd769ada2...62a550010ed94e1969c96150f2781854a0802766 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ee0deb8054da2a597fc5624469b4c44fd769ada2...62a550010ed94e1969c96150f2781854a0802766 You're receiving 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 Oct 14 22:35:41 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 14 Oct 2022 18:35:41 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 5 commits: Minor refactoring: avoid unpacking ShortText too soon Message-ID: <6349e43d48c1f_8b90f517841751a2@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 7e236701 by Sylvain Henry at 2022-10-14T22:55:14+02:00 Minor refactoring: avoid unpacking ShortText too soon - - - - - 51a4181a by Sylvain Henry at 2022-10-14T23:00:35+02:00 Remove unused derived instances - - - - - 9454d0c9 by Sylvain Henry at 2022-10-14T23:17:31+02:00 Use Ident in ClosureInfo instead of FastString - - - - - 70a041f6 by Sylvain Henry at 2022-10-14T23:49:12+02:00 Add identFS helper - - - - - 01e0ca4f by Sylvain Henry at 2022-10-15T00:35:39+02:00 Fix liftToGlobal identsS wasn't correctly ported: it has to return all the Ident occurences, not only one. Fixed this and simplified liftToGlobal implementation. Used UniqFM instead of Map forn the global ident cache. - - - - - 13 changed files: - compiler/GHC/JS/Syntax.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/Closure.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/FFI.hs - compiler/GHC/StgToJS/Ids.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Monad.hs - compiler/GHC/StgToJS/Rts/Rts.hs - compiler/GHC/StgToJS/Types.hs Changes: ===================================== compiler/GHC/JS/Syntax.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE RankNTypes #-} @@ -57,6 +57,7 @@ module GHC.JS.Syntax , JOp(..) , JUOp(..) , Ident(..) + , identFS , JsLabel -- * pattern synonyms over JS operators , pattern New @@ -383,8 +384,9 @@ instance Show SaneDouble where -- | A newtype wrapper around 'FastString' for JS identifiers. newtype Ident = TxtI { itxt :: FastString } - deriving stock (Show, Typeable, Eq, Generic) + deriving stock (Show, Eq) deriving newtype (Uniquable) -instance Ord Ident where - compare (TxtI fs1) (TxtI fs2) = lexicalCompareFS fs1 fs2 +identFS :: Ident -> FastString +identFS = \case + TxtI fs -> fs ===================================== compiler/GHC/JS/Transform.hs ===================================== @@ -38,9 +38,7 @@ import Data.Bifunctor import GHC.Data.FastString import GHC.Utils.Monad.State.Strict -import GHC.Types.Unique.FM import GHC.Types.Unique.Map -import GHC.Types.Unique.DSet mapExprIdent :: (Ident -> JExpr) -> JExpr -> JExpr mapExprIdent f = fst (mapIdent f) @@ -91,51 +89,48 @@ mapIdent f = (map_expr, map_stat) ContinueStat{} -> s {-# INLINE identsS #-} -identsS :: JStat -> UniqDSet Ident +identsS :: JStat -> [Ident] identsS = \case - DeclStat i e -> unitUniqDSet i `unionUniqDSets` maybe emptyUniqDSet identsE e + DeclStat i e -> [i] ++ maybe [] identsE e ReturnStat e -> identsE e - IfStat e s1 s2 -> identsE e `unionUniqDSets` identsS s1 `unionUniqDSets` identsS s2 - WhileStat _ e s -> identsE e `unionUniqDSets` identsS s - ForInStat _ i e s -> unitUniqDSet i `unionUniqDSets` identsE e `unionUniqDSets` identsS s - SwitchStat e xs s -> identsE e `unionUniqDSets` foldl' unionUniqDSets emptyUniqDSet (map traverseCase xs) `unionUniqDSets` identsS s - where traverseCase (e,s) = identsE e `unionUniqDSets` identsS s - TryStat s1 i s2 s3 -> identsS s1 `unionUniqDSets` unitUniqDSet i `unionUniqDSets` identsS s2 `unionUniqDSets` identsS s3 - BlockStat xs -> foldl' unionUniqDSets emptyUniqDSet (map identsS xs) - ApplStat e es -> identsE e `unionUniqDSets` foldl' unionUniqDSets emptyUniqDSet (map identsE es) + IfStat e s1 s2 -> identsE e ++ identsS s1 ++ identsS s2 + WhileStat _ e s -> identsE e ++ identsS s + ForInStat _ i e s -> [i] ++ identsE e ++ identsS s + SwitchStat e xs s -> identsE e ++ concatMap traverseCase xs ++ identsS s + where traverseCase (e,s) = identsE e ++ identsS s + TryStat s1 i s2 s3 -> identsS s1 ++ [i] ++ identsS s2 ++ identsS s3 + BlockStat xs -> concatMap identsS xs + ApplStat e es -> identsE e ++ concatMap identsE es UOpStat _op e -> identsE e - AssignStat e1 e2 -> identsE e1 `unionUniqDSets` identsE e2 + AssignStat e1 e2 -> identsE e1 ++ identsE e2 UnsatBlock{} -> error "identsS: UnsatBlock" LabelStat _l s -> identsS s - BreakStat{} -> emptyUniqDSet - ContinueStat{} -> emptyUniqDSet + BreakStat{} -> [] + ContinueStat{} -> [] {-# INLINE identsE #-} -identsE :: JExpr -> UniqDSet Ident +identsE :: JExpr -> [Ident] identsE = \case ValExpr v -> identsV v SelExpr e _i -> identsE e -- do not rename properties - IdxExpr e1 e2 -> identsE e1 `unionUniqDSets` identsE e2 - InfixExpr _ e1 e2 -> identsE e1 `unionUniqDSets` identsE e2 + IdxExpr e1 e2 -> identsE e1 ++ identsE e2 + InfixExpr _ e1 e2 -> identsE e1 ++ identsE e2 UOpExpr _ e -> identsE e - IfExpr e1 e2 e3 -> identsE e1 `unionUniqDSets` identsE e2 `unionUniqDSets` identsE e3 - ApplExpr e es -> identsE e `unionUniqDSets` foldl' unionUniqDSets emptyUniqDSet (map identsE es) + IfExpr e1 e2 e3 -> identsE e1 ++ identsE e2 ++ identsE e3 + ApplExpr e es -> identsE e ++ concatMap identsE es UnsatExpr{} -> error "identsE: UnsatExpr" {-# INLINE identsV #-} -identsV :: JVal -> UniqDSet Ident +identsV :: JVal -> [Ident] identsV = \case - JVar i -> unitUniqDSet i - JList xs -> foldl' unionUniqDSets emptyUniqDSet (map identsE xs) - JDouble{} -> emptyUniqDSet - JInt{} -> emptyUniqDSet - JStr{} -> emptyUniqDSet - JRegEx{} -> emptyUniqDSet - -- nonDetEltsUniqMap doesn't introduce non-determinism because the Set ignores - -- the List's ordering in favour of lexical comparisons - -- foldl' (<>) Set.empty (map (identsE . snd) $ nonDetEltsUniqMap m) - JHash m -> foldUFM unionUniqDSets emptyUniqDSet (mapUFM snd . getUniqMap $ mapUniqMap identsE m) - JFunc args s -> mkUniqDSet args `unionUniqDSets` identsS s + JVar i -> [i] + JList xs -> concatMap identsE xs + JDouble{} -> [] + JInt{} -> [] + JStr{} -> [] + JRegEx{} -> [] + JHash m -> concatMap (identsE . snd) (nonDetEltsUniqMap m) + JFunc args s -> args ++ identsS s UnsatVal{} -> error "identsV: UnsatVal" ===================================== compiler/GHC/StgToJS/Apply.hs ===================================== @@ -482,7 +482,7 @@ genericStackApply cfg = closure info body -- info table for h$ap_gen info = ClosureInfo - { ciVar = "h$ap_gen" + { ciVar = TxtI "h$ap_gen" , ciRegs = CIRegs 0 [PtrV] -- closure to apply to , ciName = "h$ap_gen" , ciLayout = CILayoutVariable @@ -720,8 +720,8 @@ stackApply s fun_name nargs nvars = then closure info0 body0 else closure info body where - info = ClosureInfo fun_name (CIRegs 0 [PtrV]) fun_name (CILayoutUnknown nvars) CIStackFrame mempty - info0 = ClosureInfo fun_name (CIRegs 0 [PtrV]) fun_name (CILayoutFixed 0 []) CIStackFrame mempty + info = ClosureInfo (TxtI fun_name) (CIRegs 0 [PtrV]) fun_name (CILayoutUnknown nvars) CIStackFrame mempty + info0 = ClosureInfo (TxtI fun_name) (CIRegs 0 [PtrV]) fun_name (CILayoutFixed 0 []) CIStackFrame mempty body0 = adjSpN' 1 <> enter s r1 @@ -905,7 +905,7 @@ enter s ex = jVar \c -> updates :: StgToJSConfig -> JStat updates s = BlockStat [ closure - (ClosureInfo "h$upd_frame" (CIRegs 0 [PtrV]) "h$upd_frame" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + (ClosureInfo (TxtI "h$upd_frame") (CIRegs 0 [PtrV]) "h$upd_frame" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) $ jVar \updatee waiters ss si sir -> let unbox_closure = Closure { clEntry = var "h$unbox_e" @@ -952,7 +952,7 @@ updates s = BlockStat ] , closure - (ClosureInfo "h$upd_frame_lne" (CIRegs 0 [PtrV]) "h$upd_frame_lne" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + (ClosureInfo (TxtI "h$upd_frame_lne") (CIRegs 0 [PtrV]) "h$upd_frame_lne" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) $ jVar \updateePos -> [ updateePos |= stack .! (sp - 1) , (stack .! updateePos |= r1) @@ -991,7 +991,7 @@ selectors s = , returnS (sel r) ] , closure - (ClosureInfo entryName (CIRegs 0 [PtrV]) ("select " <> name) (CILayoutFixed 1 [PtrV]) CIThunk mempty) + (ClosureInfo (TxtI entryName) (CIRegs 0 [PtrV]) ("select " <> name) (CILayoutFixed 1 [PtrV]) CIThunk mempty) (jVar \tgt -> [ tgt |= closureField1 r1 , traceRts s (toJExpr ("selector entry: " <> name <> " for ") + (tgt .^ "alloc")) @@ -1002,7 +1002,7 @@ selectors s = (returnS (app "h$e" [sel tgt])) ]) , closure - (ClosureInfo frameName (CIRegs 0 [PtrV]) ("select " <> name <> " frame") (CILayoutFixed 0 []) CIStackFrame mempty) + (ClosureInfo (TxtI frameName) (CIRegs 0 [PtrV]) ("select " <> name <> " frame") (CILayoutFixed 0 []) CIStackFrame mempty) $ mconcat [ traceRts s (toJExpr ("selector frame: " <> name)) , postDecrS sp , returnS (app "h$e" [sel r1]) @@ -1054,8 +1054,9 @@ specPapIdents = listArray (0,numSpecPap) $ map (TxtI . mkFastString . ("h$pap_"+ pap :: StgToJSConfig -> Int -> JStat -pap s r = closure (ClosureInfo funcName CIRegsUnknown funcName (CILayoutUnknown (r+2)) CIPap mempty) body +pap s r = closure (ClosureInfo funcIdent CIRegsUnknown funcName (CILayoutUnknown (r+2)) CIPap mempty) body where + funcIdent = TxtI funcName funcName = mkFastString ("h$pap_" ++ show r) body = jVar \c d f extra -> @@ -1081,7 +1082,7 @@ pap s r = closure (ClosureInfo funcName CIRegsUnknown funcName (CILayoutUnknown -- Construct a generic PAP papGen :: StgToJSConfig -> JStat papGen cfg = - closure (ClosureInfo funcName CIRegsUnknown funcName CILayoutVariable CIPap mempty) + closure (ClosureInfo funcIdent CIRegsUnknown funcName CILayoutVariable CIPap mempty) (jVar \c f d pr or r -> [ c |= closureField1 r1 , d |= closureField2 r1 @@ -1102,6 +1103,7 @@ papGen cfg = where + funcIdent = TxtI funcName funcName = "h$pap_gen" loadOwnArgs d r = let prop n = d .^ ("d" <> mkFastString (show $ n+1)) ===================================== compiler/GHC/StgToJS/Closure.hs ===================================== @@ -49,7 +49,7 @@ closureInfoStat debug (ClosureInfo obj rs name layout ctype srefs) setObjInfoL :: Bool -- ^ debug: output symbol names - -> FastString -- ^ the object name + -> Ident -- ^ the object name -> CIRegs -- ^ things in registers -> CILayout -- ^ layout of the object -> ClosureType -- ^ closure type @@ -70,7 +70,7 @@ setObjInfoL debug obj rs layout t n a CILayoutFixed _ fs -> toTypeList fs setObjInfo :: Bool -- ^ debug: output all symbol names - -> FastString -- ^ the thing to modify + -> Ident -- ^ the thing to modify -> ClosureType -- ^ closure type -> FastString -- ^ object name, for printing -> [Int] -- ^ list of item types in the object, if known (free variables, datacon fields) @@ -80,7 +80,7 @@ setObjInfo :: Bool -- ^ debug: output all symbol names -> CIStatic -- ^ static refs -> JStat setObjInfo debug obj t name fields a size regs static - | debug = appS "h$setObjInfo" [ var obj + | debug = appS "h$setObjInfo" [ toJExpr obj , toJExpr t , toJExpr name , toJExpr fields @@ -89,7 +89,7 @@ setObjInfo debug obj t name fields a size regs static , toJExpr (regTag regs) , toJExpr static ] - | otherwise = appS "h$o" [ var obj + | otherwise = appS "h$o" [ toJExpr obj , toJExpr t , toJExpr a , toJExpr size @@ -105,9 +105,9 @@ setObjInfo debug obj t name fields a size regs static closure :: ClosureInfo -- ^ object being info'd see @ciVar@ in @ClosureInfo@ -> JStat -- ^ rhs -> JStat -closure ci body = (TxtI (ciVar ci) ||= jLam body) `mappend` closureInfoStat False ci +closure ci body = (ciVar ci ||= jLam body) `mappend` closureInfoStat False ci -conClosure :: FastString -> FastString -> CILayout -> Int -> JStat +conClosure :: Ident -> FastString -> CILayout -> Int -> JStat conClosure symbol name layout constr = closure (ClosureInfo symbol (CIRegs 0 [PtrV]) name layout (CICon constr) mempty) (returnS (stack .! sp)) ===================================== compiler/GHC/StgToJS/CodeGen.hs ===================================== @@ -296,9 +296,9 @@ genToplevelConEntry i rhs = case rhs of genSetConInfo :: HasDebugCallStack => Id -> DataCon -> LiveVars -> G JStat genSetConInfo i d l {- srt -} = do - ei@(TxtI eii) <- identForDataConEntryId i + ei <- identForDataConEntryId i sr <- genStaticRefs l - emitClosureInfo $ ClosureInfo eii + emitClosureInfo $ ClosureInfo ei (CIRegs 0 [PtrV]) (mkFastString $ renderWithContext defaultSDocContext (ppr d)) (fixedLayout $ map uTypeVt fields) @@ -332,8 +332,10 @@ genToplevelRhs i rhs = case rhs of eid@(TxtI eidt) <- identForEntryId i (TxtI idt) <- identForId i body <- genBody (initExprCtx i) i R2 args body - (lidents, lids) <- unzip <$> liftToGlobal (jsSaturate (Just "ghcjs_tmp_sat_") body) - let lidents' = map (\(TxtI t) -> t) lidents + global_occs <- globalOccs (jsSaturate (Just "ghcjs_tmp_sat_") body) + let lidents = map global_ident global_occs + let lids = map global_id global_occs + let lidents' = map identFS lidents CIStaticRefs sr0 <- genStaticRefsRhs rhs let sri = filter (`notElem` lidents') sr0 sr = CIStaticRefs sri @@ -352,7 +354,7 @@ genToplevelRhs i rhs = case rhs of if et == CIThunk then enterCostCentreThunk else enterCostCentreFun cc - emitClosureInfo (ClosureInfo eidt + emitClosureInfo (ClosureInfo eid regs idt (fixedLayout $ map (uTypeVt . idType) lids) ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -238,11 +238,11 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = | otherwise = mempty lvs <- popLneFrame True payloadSize ctx body <- genBody ctx i R1 args body - ei@(TxtI eii) <- identForEntryId i + ei@(TxtI eii) <- identForEntryId i sr <- genStaticRefsRhs rhs let f = JFunc [] (bh <> lvs <> body) emitClosureInfo $ - ClosureInfo eii + ClosureInfo ei (CIRegs 0 $ concatMap idVt args) (eii <> ", " <> mkFastString (renderWithContext defaultSDocContext (ppr i))) (fixedLayout . reverse $ @@ -277,7 +277,7 @@ genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body) = res then enterCostCentreThunk else enterCostCentreFun cc sr <- genStaticRefsRhs rhs - emitClosureInfo $ ClosureInfo eii + emitClosureInfo $ ClosureInfo ei (CIRegs 0 $ PtrV : concatMap idVt args) (eii <> ", " <> mkFastString (renderWithContext defaultSDocContext (ppr i))) (fixedLayout $ map (uTypeVt . idType) live) @@ -631,7 +631,7 @@ genRet ctx e at as l = freshIdent >>= f sr <- genStaticRefs l -- srt prof <- profiling emitClosureInfo $ - ClosureInfo ri + ClosureInfo r (CIRegs 0 altRegs) ri (fixedLayout . reverse $ ===================================== compiler/GHC/StgToJS/FFI.hs ===================================== @@ -28,6 +28,7 @@ import GHC.StgToJS.Ids import GHC.Types.RepType import GHC.Types.ForeignCall import GHC.Types.Unique.Map +import GHC.Types.Unique.FM import GHC.Stg.Syntax @@ -45,7 +46,6 @@ import Data.Char import Data.Monoid import Data.Maybe import qualified Data.List as L -import qualified Data.Map as M import Control.Monad import Control.Applicative import qualified Text.ParserCombinators.ReadP as P @@ -147,7 +147,7 @@ parseFFIPattern' callback javascriptCc pat t ret args Right expr | not async && length tgt < 2 -> do (statPre, ap) <- argPlaceholders javascriptCc args let rp = resultPlaceholders async t ret - env = M.fromList (rp ++ ap) + env = addListToUFM emptyUFM (rp ++ ap) if length tgt == 1 then return $ statPre <> (mapStatIdent (replaceIdent env) (var "$r" |= expr)) else return $ statPre <> (mapStatIdent (replaceIdent env) (toStat expr)) @@ -159,7 +159,7 @@ parseFFIPattern' callback javascriptCc pat t ret args let rp = resultPlaceholders async t ret let cp = callbackPlaceholders callback (statPre, ap) <- argPlaceholders javascriptCc args - let env = M.fromList (rp ++ ap ++ cp) + let env = addListToUFM emptyUFM (rp ++ ap ++ cp) return $ statPre <> (mapStatIdent (replaceIdent env) stat) -- fixme trace? where async = isJust callback @@ -186,9 +186,10 @@ parseFFIPattern' callback javascriptCc pat t ret args where f' = toJExpr (TxtI $ mkFastString f) copyResult rs = mconcat $ zipWith (\t r -> toJExpr r |= toJExpr t) (enumFrom Ret1) rs p e = error ("Parse error in FFI pattern: " ++ pat ++ "\n" ++ e) - replaceIdent :: M.Map Ident JExpr -> Ident -> JExpr + + replaceIdent :: UniqFM Ident JExpr -> Ident -> JExpr replaceIdent env i - | isFFIPlaceholder i = fromMaybe err (M.lookup i env) + | isFFIPlaceholder i = fromMaybe err (lookupUFM env i) | otherwise = ValExpr (JVar i) where (TxtI i') = i ===================================== compiler/GHC/StgToJS/Ids.hs ===================================== @@ -49,6 +49,7 @@ import GHC.JS.Make import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Unique +import GHC.Types.Unique.FM import GHC.Types.Name import GHC.Unit.Module import GHC.Utils.Encoding (zEncodeString) @@ -158,9 +159,9 @@ cachedIdentForId i mi id_type = do when (update_global_cache) $ do GlobalIdCache gidc <- getGlobalIdCache - case M.lookup ident gidc of - Nothing -> setGlobalIdCache $ GlobalIdCache (M.insert ident (key, i) gidc) - Just _ -> pure () + case elemUFM ident gidc of + False -> setGlobalIdCache $ GlobalIdCache (addToUFM gidc ident (key, i)) + True -> pure () pure ident ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -70,6 +70,7 @@ import GHC.Types.Unique.Set import qualified GHC.SysTools.Ar as Ar +import qualified GHC.Data.ShortText as ST import GHC.Data.FastString import Control.Concurrent.MVar @@ -382,7 +383,7 @@ renderLinkerStats s = getPackageArchives :: StgToJSConfig -> UnitEnv -> [UnitId] -> IO [FilePath] getPackageArchives cfg unit_env units = - filterM doesFileExist [ p "lib" ++ l ++ profSuff <.> "a" + filterM doesFileExist [ ST.unpack p "lib" ++ ST.unpack l ++ profSuff <.> "a" | u <- units , p <- getInstalledPackageLibDirs ue_state u , l <- getInstalledPackageHsLibs ue_state u ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -47,12 +47,12 @@ import Data.Char (isSpace) import qualified Control.Exception as Exception -- | Retrieve library directories provided by the @UnitId@ in @UnitState@ -getInstalledPackageLibDirs :: UnitState -> UnitId -> [FilePath] -getInstalledPackageLibDirs us = fmap unpack . maybe mempty unitLibraryDirs . lookupUnitId us +getInstalledPackageLibDirs :: UnitState -> UnitId -> [ShortText] +getInstalledPackageLibDirs us = maybe mempty unitLibraryDirs . lookupUnitId us -- | Retrieve the names of the libraries provided by @UnitId@ -getInstalledPackageHsLibs :: UnitState -> UnitId -> [String] -getInstalledPackageHsLibs us = fmap unpack . maybe mempty unitLibraries . lookupUnitId us +getInstalledPackageHsLibs :: UnitState -> UnitId -> [ShortText] +getInstalledPackageHsLibs us = maybe mempty unitLibraries . lookupUnitId us -- | A constant holding the JavaScript executable Filename extension jsexeExtension :: String ===================================== compiler/GHC/StgToJS/Monad.hs ===================================== @@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE LambdaCase #-} -- | JS codegen state monad module GHC.StgToJS.Monad @@ -13,9 +14,10 @@ module GHC.StgToJS.Monad , emitForeign , assertRtsStat , getSettings - , liftToGlobal + , globalOccs , setGlobalIdCache , getGlobalIdCache + , GlobalOcc(..) -- * Group , modifyGroup , resetGroup @@ -44,9 +46,6 @@ import GHC.Data.FastMutInt import qualified Data.Map as M import qualified Data.Set as S import qualified Data.List as L -import Data.Function - -import GHC.Types.Unique.DSet runG :: StgToJSConfig -> Module -> UniqFM Id CgStgExpr -> G a -> IO a runG config m unfloat action = State.evalStateT action =<< initState config m unfloat @@ -133,7 +132,7 @@ defaultGenGroupState :: GenGroupState defaultGenGroupState = GenGroupState [] [] [] [] 0 S.empty emptyGlobalIdCache [] emptyGlobalIdCache :: GlobalIdCache -emptyGlobalIdCache = GlobalIdCache M.empty +emptyGlobalIdCache = GlobalIdCache emptyUFM emptyIdCache :: IdCache emptyIdCache = IdCache M.empty @@ -155,17 +154,32 @@ setGlobalIdCache :: GlobalIdCache -> G () setGlobalIdCache v = State.modify (\s -> s { gsGroup = (gsGroup s) { ggsGlobalIdCache = v}}) -liftToGlobal :: JStat -> G [(Ident, Id)] -liftToGlobal jst = do - GlobalIdCache gidc <- getGlobalIdCache - let sids = filterUniqDSet (`M.member` gidc) (identsS jst) - cnt = M.fromListWith (+) (map (,(1::Integer)) $ uniqDSetToList sids) - sids' = L.sortBy (compare `on` (cnt M.!)) (nub' $ uniqDSetToList sids) - pure $ map (\s -> (s, snd $ gidc M.! s)) sids' +data GlobalOcc = GlobalOcc + { global_ident :: !Ident + , global_id :: !Id + , global_count :: !Word + } -nub' :: (Ord a, Eq a) => [a] -> [a] -nub' xs = go S.empty xs - where - go _ [] = [] - go s (x:xs) | S.member x s = go s xs - | otherwise = x : go (S.insert x s) xs +-- | Return number of occurrences of every global id used in the given JStat. +-- Sort by increasing occurrence count. +globalOccs :: JStat -> G [GlobalOcc] +globalOccs jst = do + GlobalIdCache gidc <- getGlobalIdCache + -- build a map form Ident Unique to (Ident, Id, Count) + let + cmp_cnt g1 g2 = compare (global_count g1) (global_count g2) + inc g1 g2 = g1 { global_count = global_count g1 + global_count g2 } + go gids = \case + [] -> -- return global Ids used locally sorted by increased use + L.sortBy cmp_cnt $ nonDetEltsUFM gids + (i:is) -> + -- check if the Id is global + case lookupUFM gidc i of + Nothing -> go gids is + Just (_k,gid) -> + -- add it to the list of already found global ids. Increasing + -- count by 1 + let g = GlobalOcc i gid 1 + in go (addToUFM_C inc gids i g) is + + pure $ go emptyUFM (identsS jst) ===================================== compiler/GHC/StgToJS/Rts/Rts.hs ===================================== @@ -392,35 +392,32 @@ rts' s = , TxtI "h$vt_arr" ||= toJExpr ArrV , TxtI "h$bh" ||= jLam (bhStats s True) , TxtI "h$bh_lne" ||= jLam (\x frameSize -> bhLneStats s x frameSize) - , closure (ClosureInfo "h$blackhole" (CIRegs 0 []) "blackhole" (CILayoutUnknown 2) CIBlackhole mempty) + , closure (ClosureInfo (TxtI "h$blackhole") (CIRegs 0 []) "blackhole" (CILayoutUnknown 2) CIBlackhole mempty) (appS "throw" [jString "oops: entered black hole"]) - , closure (ClosureInfo "h$blackholeTrap" (CIRegs 0 []) "blackhole" (CILayoutUnknown 2) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$blackholeTrap") (CIRegs 0 []) "blackhole" (CILayoutUnknown 2) CIThunk mempty) (appS "throw" [jString "oops: entered multiple times"]) - , closure (ClosureInfo "h$done" (CIRegs 0 [PtrV]) "done" (CILayoutUnknown 0) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$done") (CIRegs 0 [PtrV]) "done" (CILayoutUnknown 0) CIStackFrame mempty) (appS "h$finishThread" [var "h$currentThread"] <> returnS (var "h$reschedule")) - , closure (ClosureInfo "h$doneMain_e" (CIRegs 0 [PtrV]) "doneMain" (CILayoutUnknown 0) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$doneMain_e") (CIRegs 0 [PtrV]) "doneMain" (CILayoutUnknown 0) CIStackFrame mempty) (returnS (var "h$doneMain")) - , conClosure "h$false_e" "GHC.Types.False" (CILayoutFixed 0 []) 1 - , conClosure "h$true_e" "GHC.Types.True" (CILayoutFixed 0 []) 2 - , conClosure "h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e" "GHC.Integer.Type.S#" (CILayoutFixed 1 [IntV]) 1 - , conClosure "h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e" "GHC.Integer.Type.Jp#" (CILayoutFixed 1 [ObjV]) 2 - , conClosure "h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e" "GHC.Integer.Type.Jn#" (CILayoutFixed 1 [ObjV]) 3 + , conClosure (TxtI "h$false_e") "GHC.Types.False" (CILayoutFixed 0 []) 1 + , conClosure (TxtI "h$true_e" ) "GHC.Types.True" (CILayoutFixed 0 []) 2 -- generic data constructor with 1 non-heapobj field - , conClosure "h$data1_e" "data1" (CILayoutFixed 1 [ObjV]) 1 + , conClosure (TxtI "h$data1_e") "data1" (CILayoutFixed 1 [ObjV]) 1 -- generic data constructor with 2 non-heapobj fields - , conClosure "h$data2_e" "data2" (CILayoutFixed 2 [ObjV,ObjV]) 1 - , closure (ClosureInfo "h$noop_e" (CIRegs 1 [PtrV]) "no-op IO ()" (CILayoutFixed 0 []) (CIFun 1 0) mempty) + , conClosure (TxtI "h$data2_e") "data2" (CILayoutFixed 2 [ObjV,ObjV]) 1 + , closure (ClosureInfo (TxtI "h$noop_e") (CIRegs 1 [PtrV]) "no-op IO ()" (CILayoutFixed 0 []) (CIFun 1 0) mempty) (returnS (stack .! sp)) <> (TxtI "h$noop" ||= ApplExpr (var "h$c0") (var "h$noop_e" : [jSystemCCS | csProf s])) - , closure (ClosureInfo "h$catch_e" (CIRegs 0 [PtrV]) "exception handler" (CILayoutFixed 2 [PtrV,IntV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$catch_e") (CIRegs 0 [PtrV]) "exception handler" (CILayoutFixed 2 [PtrV,IntV]) CIStackFrame mempty) (adjSpN' 3 <> returnS (stack .! sp)) - , closure (ClosureInfo "h$dataToTag_e" (CIRegs 0 [PtrV]) "data to tag" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$dataToTag_e") (CIRegs 0 [PtrV]) "data to tag" (CILayoutFixed 0 []) CIStackFrame mempty) $ mconcat [ r1 |= if_ (r1 .===. true_) 1 (if_ (typeof r1 .===. jTyObject) (r1 .^ "f" .^ "a" - 1) 0) , adjSpN' 1 , returnS (stack .! sp) ] -- function application to one argument - , closure (ClosureInfo "h$ap1_e" (CIRegs 0 [PtrV]) "apply1" (CILayoutFixed 2 [PtrV, PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$ap1_e") (CIRegs 0 [PtrV]) "apply1" (CILayoutFixed 2 [PtrV, PtrV]) CIThunk mempty) (jVar $ \d1 d2 -> mconcat [ d1 |= closureField1 r1 , d2 |= closureField2 r1 @@ -431,7 +428,7 @@ rts' s = , returnS (app "h$ap_1_1_fast" []) ]) -- function application to two arguments - , closure (ClosureInfo "h$ap2_e" (CIRegs 0 [PtrV]) "apply2" (CILayoutFixed 3 [PtrV, PtrV, PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$ap2_e") (CIRegs 0 [PtrV]) "apply2" (CILayoutFixed 3 [PtrV, PtrV, PtrV]) CIThunk mempty) (jVar $ \d1 d2 d3 -> mconcat [ d1 |= closureField1 r1 , d2 |= closureField2 r1 .^ "d1" @@ -444,7 +441,7 @@ rts' s = , returnS (app "h$ap_2_2_fast" []) ]) -- function application to three arguments - , closure (ClosureInfo "h$ap3_e" (CIRegs 0 [PtrV]) "apply3" (CILayoutFixed 4 [PtrV, PtrV, PtrV, PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$ap3_e") (CIRegs 0 [PtrV]) "apply3" (CILayoutFixed 4 [PtrV, PtrV, PtrV, PtrV]) CIThunk mempty) (jVar $ \d1 d2 d3 d4 -> mconcat [ d1 |= closureField1 r1 , d2 |= closureField2 r1 .^ "d1" @@ -458,7 +455,7 @@ rts' s = , returnS (app "h$ap_3_3_fast" []) ]) -- select first field - , closure (ClosureInfo "h$select1_e" (CIRegs 0 [PtrV]) "select1" (CILayoutFixed 1 [PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$select1_e") (CIRegs 0 [PtrV]) "select1" (CILayoutFixed 1 [PtrV]) CIThunk mempty) (jVar $ \t -> mconcat [ t |= closureField1 r1 , adjSp' 3 @@ -471,13 +468,13 @@ rts' s = , r1 |= t , returnS (app "h$ap_0_0_fast" []) ]) - , closure (ClosureInfo "h$select1_ret" (CIRegs 0 [PtrV]) "select1ret" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$select1_ret") (CIRegs 0 [PtrV]) "select1ret" (CILayoutFixed 0 []) CIStackFrame mempty) ((r1 |= closureField1 r1) <> adjSpN' 1 <> returnS (app "h$ap_0_0_fast" []) ) -- select second field of a two-field constructor - , closure (ClosureInfo "h$select2_e" (CIRegs 0 [PtrV]) "select2" (CILayoutFixed 1 [PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$select2_e") (CIRegs 0 [PtrV]) "select2" (CILayoutFixed 1 [PtrV]) CIThunk mempty) (jVar $ \t -> mconcat [t |= closureField1 r1 , adjSp' 3 @@ -491,22 +488,22 @@ rts' s = , returnS (app "h$ap_0_0_fast" []) ] ) - , closure (ClosureInfo "h$select2_ret" (CIRegs 0 [PtrV]) "select2ret" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$select2_ret") (CIRegs 0 [PtrV]) "select2ret" (CILayoutFixed 0 []) CIStackFrame mempty) $ mconcat [ r1 |= closureField2 r1 , adjSpN' 1 , returnS (app "h$ap_0_0_fast" []) ] - , closure (ClosureInfo "h$keepAlive_e" (CIRegs 0 [PtrV]) "keepAlive" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$keepAlive_e") (CIRegs 0 [PtrV]) "keepAlive" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) (mconcat [ adjSpN' 2 , returnS (stack .! sp) ] ) -- a thunk that just raises a synchronous exception - , closure (ClosureInfo "h$raise_e" (CIRegs 0 [PtrV]) "h$raise_e" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$raise_e") (CIRegs 0 [PtrV]) "h$raise_e" (CILayoutFixed 0 []) CIThunk mempty) (returnS (app "h$throw" [closureField1 r1, false_])) - , closure (ClosureInfo "h$raiseAsync_e" (CIRegs 0 [PtrV]) "h$raiseAsync_e" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$raiseAsync_e") (CIRegs 0 [PtrV]) "h$raiseAsync_e" (CILayoutFixed 0 []) CIThunk mempty) (returnS (app "h$throw" [closureField1 r1, true_])) - , closure (ClosureInfo "h$raiseAsync_frame" (CIRegs 0 []) "h$raiseAsync_frame" (CILayoutFixed 1 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$raiseAsync_frame") (CIRegs 0 []) "h$raiseAsync_frame" (CILayoutFixed 1 []) CIStackFrame mempty) (jVar $ \ex -> mconcat [ ex |= stack .! (sp - 1) , adjSpN' 2 @@ -516,19 +513,19 @@ rts' s = add this to the stack if you want the outermost result to always be reduced to whnf, and not an ind -} - , closure (ClosureInfo "h$reduce" (CIRegs 0 [PtrV]) "h$reduce" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$reduce") (CIRegs 0 [PtrV]) "h$reduce" (CILayoutFixed 0 []) CIStackFrame mempty) (ifS (isThunk r1) (returnS (r1 .^ "f")) (adjSpN' 1 <> returnS (stack .! sp)) ) , rtsApply s , closureTypes - , closure (ClosureInfo "h$runio_e" (CIRegs 0 [PtrV]) "runio" (CILayoutFixed 1 [PtrV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$runio_e") (CIRegs 0 [PtrV]) "runio" (CILayoutFixed 1 [PtrV]) CIThunk mempty) $ mconcat [ r1 |= closureField1 r1 , stack .! PreInc sp |= var "h$ap_1_0" , returnS (var "h$ap_1_0") ] - , closure (ClosureInfo "h$flushStdout_e" (CIRegs 0 []) "flushStdout" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$flushStdout_e") (CIRegs 0 []) "flushStdout" (CILayoutFixed 0 []) CIThunk mempty) $ mconcat [ r1 |= var "h$baseZCGHCziIOziHandlezihFlush" , r2 |= var "h$baseZCGHCziIOziHandleziFDzistdout" , returnS (app "h$ap_1_1_fast" []) @@ -536,7 +533,7 @@ rts' s = , TxtI "h$flushStdout" ||= app "h$static_thunk" [var "h$flushStdout_e"] -- the scheduler pushes this frame when suspending a thread that -- has not called h$reschedule explicitly - , closure (ClosureInfo "h$restoreThread" (CIRegs 0 []) "restoreThread" CILayoutVariable CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$restoreThread") (CIRegs 0 []) "restoreThread" CILayoutVariable CIStackFrame mempty) (jVar $ \f frameSize nregs -> mconcat [f |= stack .! (sp - 2) , frameSize |= stack .! (sp - 1) @@ -547,12 +544,12 @@ rts' s = , returnS f ]) -- return a closure in the stack frame to the next thing on the stack - , closure (ClosureInfo "h$return" (CIRegs 0 []) "return" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$return") (CIRegs 0 []) "return" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) ((r1 |= stack .! (sp - 1)) <> adjSpN' 2 <> returnS (stack .! sp)) -- return a function in the stack frame for the next call - , closure (ClosureInfo "h$returnf" (CIRegs 0 [PtrV]) "returnf" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$returnf") (CIRegs 0 [PtrV]) "returnf" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) (jVar $ \r -> mconcat [ r |= stack .! (sp - 1) , adjSpN' 2 @@ -561,10 +558,10 @@ rts' s = -- return this function when the scheduler needs to come into action -- (yield, delay etc), returning thread needs to push all relevant -- registers to stack frame, thread will be resumed by calling the stack top - , closure (ClosureInfo "h$reschedule" (CIRegs 0 []) "reschedule" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$reschedule") (CIRegs 0 []) "reschedule" (CILayoutFixed 0 []) CIThunk mempty) (returnS $ var "h$reschedule") -- debug thing, insert on stack to dump current result, should be boxed - , closure (ClosureInfo "h$dumpRes" (CIRegs 0 [PtrV]) "dumpRes" (CILayoutFixed 1 [ObjV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$dumpRes") (CIRegs 0 [PtrV]) "dumpRes" (CILayoutFixed 1 [ObjV]) CIThunk mempty) (jVar $ \re -> mconcat [ appS "h$log" [jString "h$dumpRes result: " + stack .! (sp-1)] , appS "h$log" [r1] @@ -584,7 +581,7 @@ rts' s = , r1 |= null_ , returnS (stack .! sp) ]) - , closure (ClosureInfo "h$resume_e" (CIRegs 0 [PtrV]) "resume" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$resume_e") (CIRegs 0 [PtrV]) "resume" (CILayoutFixed 0 []) CIThunk mempty) (jVar $ \ss -> mconcat [ss |= closureField1 r1 , updateThunk' s @@ -594,52 +591,52 @@ rts' s = , r1 |= null_ , returnS (stack .! sp) ]) - , closure (ClosureInfo "h$unmaskFrame" (CIRegs 0 [PtrV]) "unmask" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$unmaskFrame") (CIRegs 0 [PtrV]) "unmask" (CILayoutFixed 0 []) CIStackFrame mempty) ((var "h$currentThread" .^ "mask" |= 0) <> adjSpN' 1 -- back to scheduler to give us async exception if pending <> ifS (var "h$currentThread" .^ "excep" .^ "length" .>. 0) (push' s [r1, var "h$return"] <> returnS (var "h$reschedule")) (returnS (stack .! sp))) - , closure (ClosureInfo "h$maskFrame" (CIRegs 0 [PtrV]) "mask" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$maskFrame") (CIRegs 0 [PtrV]) "mask" (CILayoutFixed 0 []) CIStackFrame mempty) ((var "h$currentThread" .^ "mask" |= 2) <> adjSpN' 1 <> returnS (stack .! sp)) - , closure (ClosureInfo "h$maskUnintFrame" (CIRegs 0 [PtrV]) "maskUnint" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$maskUnintFrame") (CIRegs 0 [PtrV]) "maskUnint" (CILayoutFixed 0 []) CIStackFrame mempty) ((var "h$currentThread" .^ "mask" |= 1) <> adjSpN' 1 <> returnS (stack .! sp)) - , closure (ClosureInfo "h$unboxFFIResult" (CIRegs 0 [PtrV]) "unboxFFI" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$unboxFFIResult") (CIRegs 0 [PtrV]) "unboxFFI" (CILayoutFixed 0 []) CIStackFrame mempty) (jVar $ \d -> mconcat [d |= closureField1 r1 , loop 0 (.<. d .^ "length") (\i -> appS "h$setReg" [i + 1, d .! i] <> postIncrS i) , adjSpN' 1 , returnS (stack .! sp) ]) - , closure (ClosureInfo "h$unbox_e" (CIRegs 0 [PtrV]) "unboxed value" (CILayoutFixed 1 [DoubleV]) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$unbox_e") (CIRegs 0 [PtrV]) "unboxed value" (CILayoutFixed 1 [DoubleV]) CIThunk mempty) ((r1 |= closureField1 r1) <> returnS (stack .! sp)) - , closure (ClosureInfo "h$retryInterrupted" (CIRegs 0 [ObjV]) "retry interrupted operation" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$retryInterrupted") (CIRegs 0 [ObjV]) "retry interrupted operation" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) (jVar $ \a -> mconcat [ a |= stack .! (sp - 1) , adjSpN' 2 , returnS (ApplExpr (a .! 0 .^ "apply") [var "this", ApplExpr (a .^ "slice") [1]]) ]) - , closure (ClosureInfo "h$atomically_e" (CIRegs 0 [PtrV]) "atomic operation" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$atomically_e") (CIRegs 0 [PtrV]) "atomic operation" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) (ifS (app "h$stmValidateTransaction" []) (appS "h$stmCommitTransaction" [] <> adjSpN' 2 <> returnS (stack .! sp)) (returnS (app "h$stmStartTransaction" [stack .! (sp - 2)]))) - , closure (ClosureInfo "h$stmCatchRetry_e" (CIRegs 0 [PtrV]) "catch retry" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$stmCatchRetry_e") (CIRegs 0 [PtrV]) "catch retry" (CILayoutFixed 1 [PtrV]) CIStackFrame mempty) (adjSpN' 2 <> appS "h$stmCommitTransaction" [] <> returnS (stack .! sp)) - , closure (ClosureInfo "h$catchStm_e" (CIRegs 0 [PtrV]) "STM catch" (CILayoutFixed 3 [ObjV,PtrV,ObjV]) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$catchStm_e") (CIRegs 0 [PtrV]) "STM catch" (CILayoutFixed 3 [ObjV,PtrV,ObjV]) CIStackFrame mempty) (adjSpN' 4 <> appS "h$stmCommitTransaction" [] <> returnS (stack .! sp)) - , closure (ClosureInfo "h$stmResumeRetry_e" (CIRegs 0 [PtrV]) "resume retry" (CILayoutFixed 0 []) CIStackFrame mempty) + , closure (ClosureInfo (TxtI "h$stmResumeRetry_e") (CIRegs 0 [PtrV]) "resume retry" (CILayoutFixed 0 []) CIStackFrame mempty) (jVar $ \blocked -> mconcat [ jwhenS (stack .! (sp - 2) .!==. var "h$atomically_e") (appS "throw" [jString "h$stmResumeRetry_e: unexpected value on stack"]) @@ -648,7 +645,7 @@ rts' s = , appS "h$stmRemoveBlockedThread" [blocked, var "h$currentThread"] , returnS (app "h$stmStartTransaction" [stack .! (sp - 2)]) ]) - , closure (ClosureInfo "h$lazy_e" (CIRegs 0 [PtrV]) "generic lazy value" (CILayoutFixed 0 []) CIThunk mempty) + , closure (ClosureInfo (TxtI "h$lazy_e") (CIRegs 0 [PtrV]) "generic lazy value" (CILayoutFixed 0 []) CIThunk mempty) (jVar $ \x -> mconcat [x |= ApplExpr (closureField1 r1) [] , appS "h$bh" [] @@ -657,7 +654,7 @@ rts' s = , returnS (stack .! sp) ]) -- Top-level statements to generate only in profiling mode - , profStat s (closure (ClosureInfo "h$setCcs_e" (CIRegs 0 [PtrV]) "set cost centre stack" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) + , profStat s (closure (ClosureInfo (TxtI "h$setCcs_e") (CIRegs 0 [PtrV]) "set cost centre stack" (CILayoutFixed 1 [ObjV]) CIStackFrame mempty) (appS "h$restoreCCS" [ stack .! (sp - 1)] <> adjSpN' 2 <> returnS (stack .! sp))) ===================================== compiler/GHC/StgToJS/Types.hs ===================================== @@ -98,7 +98,7 @@ data StgToJSConfig = StgToJSConfig -- | Information relevenat to code generation for closures. data ClosureInfo = ClosureInfo - { ciVar :: FastString -- ^ object being infod + { ciVar :: Ident -- ^ object being infod , ciRegs :: CIRegs -- ^ size of the payload (in number of JS values) , ciName :: FastString -- ^ friendly name for printing , ciLayout :: CILayout -- ^ heap/stack layout of the object @@ -216,7 +216,7 @@ instance Ord OtherSymb where newtype IdCache = IdCache (M.Map IdKey Ident) -- | The global Identifier Cache -newtype GlobalIdCache = GlobalIdCache (M.Map Ident (IdKey, Id)) +newtype GlobalIdCache = GlobalIdCache (UniqFM Ident (IdKey, Id)) -- | A Stack Slot is either known or unknown. We avoid maybe here for more -- strictness. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a95716a5c4133e3fe6c9e1552295823c17e3b49...01e0ca4f31e6eccb0420a8763b9064cd1e99172d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a95716a5c4133e3fe6c9e1552295823c17e3b49...01e0ca4f31e6eccb0420a8763b9064cd1e99172d You're receiving 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 Oct 16 14:03:52 2022 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Sun, 16 Oct 2022 10:03:52 -0400 Subject: [Git][ghc/ghc][wip/llvm-ways] FIx T15155l not getting -fllvm Message-ID: <634c0f48d6c6b_8b90f51748306069@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/llvm-ways at Glasgow Haskell Compiler / GHC Commits: b75b85b1 by Krzysztof Gogolewski at 2022-10-16T16:02:11+02:00 FIx T15155l not getting -fllvm - - - - - 1 changed file: - testsuite/tests/codeGen/should_compile/Makefile Changes: ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -57,8 +57,8 @@ T15155: # Same as above, but in LLVM. Check that the static indirection b is compiled to # an alias. T15155l: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 -ddump-llvm T15155l.hs 2>/dev/null | \ - grep -F "@T15155_b_closure = alias i8, i8* @T15155_a_closure" + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 -fllvm -ddump-llvm -fforce-recomp T15155l.hs | \ + grep -F "alias i8, i8*" # Without -fcatch-nonexhaustive-cases `f` is non-CAFFY. With # -fcatch-nonexhaustive-cases it becomes CAFFY. Before CafInfo rework View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b75b85b14ceca9ef2acf81425b9aef12377f384e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b75b85b14ceca9ef2acf81425b9aef12377f384e You're receiving 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 Oct 16 14:41:44 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 16 Oct 2022 10:41:44 -0400 Subject: [Git][ghc/ghc][wip/backports-9.4] gitlab-ci: Ensure that ghc derivation is in scope Message-ID: <634c1828c6813_8b90f5143c308970@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.4 at Glasgow Haskell Compiler / GHC Commits: 9a12e496 by Ben Gamari at 2022-10-16T10:41:41-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. (cherry picked from commit 25f68acedf822e9ea21d1659b1f897fcfc96e5d4) - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -267,7 +267,7 @@ lint-ci-config: - mkdir -p ~/.cabal - cp -Rf cabal-cache/* ~/.cabal || true script: - - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#cabal-install -c cabal update + - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#cabal-install nixpkgs#ghc -c cabal update - .gitlab/generate_jobs # 1 if .gitlab/generate_jobs changed the output of the generated config - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#git -c git diff --exit-code View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a12e4961256f4c25201b8b8736ab4ef4ba0083e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a12e4961256f4c25201b8b8736ab4ef4ba0083e You're receiving 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 Oct 16 14:48:18 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 16 Oct 2022 10:48:18 -0400 Subject: [Git][ghc/ghc][wip/per-capability] 572 commits: Use UnionListsOrd instead of UnionLists in most places. Message-ID: <634c19b267209_8b90f5143c3095d0@gitlab.mail> Ben Gamari pushed to branch wip/per-capability at Glasgow Haskell Compiler / GHC Commits: 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Bodigrim at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergo ERDI at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Bodigrim at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 241be1a1 by Ben Gamari at 2022-10-14T13:40:41-04:00 GHC.IOArray: Introduce unsafeFreezeIOArray - - - - - 90915b3b by Ben Gamari at 2022-10-14T13:40:42-04:00 Add GHC.PerCapability - - - - - f2511ad4 by Ben Gamari at 2022-10-14T16:55:29-04:00 Port MIO to use PerCapability - - - - - 28 changed files: - − .appveyor.sh - .editorconfig - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/CodeGen.Platform.h - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps/Ids.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/487dee850cdf4fc86010097826d385a33b971d97...f2511ad4ac4ef94e82aacae270bc518227756c78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/487dee850cdf4fc86010097826d385a33b971d97...f2511ad4ac4ef94e82aacae270bc518227756c78 You're receiving 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 Oct 16 17:28:06 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 16 Oct 2022 13:28:06 -0400 Subject: [Git][ghc/ghc][ghc-9.4] 11 commits: Ignore .hie-bios Message-ID: <634c3f26bb128_8b90f5143c3271c2@gitlab.mail> Ben Gamari pushed to branch ghc-9.4 at Glasgow Haskell Compiler / GHC Commits: 15c496c5 by Sebastian Graf at 2022-10-12T19:20:16-04:00 Ignore .hie-bios (cherry picked from commit 2563b95cda983cd6be23a5be01fe1f1873f1fa4f) - - - - - 26af15a0 by Sebastian Graf at 2022-10-12T19:20:16-04:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. (cherry picked from commit 94f2e92a2510a3338c5201a4dcc69666fa9575f8) - - - - - ecb6accd by Sebastian Graf at 2022-10-14T16:16:07-04:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. (cherry picked from commit b570da84b7aad5ca3f90f2d1c1a690c927e99fe9) - - - - - c0b5736c by Sebastian Graf at 2022-10-14T17:10:27-04:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 (cherry picked from commit 49fb2f9b16ca987648d2ac57eecf1892d49852ec) - - - - - ccdaa83c by Ben Gamari at 2022-10-14T17:10:27-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. (cherry picked from commit cd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3) - - - - - 671491cc by Matthew Pickering at 2022-10-14T17:10:27-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 (cherry picked from commit 2361b3bc08811b0d2fb8f8fc5635b7c2fec157c6) - - - - - 6bf992e6 by Ryan Scott at 2022-10-14T17:10:27-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. (cherry picked from commit 8a666ad2a89a8ad2aa24a6406b88f516afaec671) - - - - - 3eace272 by Ryan Scott at 2022-10-14T17:10:27-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. (cherry picked from commit 3a815f30bcba5672085e823aeef90863253b0b1a) - - - - - 9ae4865b by Cheng Shao at 2022-10-14T17:10:27-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh (cherry picked from commit ee471dfb8a4a4bb5131a5baa61d1d0d22c933d5f) - - - - - 6af677a9 by Matthew Pickering at 2022-10-14T17:10:27-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 (cherry picked from commit 7f0decd5063a853fc8f38a8944b2c91995cd5e48) - - - - - 9a12e496 by Ben Gamari at 2022-10-16T10:41:41-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. (cherry picked from commit 25f68acedf822e9ea21d1659b1f897fcfc96e5d4) - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/Graph/UnVar.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Tc/Deriv/Functor.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Types/SrcLoc.hs - compiler/GHC/Utils/Binary.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Settings/Builders/Haddock.hs - m4/fp_setup_windows_toolchain.m4 - rts/PrimOps.cmm - testsuite/tests/arityanal/should_compile/Arity03.stderr - + testsuite/tests/arityanal/should_run/Makefile - + testsuite/tests/arityanal/should_run/T21652.hs - + testsuite/tests/arityanal/should_run/T21652.stdout - + testsuite/tests/arityanal/should_run/all.T - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/deSugar/should_compile/T19969.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cf828e829011f103ea946756a0c53322fa238dd...9a12e4961256f4c25201b8b8736ab4ef4ba0083e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2cf828e829011f103ea946756a0c53322fa238dd...9a12e4961256f4c25201b8b8736ab4ef4ba0083e You're receiving 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 Oct 16 17:28:05 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sun, 16 Oct 2022 13:28:05 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/backports-9.4 Message-ID: <634c3f25ae6f5_8b90f517d43269e4@gitlab.mail> Ben Gamari deleted branch wip/backports-9.4 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 Sun Oct 16 18:35:20 2022 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Sun, 16 Oct 2022 14:35:20 -0400 Subject: [Git][ghc/ghc][wip/az/T21355-exactprint-update] 6 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <634c4ee8b5316_8b90f5143c3293a0@gitlab.mail> Alan Zimmerman pushed to branch wip/az/T21355-exactprint-update at Glasgow Haskell Compiler / GHC Commits: 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - e020fdec by Alan Zimmerman at 2022-10-16T19:35:07+01:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 30 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/posix/OSThreads.c - testsuite/tests/ghc-api/exactprint/AddDecl2.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.hs - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T - testsuite/tests/printer/Makefile - + testsuite/tests/printer/Test21355.hs - testsuite/tests/printer/all.T - utils/check-exact/.ghci - utils/check-exact/ExactPrint.hs - utils/check-exact/Lookup.hs - utils/check-exact/Main.hs - + utils/check-exact/Orphans.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5baa2b4c8d2c2fde3c5e2693e3e7711d7e94d480...e020fdec3b70bd107e1bf97b721f97d720d7273a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5baa2b4c8d2c2fde3c5e2693e3e7711d7e94d480...e020fdec3b70bd107e1bf97b721f97d720d7273a You're receiving 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 Oct 16 22:28:54 2022 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 16 Oct 2022 18:28:54 -0400 Subject: [Git][ghc/ghc][wip/T21623] Wibbles Message-ID: <634c85a6d9612_8b90f5175c3305f7@gitlab.mail> Simon Peyton Jones pushed to branch wip/T21623 at Glasgow Haskell Compiler / GHC Commits: c94b50dd by Simon Peyton Jones at 2022-10-16T23:28:41+01:00 Wibbles - - - - - 3 changed files: - compiler/GHC/Core/Coercion/Opt.hs - testsuite/tests/partial-sigs/should_compile/T16728.stderr - testsuite/tests/partial-sigs/should_compile/T21667.stderr Changes: ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -125,8 +125,19 @@ optCoercion :: OptCoercionOpts -> Subst -> Coercion -> NormalCo -- ^ optCoercion applies a substitution to a coercion, -- *and* optimises it to reduce its size optCoercion opts env co - | optCoercionEnabled opts = optCoercion' env co - | otherwise = substCo env co + | optCoercionEnabled opts + = optCoercion' env co +{- + = pprTrace "optCoercion {" (text "Co:" <+> ppr co) $ + let result = optCoercion' env co in + pprTrace "optCoercion }" (vcat [ text "Co:" <+> ppr co + , text "Optco:" <+> ppr result ]) $ + result +-} + + | otherwise + = substCo env co + optCoercion' :: Subst -> Coercion -> NormalCo optCoercion' env co @@ -197,9 +208,12 @@ opt_co3 env sym _ r co = opt_co4_wrap env sym False r co -- See Note [Optimising coercion optimisation] -- | Optimize a non-phantom coercion. -opt_co4, opt_co4_wrap :: LiftingContext -> SymFlag -> ReprFlag -> Role -> Coercion -> NormalCo - +opt_co4, opt_co4_wrap :: LiftingContext -> SymFlag -> ReprFlag + -> Role -> Coercion -> NormalCo +-- Precondition: In every call (opt_co4 lc sym rep role co) +-- we should have role = coercionRole co opt_co4_wrap = opt_co4 + {- opt_co4_wrap env sym rep r co = pprTrace "opt_co4_wrap {" @@ -207,12 +221,13 @@ opt_co4_wrap env sym rep r co , text "Rep:" <+> ppr rep , text "Role:" <+> ppr r , text "Co:" <+> ppr co ]) $ - assert (r == coercionRole co ) + assert (r == coercionRole co ) $ let result = opt_co4 env sym rep r co in pprTrace "opt_co4_wrap }" (ppr co $$ text "---" $$ ppr result) $ result -} + opt_co4 env _ rep r (Refl ty) = assertPpr (r == Nominal) (text "Expected role:" <+> ppr r $$ @@ -340,9 +355,10 @@ opt_co4 env sym rep r (TransCo co1 co2) in_scope = lcInScopeSet env opt_co4 env _sym rep r (SelCo n co) - | Just (ty, co_role) <- isReflCo_maybe co - = assert (r == co_role ) $ - liftCoSubst (chooseRole rep r) env (getNthFromType n ty) + | Just (ty, _co_role) <- isReflCo_maybe co + = liftCoSubst (chooseRole rep r) env (getNthFromType n ty) + -- NB: it is /not/ true that r = _co_role + -- Rather, r = coercionRole (SelCo n co) opt_co4 env sym rep r (SelCo (SelTyCon n r1) (TyConAppCo _ _ cos)) = assert (r == r1 ) ===================================== testsuite/tests/partial-sigs/should_compile/T16728.stderr ===================================== @@ -1,9 +1,12 @@ -T16728.hs:8:37: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] +T16728.hs:8:37: warning: [GHC-88464] [-Wpartial-type-signatures] • Found type wildcard ‘_’ standing for ‘k’ Where: ‘k’ is a rigid type variable bound by the inferred type of f :: Proxy x at T16728.hs:8:13 • In the kind ‘_’ In the first argument of ‘Proxy’, namely ‘(x :: _)’ - In the type ‘Proxy (x :: _)’ + In the type signature: f :: forall k (x :: k). Proxy (x :: _) + | +8 | f :: forall k (x :: k). Proxy (x :: _) + | ^ ===================================== testsuite/tests/partial-sigs/should_compile/T21667.stderr ===================================== @@ -1,6 +1,8 @@ -T21667.hs:46:40: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] +T21667.hs:46:40: warning: [GHC-88464] [-Wpartial-type-signatures] • Found type wildcard ‘_’ standing for ‘"1" :: Symbol’ • In the second argument of ‘ExoticTraversal'’, namely ‘_’ - In the type ‘ExoticTraversal' a _ f’ In the type signature: test :: forall a f. ExoticTraversal' a _ f + | +46 | test :: forall a f. ExoticTraversal' a _ f + | ^ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c94b50dd4b76458379cf2e36bc15e271d4f98cd2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c94b50dd4b76458379cf2e36bc15e271d4f98cd2 You're receiving 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 Oct 16 23:25:05 2022 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Sun, 16 Oct 2022 19:25:05 -0400 Subject: [Git][ghc/ghc][wip/llvm-ways] Fix T15155l not getting -fllvm Message-ID: <634c92d191d37_8b90f51770331554@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/llvm-ways at Glasgow Haskell Compiler / GHC Commits: edfd863d by Krzysztof Gogolewski at 2022-10-17T01:21:15+02:00 Fix T15155l not getting -fllvm - - - - - 1 changed file: - testsuite/tests/codeGen/should_compile/Makefile Changes: ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -57,7 +57,7 @@ T15155: # Same as above, but in LLVM. Check that the static indirection b is compiled to # an alias. T15155l: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 -ddump-llvm T15155l.hs 2>/dev/null | \ + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 -fllvm -ddump-llvm T15155l.hs 2>/dev/null | \ grep -F "@T15155_b_closure = alias i8, i8* @T15155_a_closure" # Without -fcatch-nonexhaustive-cases `f` is non-CAFFY. With View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edfd863d30b4fb22b0e122f4a92b664617fd1ea6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edfd863d30b4fb22b0e122f4a92b664617fd1ea6 You're receiving 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 Oct 16 23:28:56 2022 From: gitlab at gitlab.haskell.org (doyougnu (@doyougnu)) Date: Sun, 16 Oct 2022 19:28:56 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 393 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <634c93b87579f_8b90f514143321d0@gitlab.mail> doyougnu pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 0af7d815 by Josh Meredith at 2022-10-16T18:18:44-04:00 Add ghcjs changes to deriveConstants: - change String targetOS option in deriveConstants to an enum - separate out getWantedGHSJS, removing generated c file in this path - - - - - 9e06fc3d by doyougnu at 2022-10-16T18:18:44-04:00 Add JavaScript code generator Adapt code generator of GHCJS to GHC head. Currently it is only enabled with the hidden -fjavascript flag. It produces .o files that can't be used yet except by GHCJS's linker. Codegen: doc Codegen: correctly return linkable object Now we can build a static library (-staticlib) Codegen: doc genLit Codegen: use assignAll Codegen: introduce TypedExpr Refactor assignAll et al, add documentation Codegen: minor changes Doc - - - - - 515adcd6 by doyougnu at 2022-10-16T18:18:45-04:00 Add JS.Rts JS.Rts: compiles reword: progress on RtsTypes StgToJS.Config: add SDoc Context JSRts: move ppr, workaround def type JSRts.Types: compiles JS.Rts: closer to compiling JS.Rts: move jsIdIdent' to StgToJS.Monad JS.Rts: remove unused predicates JS: cleanup, comment sections, math funcs to Make JS.Rts.Types: compiles StgToJS.Expr: fix compilation errors StgToJS.DataCon: move initClosure JS.Rts: remove Alloc module JS.Rts: initalize Rts module, remove redundant fs JS: init Rts.Alloc move initClosure JS.Apply: unwinding combinators in progress JS: add helpers and fixmes JS.Rts.Apply: no more e's, add closure, reg helper StgToJS: add ToStat instance ClosureInfo JS.Rts.Apply: closer to compiling JS.Rts.Apply: more removal of # JS.Rts.Apply: (#) removed JS.Rts.Apply: compiles JS.Rts.Rts: just pretty printing left JS.Rts: Add Notes JS.Rts: add file headers and notes JS.Rts.Rts: fixing stringy issues JS.Rts.Rts: compiles JS.Rts.Rts: fix non-exhaustive patterns warnings - - - - - 676c613c by Sylvain Henry at 2022-10-16T18:18:45-04:00 Doc has been moved into GHC.StgToJs top-level module - - - - - 2daeff7f by Sylvain Henry at 2022-10-16T18:18:45-04:00 JS.Rts; refactoring and move to StgToJS * add closure manipulation helpers and use them in Apply * add cache (Array) for pre-generated PAP names * reduce line length: * use BlockArguments instead of parens * remove implicit mconcat in jVar's body Rts: more refactorings Rts: move into StgToJS hierarchy - - - - - 3a8b0bde by Sylvain Henry at 2022-10-16T18:18:45-04:00 JS: cleanup, renaming, better module layout Various degrees of cleanup adapting GHCJS to GHC. We move several functions to CoreUtils, remove duplication between the JS.Rts.Apply and Apply module and factor out closure related code into a Closure module for cohesion. Deduplicate code between Rts.Apply and Apply Move might_be_a_function into CoreUtils Factorize closure stuff into Closure module Rename closureExtra into closureField Minor renamings, comments... - - - - - 0dcda6ea by Sylvain Henry at 2022-10-16T18:18:45-04:00 JS.Backend: add FFI code but don't implement yet FFI: don't crash on JavaScript foreign imports Note that they are still not desugared properly!! But the following cmd doesn't crash anymore: ghc -fjavascript Test.hs -fforce-recomp -ddump-tc -fno-code -ddump-ds FFI: adapt GHCJS desugarer FFI: support direct application The following example: foo :: Int# -> Int# foo = add 50000# foreign import javascript "(function(x,y) { return (x + y) })" add :: Int# -> Int# -> Int# is compiled into an application like this: var h$mainZCMzifoozur2_e; h$mainZCMzifoozur2_e = (function() { var h$mainZCMziaddzur1; h$mainZCMziaddzur1 = h$r1.d1; var h$$mainZCMzietazuB0_8KXnScrCjF5; h$$mainZCMzietazuB0_8KXnScrCjF5 = h$r2; h$r3 = h$$mainZCMzietazuB0_8KXnScrCjF5; h$r2 = 50000; h$r1 = h$mainZCMziaddzur1; return h$ap_2_2_fast(); return h$rs(); }); var h$mainZCMziaddzur1_e; h$mainZCMziaddzur1_e = (function() { var h$$mainZCMzidszusAk_236l8r0P8S9; h$$mainZCMzidszusAk_236l8r0P8S9 = h$r2; var h$$mainZCMzids1zusAl_336l8r0P8S9; h$$mainZCMzids1zusAl_336l8r0P8S9 = h$r3; var h$$mainZCM_2; var h$$mainZCMziwildzusAn_536l8r0P8S9; try { h$$mainZCMziwildzusAn_536l8r0P8S9 = (function(x,y) { return (x + y) })(h$$mainZCMzidszusAk_236l8r0P8S9, h$$mainZCMzids1zusAl_336l8r0P8S9) } catch(except) { return h$throwJSException(except) }; var h$$mainZCMzids3zusAp_736l8r0P8S9; h$$mainZCMzids3zusAp_736l8r0P8S9 = h$$mainZCMziwildzusAn_536l8r0P8S9; h$r1 = h$$mainZCMzids3zusAp_736l8r0P8S9; return h$rs(); }); FFI: correctly dispatch for foreign exports too FFI: move C FFI desugaring into its own module FFI: avoid DynFlags in toJsName (copy of toCName) - - - - - a663c436 by Sylvain Henry at 2022-10-16T18:18:45-04:00 Configure: preliminary support for triple js-unknown-ghcjs - - - - - 5e229331 by Sylvain Henry at 2022-10-16T18:18:46-04:00 Driver: enable JS backend by default for JS arch - - - - - a6de7c87 by doyougnu at 2022-10-16T18:18:46-04:00 JS.Backend: Add JS specific Linker JS: initialize Linker, DynamicLinking JS.Printer: adapted to GHC Head JS.Printer: some cleanup and init Printer StgToJS.Printer: Compiles JS.Linker: Add types, expose JS keywords JS.Syntax: add Binary instance on Ident's JS.Linker: Migrate more Types to Data.Binary JS.Linker.Types: compiles and adapted to GHC Head JS.Linker.Types: compiles JS.Linker.Types: add UseBase type JS.Linker: Comments and Cleanup JS.Linker.Types: add TH types, Env type, DepsLoc JS.Linker: more FIXMEs numerous Linker fixes JS.Linker: removed Text references JS.UnitUtils: add package related helper functions JS.Linker: more DynFlags removal JS.Linker: Time for semantic errors JS.Linker: DynFlags finally removed JS.Linker: 107 compile errors to go JS.Linker.Utils: initialized, adapted to GHC Head JS.Linker.Utils: initialize Utils module JS.Linker.Utils: more utils JS.Rts: move rtsText to Rts JS.Linker: linkerStats implemented JS.Compactor: compiles, adapted to GHC Head JS.Compactor: have to retrofit compact for linker JS.Linker.Compactor: unwinding lenses JS.Linker.Compactor: comments over addItem JS.Linker.Compactor: Lenses removed JS.Linker.Compactor: SHA256 removed JS.Linker.Compactor: only missing instances left JS.Linker.Compactor: compiles JS.Linker: compiles, adapted to ghc Head JS.Linker: More progress JS.Linker: link in memory compiles JS.Linker: just shims left JS.Linker.DynamicLinking compiles: adapted to head JS.Linker.DynamicLinking: initialization JS.Linker.DynamicLinking: compiles up to Variants JS.Variants: initialize JS.Linker: numerous and various fixes JS.Linker.DynamicLinking: only small errors left JS.Linker.Archive: compiles, adapted to GHC Head JS.Linker: initialize Archive compat module JS.Linker.Archive: minor fixes JS.Linker.DynamicLinking: compiles JS.Linker: cleanup, remove Variants, add comments fixup: more cleanup JS.Linker: more cleanup and comments - - - - - 4e236651 by Sylvain Henry at 2022-10-16T18:18:46-04:00 Minor panic fix - - - - - 83ddb29d by Sylvain Henry at 2022-10-16T18:18:46-04:00 Linker: fix stage2 build - - - - - d31d68f0 by Sylvain Henry at 2022-10-16T18:18:47-04:00 Configure: Add support fo JS as unregistered ABI Configure: detect emscripten tools e.g. on ArchLinux: EMSDK=/usr/lib/emscripten EMSDK_LLVM=/opt/emscripten-llvm ./configure --target=js-unknown-ghcjs Configure: detect nm tool too, required by Hadrian Configure: make StgToJS use non-unregisterised ABI It should probably be a third kind of ABI... - - - - - d182986c by doyougnu at 2022-10-16T18:18:47-04:00 JS.Linker: Hook up to GHC.Driver.Pipeline JS.Linker.Types: Add newGhcjsEnv function JS.UnitUtils: fix encodeModule api JS.Linker: more removal of HscEnv JS.Linker: hooked into GHC.Driver.Pipeline - - - - - 6715f6f2 by Sylvain Henry at 2022-10-16T18:20:13-04:00 VERY WIP Hadrian/rts fixes export EMSDK_LLVM=/opt/emscripten-llvm export EMSDK=/usr/lib/emscripten export PATH=./inplace/ghcjs_toolchain/bin:$PATH ./configure --target=js-unknown-ghcjs ./hadrian/build --flavour=quick-js -j --bignum=native --docs=none -V - - - - - f08f0f32 by Sylvain Henry at 2022-10-16T18:21:17-04:00 Force creation of rts library with dummy file - - - - - 34db2722 by Sylvain Henry at 2022-10-16T18:21:21-04:00 ghc-prim: avoid building C files - - - - - eb8e0f62 by Sylvain Henry at 2022-10-16T18:21:21-04:00 Hadrian: disable -fllvm - - - - - f0c87f73 by Sylvain Henry at 2022-10-16T18:21:21-04:00 JS: fix caches Note that the fact that we need index 0 may hide another issue... - - - - - 86943537 by Sylvain Henry at 2022-10-16T18:21:21-04:00 codegen: enhance genCon debug message - - - - - 8478a31c by Sylvain Henry at 2022-10-16T18:21:22-04:00 RTS: fix stupid comment - - - - - 149f74d6 by Sylvain Henry at 2022-10-16T18:21:22-04:00 RTS: embed headers - - - - - 3d3dee8f by Sylvain Henry at 2022-10-16T18:21:22-04:00 JS.StgToJS: add documentation header for JS Types - - - - - dfdaa446 by Sylvain Henry at 2022-10-16T18:21:22-04:00 CodeGen: refactor ExprCtx code - - - - - 17b920ba by Sylvain Henry at 2022-10-16T18:21:22-04:00 CodeGen: cache LNE frame size - - - - - 4161b4a1 by doyougnu at 2022-10-16T18:21:22-04:00 JS.Types: Add Outputable for TypedExpr - - - - - c1aa4ce2 by doyougnu at 2022-10-16T18:21:23-04:00 JS.CoreUtils: handle IOPort case - - - - - 2502af33 by doyougnu at 2022-10-16T18:21:23-04:00 JS.Expr: Fix unhandled datacon for RuntimeRep - - - - - ef25292f by doyougnu at 2022-10-16T18:21:23-04:00 JS.Literals: Adapt genLit to new Literal domain - - - - - ab95e5fc by Sylvain Henry at 2022-10-16T18:21:23-04:00 RTS: expose more headers (required to build base) - - - - - b71213ba by Sylvain Henry at 2022-10-16T18:21:23-04:00 Base: don't build C and Cmm sources with ghcjs - - - - - a5736e2c by Sylvain Henry at 2022-10-16T18:21:24-04:00 Tentatively set NO_REGS for JS platforms - - - - - d9437c3c by Sylvain Henry at 2022-10-16T18:21:24-04:00 CodeGen: output LitRubbish as null JS values - - - - - d401333a by Sylvain Henry at 2022-10-16T18:21:24-04:00 base: disable forkOS and bound thread machinery - - - - - 43d0410f by Sylvain Henry at 2022-10-16T18:21:24-04:00 CodeGen: support StackSnapshot# in primTypeVt - - - - - e3422df5 by Sylvain Henry at 2022-10-16T18:21:24-04:00 CodeGen: better debug message for assignCoerce1 - - - - - a8bd6d23 by Sylvain Henry at 2022-10-16T18:21:25-04:00 Misc: enable HasDebugCallStack for zipWithEqual* - - - - - 11254f30 by Sylvain Henry at 2022-10-16T18:21:25-04:00 CodeGen: remove useless imports - - - - - 7df18064 by Sylvain Henry at 2022-10-16T18:21:25-04:00 Stg: expose pprStgAlt - - - - - e83f5be3 by Sylvain Henry at 2022-10-16T18:21:25-04:00 CodeGen: restore assignAll (instead of assignAllEqual) - - - - - 3330d418 by Sylvain Henry at 2022-10-16T18:21:25-04:00 CodeGen: handle proxy# - - - - - e5a917e7 by doyougnu at 2022-10-16T18:21:26-04:00 ghc-heap: Don't compile Cmm file for JS-Backend - - - - - 46fdd7d0 by doyougnu at 2022-10-16T18:21:26-04:00 Driver.Main: minor refactor do_code_gen To clearly separate the JS-Backend from any other backend - - - - - 48a84962 by Sylvain Henry at 2022-10-16T18:21:26-04:00 Configure: fix echo on Mac, add ghcjs target OS - - - - - 245bde6e by Sylvain Henry at 2022-10-16T18:21:26-04:00 Configure: fix previous commit - - - - - 661abd69 by Luite Stegeman at 2022-10-16T18:21:26-04:00 fix package name in module name field of system dependencies - - - - - 376b551e by Luite Stegeman at 2022-10-16T18:21:27-04:00 fix duplicate module name in symbols - - - - - 5a03af16 by doyougnu at 2022-10-16T18:21:27-04:00 GHCi.FFI: ignore ffi.h and friends for js-backend - - - - - ddca965a by Sylvain Henry at 2022-10-16T18:21:27-04:00 RTS: fix build of native rts - - - - - d14a6e3d by Sylvain Henry at 2022-10-16T18:21:27-04:00 Remove temporary -fjavascript flag - - - - - b264e797 by Sylvain Henry at 2022-10-16T18:21:27-04:00 Codegen: fix symbol names ppr - - - - - 1dd46a7c by Sylvain Henry at 2022-10-16T18:21:28-04:00 Outputable: add ShortText instance - - - - - 28d4e376 by Sylvain Henry at 2022-10-16T18:21:28-04:00 Linker: enhance debugging message - - - - - 328a74db by Sylvain Henry at 2022-10-16T18:21:28-04:00 Remove unused ghcjs unit related code - - - - - d94b3c97 by Sylvain Henry at 2022-10-16T18:21:28-04:00 ghci: Avoid unused-xyz warnings - - - - - f76102f0 by Sylvain Henry at 2022-10-16T18:21:28-04:00 Linker: remove wiring of ghcjs-prim and ghcjs-th They will be replaced by ghc-prim, base, template-haskell, etc. - - - - - 89a66d1a by Sylvain Henry at 2022-10-16T18:21:29-04:00 Add outputable instance for Deps - - - - - 5a26bff4 by doyougnu at 2022-10-16T18:21:29-04:00 Docs: JS.Syntax, JS.Make docs done JS-backend: Add documentation headers Docs: JS.Syntax done Docs: JS.Make done Docs: JS.Make JS.Syntax refined a bit - - - - - 807ad2d9 by Sylvain Henry at 2022-10-16T18:21:29-04:00 Rename u_env into unit_env (more common) - - - - - 6b1a9533 by Sylvain Henry at 2022-10-16T18:21:29-04:00 Linker: deduplication + fixes - deduplicate code that was copied from old GHC - explicitly add preloadUnits to the link - avoid calling getShims - - - - - 437a6b37 by Sylvain Henry at 2022-10-16T18:21:29-04:00 Linker: reenable packStrings (not yet implemented though) - - - - - 032c2992 by Sylvain Henry at 2022-10-16T18:21:30-04:00 ShortText: add singleton - - - - - 8bf562e6 by Sylvain Henry at 2022-10-16T18:21:30-04:00 Linker: force less efficient (but working) static encoding - - - - - 10f5b427 by Luite Stegeman at 2022-10-16T18:21:30-04:00 add GHCJS modules to base package - - - - - ed2d3588 by Sylvain Henry at 2022-10-16T18:21:30-04:00 Linker: remove JS Shims,tiny GHC.Linker refactor - - - - - 43674ddb by doyougnu at 2022-10-16T18:21:30-04:00 Hadrian: QuickJS ways [] --> Set - - - - - a9140f89 by doyougnu at 2022-10-16T18:21:31-04:00 JS-Backend: rebased to master 468f919b First rebase of the JS-Backend. This rebase includes the JS backend combined with !7442 (new backend design). Unfortunately we have to short circuit the new backend design because the JS backend takes over after STG and not after StgToCmm. What's working: - hadrian builds JS backend - JS backend outputs .js files and "links" them What still has to be done: - JS backend is missing core js libraries as we add these we discover bugs in the linker and js rts. - - - - - ce312121 by doyougnu at 2022-10-16T18:21:31-04:00 JS: silence haddock warnings JS Backend: remove misc. warnings - - - - - febcfef4 by doyougnu at 2022-10-16T18:21:31-04:00 JS Backend: ghcjs_HOST_OS --> js_HOST_ARCH - - - - - 406c1264 by Sylvain Henry at 2022-10-16T18:21:31-04:00 JS.Linker: add shims GHCJS uses JS files for primitive things like the GC and RTS. We call these JS files "shims". This sequence of commits adds shims from JS and includes them for linking. In addition the shim directory is controlled via an evironment variable JS_RTS_PATH...at least for now. Linker: implement tryReadShimFile Linker: link with shims provided via an env variable Use JS_RTS_PATH to provide a directory into which .js and .js.pp files will be linked into rts.js JS.Linker: add js dir at root, fix js cpp includes JS.gc.pp: remove variadic macro JS.RTS: add rts JS shims files, remove shim CPP RTS: remove the need for rts.h and add rts JS files rts.h only contained a few constants duplicated in the codegen. Let's use the Haskell version as the single source of truth and pass defined values explicitly to cpp command line ("-DXYZ=abc" arguments). Also switch from "raw" (use_cpp_and_not_cc_dash_E = True) to the opposite: in both case we call "cc -E" (meh), but with False the preprocessor doesn't choke one varargs in macros. RTS: remove integer.js.pp We use the native ghc-bignum backend, so we don't need the GMP compatible JS code. In addition, this code was failing to run as it requires the JSBN (https://www.npmjs.com/package/jsbn) "Javascript big number" library, which we don't necessarily have installed. RTS: fix typo in field name RTS: generate CPP macros in Haskell RTS: share common CPP def into CAFs - - - - - 62117a4e by Sylvain Henry at 2022-10-16T18:21:32-04:00 CPP: disable line markers CPP: move option before input filename (to be squashed) - - - - - bedc8c1a by Sylvain Henry at 2022-10-16T18:21:32-04:00 Linker: add more types Some cleanup Enhance and fix LinkerStats Document and refactor renderLinker Split collectDeps Fix collectDeps Fix linker stats rendering Remove unused seqListSpine It isn't used in ghcjs either - - - - - 84302e8b by Sylvain Henry at 2022-10-16T18:21:32-04:00 Add some missing primops (Word32,Int32) Also fix the rendering of missing primops (they must be z-encoded to avoid having a "#" in their JS name) - - - - - 8715c452 by Sylvain Henry at 2022-10-16T18:21:32-04:00 FFI: desugar every foreign import/export in JS with JS backend It means we also desugar CApi calls into JS. It's probably wrong but instead of generating invalid JS we will only get the failure at runtime when we will use the function. fixup - - - - - 3256d467 by doyougnu at 2022-10-16T18:21:32-04:00 JS.Linker: remove dflags includePath workaround. We implemented a workaround for shims that modified the dynflags includePaths so that the JS backend would find the rts.h file during CPP of shims. Since aebcca98 this is no longer required because we've removed the need for rts.h completely. Thus, this commit reverts that modification. - - - - - 1514c6a8 by Sylvain Henry at 2022-10-16T18:21:33-04:00 Temporarily wire-in base's shim Use JS_BASE_PATH env var to set base's shim directory (js_base for now) Also minor other changes base: fix encoding for JS arch - - - - - 9bca70f5 by Sylvain Henry at 2022-10-16T18:21:33-04:00 Add primops Add primop - - - - - 876ed64b by doyougnu at 2022-10-16T18:21:33-04:00 Make Shims type, refactor JS Linker This commit: - Adds a proper Shim type and associated utilities. These utitlies are purposefully limited to ensure the ShimLbl tag is preserved thus guarenteeing shim ordering at link time. - Refactors the JS backend linker to use this ordering and Shim API. The ordering is not correct (yet!) but with this API its much easier to triage, experiment and diagnose link time issues. Refactor linker to compile time shim ordering - - - - - 832a5f70 by doyougnu at 2022-10-16T18:21:33-04:00 Base: Adapt primitives to JS backend, add base.js - - - - - 3e8abd83 by doyougnu at 2022-10-16T18:21:33-04:00 Base: Remove binding forms in JS ffi - - - - - af93720c by Josh Meredith at 2022-10-16T18:21:34-04:00 Replace GHCJS Objectable with GHC Binary - - - - - 2e1b7fa0 by Sylvain Henry at 2022-10-16T18:21:34-04:00 Binary: remove unused Map instance - - - - - 74971521 by Sylvain Henry at 2022-10-16T18:21:34-04:00 CodeGen: Add export list - - - - - b78a657d by Sylvain Henry at 2022-10-16T18:21:34-04:00 Primops: add some Int64/Word64 primops - - - - - 74fbd756 by Sylvain Henry at 2022-10-16T18:21:35-04:00 base: fix one ffi import - - - - - dcba1a41 by doyougnu at 2022-10-16T18:21:35-04:00 base: CPP for JS-backend, adapt write in base shim This commit ports over each CPP directive from GHCJS to base. In addition, it adds struct.js.pp to Base shim directory and modifies h$base_write to always take 6 arguments. Thereby avoiding errors such as "c(bytesWritten) is not a function". The missing parameter was the file descriptor object, fdo, which was looked up in the function itself and is now passed through to comport with the FFI expectations. - - - - - 9470a026 by doyougnu at 2022-10-16T18:21:35-04:00 fixup: remove redundant struct.js.pp in js_base - - - - - c60a9588 by doyougnu at 2022-10-16T18:21:35-04:00 JS.Linker: enable linker RTS symbols - - - - - 6c15dd3e by doyougnu at 2022-10-16T18:21:35-04:00 base.GHCJS: adapt Prim to direct call FFI format - - - - - dfcf1b03 by doyougnu at 2022-10-16T18:21:36-04:00 Linker: Load JSVal from base not ghc-prim - - - - - 779ae1dc by doyougnu at 2022-10-16T18:21:36-04:00 fixup: caught one more reference to JSVal in prim - - - - - 952bd629 by Sylvain Henry at 2022-10-16T18:21:36-04:00 base: match on js arch , not ghcjs os - - - - - 40829546 by Sylvain Henry at 2022-10-16T18:21:36-04:00 Fix MK_JSVAL - - - - - ec0e53dd by doyougnu at 2022-10-16T18:21:36-04:00 Prim: cleanup comments - - - - - 777be65c by doyougnu at 2022-10-16T18:21:36-04:00 JS.Prim: add Int64 PrimOps - - - - - cfeb6859 by Sylvain Henry at 2022-10-16T18:21:37-04:00 Vendor MD5 lib - - - - - 8cdd8d78 by Sylvain Henry at 2022-10-16T18:21:37-04:00 More 64-bit primops - - - - - 24241365 by Sylvain Henry at 2022-10-16T18:21:37-04:00 CodeGen: use if10 helper - - - - - 6ee095d5 by Sylvain Henry at 2022-10-16T18:21:37-04:00 Ppr: fix selector to avoid adding a newline - - - - - 1ccf32e9 by doyougnu at 2022-10-16T18:21:37-04:00 base: GHCJS.Prim make ffi imports use anon funcs - - - - - a65f243e by Sylvain Henry at 2022-10-16T18:21:38-04:00 Linker: disable invalid constructors again - - - - - ce3b3cbf by Sylvain Henry at 2022-10-16T18:21:38-04:00 More 64-bits primops - - - - - 6860b03e by Sylvain Henry at 2022-10-16T18:21:38-04:00 Fix base_write function - - - - - 8607afd0 by Sylvain Henry at 2022-10-16T18:21:38-04:00 Fix base_write for 32-bit size_t - - - - - e87f2a3c by Sylvain Henry at 2022-10-16T18:21:38-04:00 Configure: fix detection of the target toolchain - - - - - cd89532a by Sylvain Henry at 2022-10-16T18:21:39-04:00 Remove js_base directory - - - - - b72f9498 by Sylvain Henry at 2022-10-16T18:21:39-04:00 Kill Node when the main loop reports an unhandled exception - - - - - 9e412804 by Sylvain Henry at 2022-10-16T18:21:39-04:00 CodeGen: preparation to make match on primops complete - - - - - 5414fe7d by Sylvain Henry at 2022-10-16T18:21:39-04:00 Primops: fix Compact primops - - - - - 476b1adb by Sylvain Henry at 2022-10-16T18:21:39-04:00 Ignore result arity for some exception primops - - - - - a30c0776 by Sylvain Henry at 2022-10-16T18:21:40-04:00 Fix more primops. Bump array submodule! - - - - - 7bf62853 by Sylvain Henry at 2022-10-16T18:21:40-04:00 Compact: fix return of 3 values - - - - - 35a179b8 by Sylvain Henry at 2022-10-16T18:21:40-04:00 Configure: switch to absolute path - - - - - 29b504bf by Sylvain Henry at 2022-10-16T18:21:40-04:00 Add a few primops - - - - - 7af450bc by Sylvain Henry at 2022-10-16T18:21:40-04:00 Primop: implement WordAdd2 - - - - - 9bdc0735 by Luite Stegeman at 2022-10-16T18:21:40-04:00 quick fix for uTypeVt and typePrimRep panics this may cause other panics, a full fix will require a bit more rework and probably removal of VarType - - - - - b36d7df3 by Josh Meredith at 2022-10-16T18:21:41-04:00 Replace ShortText with (Lexical)FastString in GHCJS backend - - - - - 59e648ee by Sylvain Henry at 2022-10-16T18:21:41-04:00 Primops: add arithmetic ops Primops: add decodeDoubleInt64 back Primop: added timesInt2# Primop: add mulWord32 and mul2Word32 - - - - - 4983b5d5 by Sylvain Henry at 2022-10-16T18:21:41-04:00 Reduce dependency on goog - - - - - 6b4ca19d by Sylvain Henry at 2022-10-16T18:21:41-04:00 Primop: implement quotWord32, remWord32, and quotRemWord32 - - - - - e83117f4 by Sylvain Henry at 2022-10-16T18:21:42-04:00 Primop: Implement quotRem2Word32, misc fixes Primop: implement quotRem2Word32 Primop: fix timesInt2# Primop: fix some shifting primops - - - - - bb1c1c29 by Sylvain Henry at 2022-10-16T18:21:42-04:00 Fix bug in upd_frame I've introduced this bug when I've refactored the code to use helpers to assign closures. - - - - - 7a4f1de9 by Sylvain Henry at 2022-10-16T18:21:42-04:00 Primop: throw an exception for unimplemented primops - - - - - abe014a9 by Sylvain Henry at 2022-10-16T18:21:42-04:00 Primop: fix remWord32 - - - - - d572ca98 by Josh Meredith at 2022-10-16T18:21:42-04:00 Configure: add EMSDK_BIN, match emsdk expectations Change EMSDK vars to match emscripten/emsdk_env.sh definitions Add EMSDK_BIN environment variable to configure - - - - - 930ea3f8 by Sylvain Henry at 2022-10-16T18:21:43-04:00 resultSize: correctly handle Void# - - - - - aec6ae42 by Sylvain Henry at 2022-10-16T18:21:43-04:00 Primop: fix Sized test, more shifting fixes Primop: ensure that we return u32 values for word primops Also a refactoring from i3 to i32 for clarity. Primop: add/fix more shifting primops Primops: fix Sized test! - - - - - 02d9bbaa by Sylvain Henry at 2022-10-16T18:21:43-04:00 StgToJS.Apply: Docs Doc Doc - - - - - ee48010b by Josh Meredith at 2022-10-16T18:21:43-04:00 Fix EMSDK configure condition - - - - - bd74db6f by doyougnu at 2022-10-16T18:21:43-04:00 StgToJS.Arg: Unboxable Literal Optimization note - - - - - b3f739f9 by Sylvain Henry at 2022-10-16T18:21:44-04:00 Fix Outputable instances for JExpr/JVal - Put orphan instances in JS.Ppr - Also fix some redundant imports - - - - - 58d39cd4 by doyougnu at 2022-10-16T18:21:44-04:00 configure: avoid CXX stdlib check for js backend and some cleanup for a previously mis-applied commit during rebasing - - - - - 3f0f7567 by doyougnu at 2022-10-16T18:21:44-04:00 fixup: misc. fixes post rebase - - - - - 401a8dc8 by Sylvain Henry at 2022-10-16T18:21:44-04:00 PrimOps: add more 64-bit primops PrimOp: implement more 64-bit primops + PM fix Ensure that we cover every primop explicitly - - - - - e7f69bc8 by Sylvain Henry at 2022-10-16T18:21:44-04:00 PrimOp: correclty (un)handle new thread related primops - - - - - c297c3a1 by Sylvain Henry at 2022-10-16T18:21:45-04:00 PrimOp: disable LabelThreadOp for now - - - - - 8848b86d by Sylvain Henry at 2022-10-16T18:21:45-04:00 Minor doc/cleanup Fix more redundant imports - - - - - 58cd2b3c by doyougnu at 2022-10-16T18:21:45-04:00 base: GHCJS.Prim directory --> GHC.JS.Prim - - - - - b18154be by Luite Stegeman at 2022-10-16T18:21:45-04:00 implement KeepAlive primop - - - - - c937ff33 by Sylvain Henry at 2022-10-16T18:21:45-04:00 Remove orphan instance for StaticArg - - - - - 0ea44ad8 by Sylvain Henry at 2022-10-16T18:21:46-04:00 Remove redundant jsIdIdent' function - - - - - e41d597d by Sylvain Henry at 2022-10-16T18:21:46-04:00 Split StgToJS.Monad into StgToJS.{Monad,Ids,Stack} - - - - - af8df178 by Sylvain Henry at 2022-10-16T18:21:46-04:00 Apply: remove commented case (wasn't optimized either in latest ghcjs) - - - - - 8ba39cbe by Sylvain Henry at 2022-10-16T18:21:46-04:00 Doc: Apply Apply: doc and refactoring - use new types instead of Bool/Int - factorize some code - - - - - bc47ba4d by Sylvain Henry at 2022-10-16T18:21:47-04:00 Primop: arith fixes Primop: fix 64-bit shifting primops + add some traces Primop: fix quotRem2Word32 Primop: fix timesInt2. Progress towards passing arith003 PrimOp: fix timesInt32 PrimOp: use mulWord32 when appropriate - - - - - 09e3bf6f by doyougnu at 2022-10-16T18:21:47-04:00 Configure: remove EMSDK hacks and wrapper scripts configure JS: remove wrapper scripts Configure: remove EMSDK hacks. Use emconfigure instead emconfigure ./configure --target=js-unknown-ghcjs - - - - - fb7bfb07 by Sylvain Henry at 2022-10-16T18:21:47-04:00 GHCJS.Prim leftovers - - - - - 0177103e by Sylvain Henry at 2022-10-16T18:21:47-04:00 Linker: fix linking issue for tuples - - - - - 9c3f7e61 by Sylvain Henry at 2022-10-16T18:21:47-04:00 FFI: remove narrowing Fix tests such as cgrun015 (Core lint error) - - - - - 6b2fc8b2 by Sylvain Henry at 2022-10-16T18:21:48-04:00 Linker: disable logs with default verbosity - - - - - 6c7f2cc5 by Sylvain Henry at 2022-10-16T18:21:48-04:00 Append program name in top-level exception handler - - - - - 47bd8795 by doyougnu at 2022-10-16T18:21:48-04:00 GHC.JS: Remove FIXMEs JS.Syntax: Remove FIXMEs JS.Make: remove FIXMEs JS.Ppr/Transform: Remove FIXMEs - - - - - 39df9a34 by Sylvain Henry at 2022-10-16T18:21:48-04:00 Primop: fix timesInt2# Pass arith003 test - - - - - f20b1166 by doyougnu at 2022-10-16T18:21:48-04:00 JS.Linker.Linker: remove FIXMEs, clean dead code - - - - - c4718510 by Sylvain Henry at 2022-10-16T18:21:49-04:00 Linker: link platform shim before the others - - - - - 78f6417a by Sylvain Henry at 2022-10-16T18:21:49-04:00 Primops: rework 64-bit and Word32 primops - Use BigInt instead of complex and buggy bit twiddling. We'll assess performance later. Let's use a correct and simple implementation for now. - Implement previously missing 64-bit quot and rem - Refactor logical operators and Prim module more generally - - - - - 82f2231a by Sylvain Henry at 2022-10-16T18:21:49-04:00 PrimOp: fixup previous commit... - - - - - d4816913 by Sylvain Henry at 2022-10-16T18:21:49-04:00 Primop: fixup previous commit - - - - - f4473a2f by Sylvain Henry at 2022-10-16T18:21:49-04:00 Doc: minor changes - - - - - 8eca93c7 by Sylvain Henry at 2022-10-16T18:21:50-04:00 Add debug option to watch for insertion of undefined/null in the stack - - - - - 75ae445b by Sylvain Henry at 2022-10-16T18:21:50-04:00 Apply: fix tag generation - - - - - 16c4d125 by Sylvain Henry at 2022-10-16T18:21:50-04:00 Remove redundant import - - - - - bf9eaa90 by Sylvain Henry at 2022-10-16T18:21:50-04:00 Testsuite: disable Cmm tests with the JS backend - - - - - 352d5c04 by Sylvain Henry at 2022-10-16T18:21:50-04:00 Base: fix c_interruptible_open - - - - - ff60c1d2 by Sylvain Henry at 2022-10-16T18:21:50-04:00 Base: fix typo in long_from_number - - - - - e3329bd0 by Sylvain Henry at 2022-10-16T18:21:51-04:00 Env: only add program name to errors, not to traces - - - - - dedfa5fa by Sylvain Henry at 2022-10-16T18:21:51-04:00 Testsuite: disable more Cmm tests - - - - - ef04a471 by doyougnu at 2022-10-16T18:21:51-04:00 JS.Linker: removes FIXMEs JS.Linker.Linker: remove FIXMEs, clean dead code StgToJS.Linker.Utils: remove FIXMEs Compactor: Remove FIXMEs StgToJS.Linker.Types: Remove FIXMEs JS.Linker.Archive/Dynamic: remove FIXMEs StgToJS.Linker.Shims: remove FIXMEs - - - - - 986b299e by doyougnu at 2022-10-16T18:21:51-04:00 JS RTS: remove FIXMEs StgToJS.Rts.Types: Remove FIXMEs - - - - - 5b28e80d by Sylvain Henry at 2022-10-16T18:21:52-04:00 Primop: fix bswap32/64 (cf cgrun072) - - - - - 06e69e51 by Sylvain Henry at 2022-10-16T18:21:52-04:00 Testsuite: normalise ghc program name - - - - - dd114d04 by doyougnu at 2022-10-16T18:21:52-04:00 JS Backend: Remove FIXMEs StgToJS.Apply: Remove FIXMEs StgToJS.FFI: remove FIXMEs StgToJS.Expr: remove FIXMEs StgToJS: Remove FIXMEs - - - - - aa05fd97 by Sylvain Henry at 2022-10-16T18:21:52-04:00 Enable RTS args filtering (cf cgrun025) - - - - - f0e27ead by Sylvain Henry at 2022-10-16T18:21:52-04:00 Remove trailing whitespaces (whitespace test) - - - - - dc912771 by Sylvain Henry at 2022-10-16T18:21:53-04:00 Testsuite: remove platform prefix for unlit tool - - - - - c0e1a0f0 by Sylvain Henry at 2022-10-16T18:21:53-04:00 Primop: fix Int64 conversion/negate (integerConversions test) - - - - - cd641da8 by Sylvain Henry at 2022-10-16T18:21:53-04:00 Linker: remove message with default verbosity - - - - - 769aace4 by Sylvain Henry at 2022-10-16T18:21:53-04:00 Testsuite: normalise .jsexe suffix - - - - - ebdf068c by Sylvain Henry at 2022-10-16T18:21:53-04:00 Remove warning about orphan instance - - - - - 6180e20b by Sylvain Henry at 2022-10-16T18:21:54-04:00 Compactor: disable dead code - - - - - b7b99ae9 by Sylvain Henry at 2022-10-16T18:21:54-04:00 Exception: implement raiseUnderflow etc. as primops - - - - - 24530d44 by Sylvain Henry at 2022-10-16T18:21:54-04:00 Primop: fix Int8/18 quot/rem - - - - - 0d66bf2b by Sylvain Henry at 2022-10-16T18:21:54-04:00 Linker: refactor wired-in deps - - - - - 0bd95fc1 by Sylvain Henry at 2022-10-16T18:21:54-04:00 Ppr: remove useless left padding for functions in JS dumps - - - - - 0a1e1cdf by Josh Meredith at 2022-10-16T18:21:55-04:00 Disable llvm ways and ghci for JS backend testsuite - - - - - 7de0ccf2 by Sylvain Henry at 2022-10-16T18:21:55-04:00 StaticPtr: don't generate CStubs for the JS backend - - - - - daaa27a4 by Sylvain Henry at 2022-10-16T18:21:55-04:00 StaticPtr: fix hs_spt_lookup after upstream change - - - - - 14437b98 by Sylvain Henry at 2022-10-16T18:21:55-04:00 Testsuite: fix normalisation for unlit T8430 shows: `js-unknown-ghcjs-unlit' failed in phase `Literate pre-processor'. (Exit code: 1) Notice the quote around the program name. So I've made the regex match more cases (i.e. not only lines starting with the program name). - - - - - 8a53ab48 by Sylvain Henry at 2022-10-16T18:21:55-04:00 Codegen: fix codegen of string literals Due to FastString change: Before: Text.pack . BSC.unpack After: mkFastString . BSC.unpack It seems that Text handles buggy multi-byte codepoints split into several String Chars. - - - - - a62bdbaa by Sylvain Henry at 2022-10-16T18:21:56-04:00 CPP: fix LINE markers. Only disable them for JS - - - - - fc900ce1 by Luite Stegeman at 2022-10-16T18:21:56-04:00 add JavaScript files listed in js-sources to package archives - - - - - eac08f5b by Luite Stegeman at 2022-10-16T18:21:56-04:00 update rts js files to include recent fixes - - - - - 96d54574 by Luite Stegeman at 2022-10-16T18:21:56-04:00 fix definitions in js/rts.h - - - - - ad6615d3 by Josh Meredith at 2022-10-16T18:21:57-04:00 stopgap fix for missing ghc-pkg in cross-compiler tests - - - - - 22f50303 by Sylvain Henry at 2022-10-16T18:21:57-04:00 Testsuite: better fix for finding prefixed tools - - - - - 71135267 by Sylvain Henry at 2022-10-16T18:21:57-04:00 Ppr: add hangBrace helper - - - - - 45be6c87 by Sylvain Henry at 2022-10-16T18:21:57-04:00 Only declare ccs var in profiling mode - - - - - baa11726 by Sylvain Henry at 2022-10-16T18:21:57-04:00 Don't consider recursive bindings as inline nor as evaluated Fix mdo001 - - - - - 66a6f780 by Sylvain Henry at 2022-10-16T18:21:57-04:00 Hadrian: disable shared libs for JS target - - - - - 07a7a66f by Sylvain Henry at 2022-10-16T18:21:58-04:00 Support -ddump-stg-final with the JS backend - - - - - 201d4e27 by Sylvain Henry at 2022-10-16T18:21:58-04:00 Add ticky_ghc0 flavour transformer to ticky stage1 - - - - - b2176a2e by Sylvain Henry at 2022-10-16T18:21:58-04:00 Don't read object file when -ddump-js isn't passed - - - - - 48cde7e6 by Sylvain Henry at 2022-10-16T18:21:58-04:00 Object: remove dead code + renaming - - - - - f0bdbfed by Sylvain Henry at 2022-10-16T18:21:58-04:00 Object: replace SymbolTableR with Dictionary - - - - - 32929f9b by Sylvain Henry at 2022-10-16T18:21:59-04:00 Object: refactoring - - - - - c21ea283 by Sylvain Henry at 2022-10-16T18:21:59-04:00 RTS: link platform.js before the others! - - - - - 477fe776 by Sylvain Henry at 2022-10-16T18:21:59-04:00 Hadrian: treat JS objects similarly to other objects - - - - - 9c28e74d by Luite Stegeman at 2022-10-16T18:21:59-04:00 fix javascript FFI calls for read and write - - - - - 2b818fcb by doyougnu at 2022-10-16T18:21:59-04:00 propagate ppr code changes to JS backend - - - - - f7c5f4b7 by Sylvain Henry at 2022-10-16T18:22:00-04:00 Switch from Data.Binary and ByteString to BinHandle - - - - - 3d8b5d9b by Sylvain Henry at 2022-10-16T18:22:00-04:00 Perf: use Ppr's LeftMode to output JS - - - - - 7525313b by doyougnu at 2022-10-16T18:22:00-04:00 Primops: Add {Index,Write,Read}ByteArrayAs ops Still need to check for correctness based on T4442. minor doc fixes fixup: add some Index..As primops fixup missed type signature Primops: Add WriteByteArrayOp_Word8AsFoo ops Primops: {Index,Read,Write}FooAsBar done except Addr's Primops: add {Index,Read,Write}ByteArrayAsAddr ops These will need to be tested for correctness with T4442.hs - - - - - ef6ced26 by Sylvain Henry at 2022-10-16T18:22:00-04:00 Move platform.js to base (it must be linked first) - - - - - 674af34e by Sylvain Henry at 2022-10-16T18:22:00-04:00 Remove old shim directory - - - - - 3ca531a3 by doyougnu at 2022-10-16T18:22:01-04:00 JS.Prim: more PrimOps {IndexByteArrayAs, CAS} Primop: WriteByteArrayOp_Word8AsChar use setInt8 Primops: remove dv_s_u8 This function is non-sensical. Due to the infelicities of JS as a platform we must use Int8 and friends to write, then coerce to a word, thus dv_s_iN are the only legal calls for a write, and dv_s_uN legal for Index and Reads. Primops: set dv_u8 to correct method call should be getUint8, not getUInt8, of course the naming convention changes ever so slightly for Words. Primops: T4442 finishes ByteArrayAs still fails JS.Prim: More IndexByteAAs primops JS.Prim: Prefetch PrimOps are noOps JS.Primops: Doc explaining lack of vector support JS.Prim: add CAS and Fetch Ops - - - - - 805e9ac7 by doyougnu at 2022-10-16T18:22:01-04:00 GHC.Utils.Binary: BinDictionary -> FSTable Rename to avoid naming conflict with haddock. - - - - - ef720bf6 by Josh Meredith at 2022-10-16T18:22:01-04:00 Adjust derefnull test exit code for ghcjs - - - - - 7de30bd4 by doyougnu at 2022-10-16T18:22:01-04:00 Fix Driver missing type signature warnings - - - - - aec9044b by doyougnu at 2022-10-16T18:22:01-04:00 PipeLine.Execute: silence warnings on JS backend - - - - - e0fb8da6 by doyougnu at 2022-10-16T18:22:02-04:00 JS.Primops: Add Bit reverse ops - - - - - 6ffe6c29 by doyougnu at 2022-10-16T18:22:02-04:00 SysTools.Tasks: quiet non-totality warnings - - - - - 74c47475 by doyougnu at 2022-10-16T18:22:02-04:00 JS.Primops: Add InterlockedExchange Addr Word - - - - - 260119c2 by Sylvain Henry at 2022-10-16T18:22:02-04:00 base: conditional js-sources - - - - - bc7c028a by Sylvain Henry at 2022-10-16T18:22:02-04:00 TH: add support for JS files - - - - - 877b163e by Sylvain Henry at 2022-10-16T18:22:03-04:00 Linker: fix creation of directories in output paths - - - - - c9aeee21 by Sylvain Henry at 2022-10-16T18:22:03-04:00 Backpack: fix empty stubs - - - - - aa8c9b92 by Sylvain Henry at 2022-10-16T18:22:03-04:00 Add encodeDouble/Float RTS functions - - - - - f9d27885 by Sylvain Henry at 2022-10-16T18:22:03-04:00 encodeDouble: correctly handle 0 base - - - - - 4a6a69a8 by doyougnu at 2022-10-16T18:22:03-04:00 JS.Primops: Add listThreads op - - - - - 46782b3f by doyougnu at 2022-10-16T18:22:04-04:00 JS.Primops: Add Read/WriteAddrOp ops - - - - - f1faa5df by doyougnu at 2022-10-16T18:22:04-04:00 JS: Linker and Compactor: cleanup and docs Compactor: Cleanup: Remove dead comments JS.Linker.Types: cleanup and document module - - - - - bbc80342 by doyougnu at 2022-10-16T18:22:04-04:00 StgToJS.Linker: Add docs to utility modules StgToJS.Linker.Utils: more docs StgToJS.Linker.Archive: more docs - - - - - 85eab631 by doyougnu at 2022-10-16T18:22:04-04:00 StgToJS.Object: Add documentation - - - - - 3d44bfc8 by Sylvain Henry at 2022-10-16T18:22:04-04:00 Refactor Expr - - - - - 6eab0a16 by Sylvain Henry at 2022-10-16T18:22:05-04:00 Object: reduce pinned allocation. And don't forget to hClose invalid objects - - - - - 31386e6d by Sylvain Henry at 2022-10-16T18:22:05-04:00 Fix pdep (cgrun075) - - - - - b8303439 by Sylvain Henry at 2022-10-16T18:22:05-04:00 Fix error message (don't mention emscripten) - - - - - 74c69a21 by Sylvain Henry at 2022-10-16T18:22:05-04:00 Add Float/Word casts - - - - - 2133424d by Sylvain Henry at 2022-10-16T18:22:05-04:00 Disable HPC tests with JS backend - - - - - a243f8b7 by Sylvain Henry at 2022-10-16T18:22:06-04:00 Fix encodeDouble/Float - - - - - dcd26797 by Sylvain Henry at 2022-10-16T18:22:06-04:00 Implement putchar (fix cgrun015) - - - - - 850d558b by Sylvain Henry at 2022-10-16T18:22:06-04:00 Fix decoding of denormalized floats - - - - - 83399730 by Sylvain Henry at 2022-10-16T18:22:06-04:00 Fix isFloatDenormalized function - - - - - ba3b200c by Sylvain Henry at 2022-10-16T18:22:06-04:00 Reuse convert buffer - - - - - 8f6cd127 by Sylvain Henry at 2022-10-16T18:22:07-04:00 Reuse convert buffer bis - - - - - e597c475 by Sylvain Henry at 2022-10-16T18:22:07-04:00 Skip some tests that require the dynamic linker - - - - - 69d676d0 by Josh Meredith at 2022-10-16T18:22:07-04:00 JavaScript ShrinkSmallMutableArrayOp_Char & GetSizeofSmallMutableArrayOp - - - - - 7eb8de07 by Sylvain Henry at 2022-10-16T18:22:07-04:00 Disable more linker tests - - - - - db0ac187 by Sylvain Henry at 2022-10-16T18:22:07-04:00 Testsuite: better normalisation for ghc and ghc-pkg Allow normalisation for ghc and ghc-pkg anywhere in the output, not just at the beginning of the line. Fix T1750 and ghcpkg05 for example - - - - - 95381257 by Sylvain Henry at 2022-10-16T18:22:08-04:00 Skip T14373 because it requires Cmm - - - - - 4ad47321 by Sylvain Henry at 2022-10-16T18:22:08-04:00 Disable cg010 with JS backend - - - - - c0606904 by Sylvain Henry at 2022-10-16T18:22:08-04:00 Testsuite: better normalisation of .jsexe extension - - - - - c33fc565 by doyougnu at 2022-10-16T18:22:08-04:00 JS: Linker,Rts docs and cleanup JS.Linker: Cleanup: remove unused functions/types JS.Rts.Types: remove dead code, docs StgToJS.RTS: cleanup and more docs - - - - - 386fca79 by Sylvain Henry at 2022-10-16T18:22:08-04:00 Disable recomp015 - - - - - b07157f3 by Sylvain Henry at 2022-10-16T18:22:09-04:00 Minor refactoring - - - - - 52d5d857 by Sylvain Henry at 2022-10-16T18:22:09-04:00 Temporary fix the testsuite bug - - - - - a82e2003 by doyougnu at 2022-10-16T18:22:09-04:00 JS.StgToJS.Types: Docs and cleanup - - - - - 08cf300a by Josh Meredith at 2022-10-16T18:22:09-04:00 change JS.Transform.Idents* to use UniqDSet from Set - - - - - 5909304b by Sylvain Henry at 2022-10-16T18:22:09-04:00 Minor Linker cleanup Minor cleanup - - - - - 8e98f7ef by Sylvain Henry at 2022-10-16T18:22:10-04:00 Linker: load all the dependent units transitively - - - - - 0fc0688d by doyougnu at 2022-10-16T18:22:10-04:00 JS: Add Docs and cleanup StgToJS.{Arg,Ids} JS.Arg: docs and cleanup StgToJS.Arg: add minimal docs StgToJS.Ids: Add header - - - - - 6fc6866d by Sylvain Henry at 2022-10-16T18:22:10-04:00 Implement h$sleep (T5611) - - - - - 696a0f79 by Sylvain Henry at 2022-10-16T18:22:10-04:00 Linker: don't link the same unit twice - - - - - ca9c5e97 by doyougnu at 2022-10-16T18:22:10-04:00 JS: docs, cleanup, StgToJS.{Expr,DataCon,Stack} StgToJS.Deps/Expr: add docs StgToJS.DataCon: add minor docs StgToJS.Stack: Docs and cleanup In particular: -- Removing some single use functions -- Some minor refactors related to these removals StgToJS: comments on static args and optimizeFree - - - - - 0c35aa4d by Sylvain Henry at 2022-10-16T18:22:11-04:00 Disable compact tests - - - - - c170d2a6 by Sylvain Henry at 2022-10-16T18:22:11-04:00 Add support for JS files passed on the command line - - - - - 8e9ea0db by Sylvain Henry at 2022-10-16T18:22:11-04:00 Minor cleanup in compactor - - - - - ffb33fd4 by Sylvain Henry at 2022-10-16T18:22:11-04:00 Fix encoding of unboxed strings (don't pass through FastString/h$str) - - - - - c5257bb7 by doyougnu at 2022-10-16T18:22:11-04:00 JS: Misc fixes post Del-Cont rebase - - - - - 22c98b1a by Sylvain Henry at 2022-10-16T18:22:12-04:00 Minor cleanup - - - - - 4a700d87 by Sylvain Henry at 2022-10-16T18:22:12-04:00 Add log1p and expm1 (fix cgrun078) - - - - - ae835a0b by Sylvain Henry at 2022-10-16T18:22:12-04:00 Assume existence of Math.fround and use it in Float's primops - - - - - ae5ea656 by Sylvain Henry at 2022-10-16T18:22:12-04:00 Disable "debug" test - - - - - a0619797 by Sylvain Henry at 2022-10-16T18:22:12-04:00 Implement copyMutableArray with overlap support - - - - - 86d841c0 by Sylvain Henry at 2022-10-16T18:22:13-04:00 Skip CmmSwitchTests - - - - - a99ca296 by Sylvain Henry at 2022-10-16T18:22:13-04:00 Fix WordToDouble/WordToFloat (Word2Float32 test) - - - - - c3beb69e by Sylvain Henry at 2022-10-16T18:22:13-04:00 Skip one more test - - - - - f9f6c23f by Sylvain Henry at 2022-10-16T18:22:13-04:00 Fix after GHC.Tuple to GHC.Tuple.Prim - - - - - 1d0656fb by Sylvain Henry at 2022-10-16T18:22:13-04:00 Fix InterlockedExchange primops (cgrun080) - - - - - 847ddd69 by Sylvain Henry at 2022-10-16T18:22:14-04:00 Disable T12059 - - - - - 70839cbc by Sylvain Henry at 2022-10-16T18:22:14-04:00 Implement sqrt/sqrtf (fix T14619) - - - - - 67ec5f28 by Sylvain Henry at 2022-10-16T18:22:14-04:00 Skip more tests - - - - - 340fbe87 by Sylvain Henry at 2022-10-16T18:22:14-04:00 Disable conc012 - - - - - d65c4ebb by Sylvain Henry at 2022-10-16T18:22:14-04:00 Disable more Cmm tests - - - - - 98d884f9 by Sylvain Henry at 2022-10-16T18:22:15-04:00 Fix AtomicPrimops test. Some refactoring in Prim too - - - - - dc57858f by Sylvain Henry at 2022-10-16T18:22:15-04:00 Use GHCJS's signExtend/narrow - - - - - 899f51af by Josh Meredith at 2022-10-16T18:22:15-04:00 Implement get/set thread label prims - - - - - 72048483 by doyougnu at 2022-10-16T18:22:15-04:00 JS: remove Linker.Archive module - - - - - ddaf4f8d by Sylvain Henry at 2022-10-16T18:22:15-04:00 Start disabling tests that use TH/interpreter - - - - - cf789c31 by Josh Meredith at 2022-10-16T18:22:16-04:00 Add flagged bounds checking to JS primops - - - - - 7f3b8e73 by Sylvain Henry at 2022-10-16T18:27:26-04:00 Disable more tests - - - - - 254dee56 by Sylvain Henry at 2022-10-16T18:27:29-04:00 Disable T1791 - - - - - e6f424d5 by Sylvain Henry at 2022-10-16T18:27:29-04:00 Raise NonTermination as an async exception - - - - - de5bc565 by Sylvain Henry at 2022-10-16T18:27:30-04:00 Expect IOPort test to be broken - - - - - b35a93b3 by Sylvain Henry at 2022-10-16T18:27:30-04:00 Implement rts_isThreaded (fix jules_xref2) - - - - - caaa1851 by Sylvain Henry at 2022-10-16T18:27:30-04:00 Disable outofmem2 test - - - - - d7b9f7df by Sylvain Henry at 2022-10-16T18:27:30-04:00 Disable tests using C files - - - - - 43d206ab by Sylvain Henry at 2022-10-16T18:27:30-04:00 Disable delimited continuation tests - - - - - a69ced57 by Sylvain Henry at 2022-10-16T18:27:31-04:00 Disable native RTS flag tests - - - - - 4a2ec8a7 by Sylvain Henry at 2022-10-16T18:27:31-04:00 Disable more tests - - - - - a11da0c6 by Sylvain Henry at 2022-10-16T18:27:31-04:00 Disable more tests - - - - - 4e0f259b by Sylvain Henry at 2022-10-16T18:27:31-04:00 Annotation tests require an interpreter - - - - - fe07e1ca by Sylvain Henry at 2022-10-16T18:27:31-04:00 Skip more tests - - - - - 5877574b by Sylvain Henry at 2022-10-16T18:27:32-04:00 Disable try_putmvar tests that use C files - - - - - 9f33cd31 by Sylvain Henry at 2022-10-16T18:27:32-04:00 Disable even more tests - - - - - 348ab202 by Sylvain Henry at 2022-10-16T18:27:32-04:00 Disable test using Cmm - - - - - 7c01ae4b by Sylvain Henry at 2022-10-16T18:27:32-04:00 Linker: remove dead code (base, compactor) - - - - - 9c9aad7a by Sylvain Henry at 2022-10-16T18:27:32-04:00 Better shims linking - - - - - 4792a781 by Sylvain Henry at 2022-10-16T18:27:32-04:00 Make isJsFile a bit faster by only reading the header - - - - - 3c39400d by Sylvain Henry at 2022-10-16T18:27:33-04:00 Linker: write directly into output file - - - - - a569bbff by Sylvain Henry at 2022-10-16T18:27:33-04:00 Linker: more refactoring - - - - - 49c235ce by Sylvain Henry at 2022-10-16T18:27:33-04:00 Lazy loading of JStat in object code - - - - - 539de1dc by Sylvain Henry at 2022-10-16T18:27:33-04:00 Use Ppr hack to render directly into a file - - - - - 04f36477 by Sylvain Henry at 2022-10-16T18:27:33-04:00 Fix backpack dependencies - - - - - eaa19192 by doyougnu at 2022-10-16T18:27:34-04:00 testsuite: add js_skip_csources function Used to indicate a test that fails in the JS backend because the JS Backend does not yet support c-sources in cabal files. - - - - - 3940618e by doyougnu at 2022-10-16T18:27:34-04:00 testsuite: JS: skip tests which use c-sources Skip because these tests use c-sources and the JS backend does not yet support including c-sources testsuite: JS backend: skip backpack tests testsuite: JS: skip c-sources ffi tests testsuite: JS: skip multipleHomeUnits_odir testsuite: JS: disable more backpack tests testsuite: JS: disable c-sources rts tests testsuite: JS: skip c-sources codeGen tests testsuite: JS: skip c-sources generics test - - - - - 49f6ffb3 by Josh Meredith at 2022-10-16T18:27:34-04:00 use exit code 134 for JS prim bounds checks - - - - - 24a28e6b by Sylvain Henry at 2022-10-16T18:27:34-04:00 Remove panic in getObject - - - - - 3f6f2735 by Sylvain Henry at 2022-10-16T18:27:34-04:00 Add debug and Outputable instances - - - - - 35399b81 by Sylvain Henry at 2022-10-16T18:27:35-04:00 Remove backup file - - - - - f67870f6 by Sylvain Henry at 2022-10-16T18:27:35-04:00 Skip overflow tests - - - - - a14761dd by Sylvain Henry at 2022-10-16T18:27:35-04:00 Fix RTS includes for native build - - - - - a95b6e28 by Sylvain Henry at 2022-10-16T18:27:35-04:00 Doc - - - - - 496bab91 by Sylvain Henry at 2022-10-16T18:27:35-04:00 Add perf-js Hadrian flavour - - - - - e9584805 by doyougnu at 2022-10-16T18:27:36-04:00 JS.Syntax: fix doc wording - - - - - 11956b43 by doyougnu at 2022-10-16T18:27:36-04:00 Driver: JS: tweak error message - - - - - 7c94c8d8 by Josh Meredith at 2022-10-16T18:27:36-04:00 Factor JS platform constants and h$programArgs/h$rtsArgs into functions with init - - - - - 13c113f6 by Josh Meredith at 2022-10-16T18:27:36-04:00 Fix function name from h$shrinkMutableArray to h$shrinkMutableCharArray - - - - - b83ee612 by Luite Stegeman at 2022-10-16T18:27:36-04:00 allow async exceptions to be thrown from outside a haskell thread - - - - - 523bc8a4 by Sylvain Henry at 2022-10-16T18:27:37-04:00 Remove shims and refactor Cpp I've removed the use of js/rts.h and js/constants.h again. We generate their contents at cpp time. Instead of wiring z-encoded strings into these macros, we should derive them from wired-in Names so that they stay correct in the future. Using wired-in Names as single source of truth. - - - - - 33d50776 by Sylvain Henry at 2022-10-16T18:27:37-04:00 Support RTS globals (used by GHC) and EISDIR Did this while trying to fix CallArity1 (still failing) - - - - - 88c78f1c by Sylvain Henry at 2022-10-16T18:27:37-04:00 Remove JS keywords 1. The list is incomplete 2. We prefix locals with "h$$" so there is no risk of conflict with JS keywords - - - - - 6f5768eb by Sylvain Henry at 2022-10-16T18:27:37-04:00 Remove dead code - - - - - 29b9e582 by Sylvain Henry at 2022-10-16T18:27:37-04:00 Make ident supply strict (no need to make it lazy, list already is) - - - - - 8bdb8928 by Sylvain Henry at 2022-10-16T18:27:38-04:00 Add optional assign to DeclStat and remove dead code - - - - - 7914300c by doyougnu at 2022-10-16T18:27:38-04:00 JS: Note on JS .o file order, fix .o files To be specific: 1. add Note [JS Backend .o file procedure] 2. ensure that .o files are touch'd in JS backend postHsc phase. This fixes "missing object file" errors produced by 'GHC.Driver.Main.checkObjects'. - - - - - 27ad47f4 by Luite Stegeman at 2022-10-16T18:27:38-04:00 start a subtransaction in a catchStm block - - - - - bf2ba4e2 by Sylvain Henry at 2022-10-16T18:27:38-04:00 Use FastMutInt in G for uniques - - - - - f6c89283 by Sylvain Henry at 2022-10-16T18:27:38-04:00 Compactor: remove dead code - - - - - 12b3f54b by Sylvain Henry at 2022-10-16T18:27:39-04:00 Compactor: remove more dead code - - - - - 065dbf6d by Sylvain Henry at 2022-10-16T18:27:39-04:00 Compactor: remove unused debug code - - - - - 958b77ac by Sylvain Henry at 2022-10-16T18:27:39-04:00 Compactor: remove unimplemented packStrings - - - - - c2ef1dd3 by Sylvain Henry at 2022-10-16T18:27:39-04:00 RTS: fix query/replace error - - - - - b87c9c60 by Luite Stegeman at 2022-10-16T18:27:39-04:00 remove unused STM check invariants - - - - - dd61795f by Josh Meredith at 2022-10-16T18:27:40-04:00 Refactor renaming functions from Compactor module into the Linker - - - - - c637c2c2 by Sylvain Henry at 2022-10-16T18:27:40-04:00 Linker: refactor and cleanup after compactor removal - - - - - d6ee1d06 by Sylvain Henry at 2022-10-16T18:27:40-04:00 Filter empty exports to avoid printing a lot of useless newlines - - - - - 8e0f4348 by Sylvain Henry at 2022-10-16T18:27:40-04:00 RTS: remove dangling semicolons - - - - - 7f6882a2 by Sylvain Henry at 2022-10-16T18:27:40-04:00 RTS: remove more dangling semicolons - - - - - 0dd42855 by Sylvain Henry at 2022-10-16T18:27:41-04:00 RTS: less semicolons - - - - - aecfe497 by Sylvain Henry at 2022-10-16T18:27:41-04:00 Only initialize statics once! - - - - - 5f0bfa97 by Sylvain Henry at 2022-10-16T18:27:41-04:00 Minor refactoring: avoid unpacking ShortText too soon - - - - - 53e6c8bd by Sylvain Henry at 2022-10-16T18:27:41-04:00 Remove unused derived instances - - - - - 3df71141 by Sylvain Henry at 2022-10-16T18:27:41-04:00 Use Ident in ClosureInfo instead of FastString - - - - - 1a673201 by Sylvain Henry at 2022-10-16T18:27:42-04:00 Add identFS helper - - - - - d049e360 by Sylvain Henry at 2022-10-16T18:27:42-04:00 Fix liftToGlobal identsS wasn't correctly ported: it has to return all the Ident occurences, not only one. Fixed this and simplified liftToGlobal implementation. Used UniqFM instead of Map forn the global ident cache. - - - - - 27 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/Graph/Directed.hs - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/Backend/Internal.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Config/StgToCmm.hs - + compiler/GHC/Driver/Config/StgToJS.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Phases.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01e0ca4f31e6eccb0420a8763b9064cd1e99172d...d049e360c124ab632408637e0d30e291b99aa20f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01e0ca4f31e6eccb0420a8763b9064cd1e99172d...d049e360c124ab632408637e0d30e291b99aa20f You're receiving 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 Oct 17 08:02:50 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 17 Oct 2022 04:02:50 -0400 Subject: [Git][ghc/ghc][wip/T22241] DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Message-ID: <634d0c2a92117_8b90f51798349814@gitlab.mail> Sebastian Graf pushed to branch wip/T22241 at Glasgow Haskell Compiler / GHC Commits: 63c3718f by Sebastian Graf at 2022-10-17T09:52:06+02:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 6 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -553,13 +553,16 @@ analysing their unfolding. A few reasons for the change: *workers*, because their transformers need to adapt to CPR for their arguments in 'cprTransformDataConWork' to enable Note [Nested CPR]. Better keep it all in this module! The alternative would be that - 'GHC.Types.Id.Make' depends on DmdAnal. + 'GHC.Types.Id.Make' depends on CprAnal. 3. In the future, Nested CPR could take a better account of incoming args in cprAnalApp and do some beta-reduction on the fly, like !1866 did. If any of those args had the CPR property, then we'd even get Nested CPR for DataCon wrapper calls, for free. Not so if we simply give the wrapper a single CPR sig in 'GHC.Types.Id.Make.mkDataConRep'! +DmdAnal also looks through the wrapper's unfolding: +See Note [DmdAnal for DataCon wrappers]. + Note [Trimming to mAX_CPR_SIZE] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We do not treat very big tuples as CPR-ish: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,10 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + -- See Note [DmdAnal for DataCon wrappers] + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1388,6 +1392,45 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +Note [DmdAnal for DataCon wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We give DataCon wrappers a (necessarily flat) demand signature in +`GHC.Types.Id.Make.mkDataConRep`, so that passes such as the Simplifier can +exploit it via the call to `GHC.Core.Opt.Simplify.Utils.isStrictArgInfo` in +`GHC.Core.Opt.Simplify.Iteration.rebuildCall`. But during DmdAnal, we *ignore* +the demand signature of a DataCon wrapper, and instead analyse its unfolding at +every call site. + +The reason is that DataCon *worker*s have very precise demand transformers, +computed by `dmdTransformDataConSig`. It would be awkward if DataCon *wrappers* +would behave much less precisely during DmdAnal. Example: + + data T1 = MkT1 { get_x1 :: Int, get_y1 :: Int } + data T2 = MkT2 { get_x2 :: !Int, get_y2 :: Int } + f1 x y = get_x1 (MkT1 x y) + f2 x y = get_x2 (MkT2 x y) + +Here `MkT1` has no wrapper. `get_x1` puts a demand `!P(1!L,A)` on its argument, +and `dmdTransformDataConSig` will transform that demand to an absent demand on +`y` in `f1` and an unboxing demand on `x`. +But `MkT2` has a wrapper (to evaluate the first field). If demand analysis deals +with `MkT2` only through its demand signature, demand signatures can't transform +an incoming demand `P(1!L,A)` in a useful way, so we won't get an absent demand +on `y` in `f2` or see that `x` can be unboxed. That's a serious loss. + +The example above will not actually occur, because $WMkT2 would be inlined. +Nevertheless, we can get interesting sub-demands on DataCon wrapper +applications in boring contexts; see T22241. + +You might worry about the efficiency cost of demand-analysing datacon wrappers +at every call site. But in fact they are inlined /anyway/ in the Final phase, +which happens before DmdAnal, so few wrappers remain. And analysing the +unfoldings for the remaining calls (which are those in a boring context) will be +exactly as (in)efficent as if we'd inlined those calls. It turns out to be not +measurable in practice. + +See also Note [CPR for DataCon wrappers] in `GHC.Core.Opt.CprAnal`. + Note [Boxity for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider (A) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -477,9 +477,9 @@ mkDictSelId name clas -- See Note [Type classes and linear types] base_info = noCafIdInfo - `setArityInfo` 1 - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` 1 + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig info | new_tycon = base_info `setInlinePragInfo` alwaysInlinePragma @@ -697,6 +697,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + -- The signature is purely for passes like the Simplifier, not for + -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv wrap_arg_dmds = @@ -1321,9 +1323,9 @@ mkFCallId uniq fcall ty name = mkFCallName uniq occ_str info = noCafIdInfo - `setArityInfo` arity - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` arity + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty arity = count isAnonTyCoBinder bndrs ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,31 @@ +module T22241 where + +data D = D { unD :: !Int } + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} + + + +data T a = T Int !a +get (T _ x) = x + +-- Here, the goal is to discard `unD (f True z)` and thus `z` as absent by +-- looking through $WT in `j` *during the first pass of DmdAnal*! +g :: Bool -> Int -> Int -> Bool +g x y z | even y = get (fst t) + | y > 13 = not (get (fst t)) + | otherwise = False + where + t | x = j (unD (f True z)) + | otherwise = j (unD (f False z)) + where + j a = (T a x, True) + {-# NOINLINE j #-} +{-# NOINLINE g #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,24 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + + +==================== Cpr signatures ==================== +T22241.f: 1 +T22241.g: +T22241.get: +T22241.unD: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63c3718fe033f924415b1ea873d146b557837698 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/63c3718fe033f924415b1ea873d146b557837698 You're receiving 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 Oct 17 08:04:32 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 17 Oct 2022 04:04:32 -0400 Subject: [Git][ghc/ghc][wip/T22241] DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Message-ID: <634d0c906da2b_8b90f5143c3569ac@gitlab.mail> Sebastian Graf pushed to branch wip/T22241 at Glasgow Haskell Compiler / GHC Commits: c8aeb4e3 by Sebastian Graf at 2022-10-17T10:04:24+02:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 6 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -553,13 +553,16 @@ analysing their unfolding. A few reasons for the change: *workers*, because their transformers need to adapt to CPR for their arguments in 'cprTransformDataConWork' to enable Note [Nested CPR]. Better keep it all in this module! The alternative would be that - 'GHC.Types.Id.Make' depends on DmdAnal. + 'GHC.Types.Id.Make' depends on CprAnal. 3. In the future, Nested CPR could take a better account of incoming args in cprAnalApp and do some beta-reduction on the fly, like !1866 did. If any of those args had the CPR property, then we'd even get Nested CPR for DataCon wrapper calls, for free. Not so if we simply give the wrapper a single CPR sig in 'GHC.Types.Id.Make.mkDataConRep'! +DmdAnal also looks through the wrapper's unfolding: +See Note [DmdAnal for DataCon wrappers]. + Note [Trimming to mAX_CPR_SIZE] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We do not treat very big tuples as CPR-ish: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,10 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + -- See Note [DmdAnal for DataCon wrappers] + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1388,6 +1392,45 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +Note [DmdAnal for DataCon wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We give DataCon wrappers a (necessarily flat) demand signature in +`GHC.Types.Id.Make.mkDataConRep`, so that passes such as the Simplifier can +exploit it via the call to `GHC.Core.Opt.Simplify.Utils.isStrictArgInfo` in +`GHC.Core.Opt.Simplify.Iteration.rebuildCall`. But during DmdAnal, we *ignore* +the demand signature of a DataCon wrapper, and instead analyse its unfolding at +every call site. + +The reason is that DataCon *worker*s have very precise demand transformers, +computed by `dmdTransformDataConSig`. It would be awkward if DataCon *wrappers* +would behave much less precisely during DmdAnal. Example: + + data T1 = MkT1 { get_x1 :: Int, get_y1 :: Int } + data T2 = MkT2 { get_x2 :: !Int, get_y2 :: Int } + f1 x y = get_x1 (MkT1 x y) + f2 x y = get_x2 (MkT2 x y) + +Here `MkT1` has no wrapper. `get_x1` puts a demand `!P(1!L,A)` on its argument, +and `dmdTransformDataConSig` will transform that demand to an absent demand on +`y` in `f1` and an unboxing demand on `x`. +But `MkT2` has a wrapper (to evaluate the first field). If demand analysis deals +with `MkT2` only through its demand signature, demand signatures can't transform +an incoming demand `P(1!L,A)` in a useful way, so we won't get an absent demand +on `y` in `f2` or see that `x` can be unboxed. That's a serious loss. + +The example above will not actually occur, because $WMkT2 would be inlined. +Nevertheless, we can get interesting sub-demands on DataCon wrapper +applications in boring contexts; see T22241. + +You might worry about the efficiency cost of demand-analysing datacon wrappers +at every call site. But in fact they are inlined /anyway/ in the Final phase, +which happens before DmdAnal, so few wrappers remain. And analysing the +unfoldings for the remaining calls (which are those in a boring context) will be +exactly as (in)efficent as if we'd inlined those calls. It turns out to be not +measurable in practice. + +See also Note [CPR for DataCon wrappers] in `GHC.Core.Opt.CprAnal`. + Note [Boxity for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider (A) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -477,9 +477,9 @@ mkDictSelId name clas -- See Note [Type classes and linear types] base_info = noCafIdInfo - `setArityInfo` 1 - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` 1 + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig info | new_tycon = base_info `setInlinePragInfo` alwaysInlinePragma @@ -697,6 +697,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + -- The signature is purely for passes like the Simplifier, not for + -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv wrap_arg_dmds = @@ -1321,9 +1323,9 @@ mkFCallId uniq fcall ty name = mkFCallName uniq occ_str info = noCafIdInfo - `setArityInfo` arity - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` arity + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty arity = count isAnonTyCoBinder bndrs ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,31 @@ +module T22241 where + +data D = D { unD :: !Int } + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} + + + +data T a = T Int !a +get (T _ x) = x + +-- Here, the goal is to discard `unD (f True z)` and thus `z` as absent by +-- looking through $WT in `j` *during the first pass of DmdAnal*! +g :: Bool -> Int -> Int -> Bool +g x y z | even y = get (fst t) + | y > 13 = not (get (fst t)) + | otherwise = False + where + t | x = j (unD (f True z)) + | otherwise = j (unD (f False z)) + where + j a = (T a x, True) + {-# NOINLINE j #-} +{-# NOINLINE g #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,24 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + + +==================== Cpr signatures ==================== +T22241.f: 1 +T22241.g: +T22241.get: +T22241.unD: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8aeb4e3692c0934bdb1b8ca47c4abf7be24d5ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8aeb4e3692c0934bdb1b8ca47c4abf7be24d5ce You're receiving 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 Oct 17 09:57:21 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 05:57:21 -0400 Subject: [Git][ghc/ghc][wip/andreask/opt-bindersof] Avoid allocating intermediate lists for non recursive bindings. Message-ID: <634d2701a43dc_8b90f517703763d8@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/opt-bindersof at Glasgow Haskell Compiler / GHC Commits: 9cf405df by Andreas Klebinger at 2022-10-17T11:53:30+02:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - 8 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Types/Var/Env.hs Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -42,6 +42,7 @@ module GHC.Core ( -- ** Simple 'Expr' access functions and predicates bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts, + foldBindersOfBindStrict, foldBindersOfBindsStrict, collectBinders, collectTyBinders, collectTyAndValBinders, collectNBinders, collectNValBinders_maybe, collectArgs, stripNArgs, collectArgsTicks, flattenBinds, @@ -1953,6 +1954,21 @@ bindersOf (Rec pairs) = [binder | (binder, _) <- pairs] bindersOfBinds :: [Bind b] -> [b] bindersOfBinds binds = foldr ((++) . bindersOf) [] binds +-- We inline this to avoid unknown function calls. +{-# INLINE foldBindersOfBindStrict #-} +foldBindersOfBindStrict :: (a -> b -> a) -> a -> Bind b -> a +foldBindersOfBindStrict f + = \z bind -> case bind of + NonRec b _rhs -> f z b + Rec pairs -> foldl' f z $ map fst pairs + +{-# INLINE foldBindersOfBindsStrict #-} +foldBindersOfBindsStrict :: (a -> b -> a) -> a -> [Bind b] -> a +foldBindersOfBindsStrict f = \z binds -> foldl' fold_bind z binds + where + fold_bind = (foldBindersOfBindStrict f) + + rhssOfBind :: Bind b -> [Expr b] rhssOfBind (NonRec _ rhs) = [rhs] rhssOfBind (Rec pairs) = [rhs | (_,rhs) <- pairs] ===================================== compiler/GHC/Core/Opt/Exitify.hs ===================================== @@ -62,7 +62,7 @@ exitifyProgram binds = map goTopLvl binds goTopLvl (Rec pairs) = Rec (map (second (go in_scope_toplvl)) pairs) -- Top-level bindings are never join points - in_scope_toplvl = emptyInScopeSet `extendInScopeSetList` bindersOfBinds binds + in_scope_toplvl = emptyInScopeSet `extendInScopeSetBndrs` binds go :: InScopeSet -> CoreExpr -> CoreExpr go _ e@(Var{}) = e @@ -94,7 +94,7 @@ exitifyProgram binds = map goTopLvl binds | otherwise = Let (Rec pairs') body' where is_join_rec = any (isJoinId . fst) pairs - in_scope' = in_scope `extendInScopeSetList` bindersOf (Rec pairs) + in_scope' = in_scope `extendInScopeSetBind` (Rec pairs) pairs' = mapSnd (go in_scope') pairs body' = go in_scope' body ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Core.Utils ( exprType, exprIsHNF , exprOkForSpeculation , exprIsTopLevelBindable , collectMakeStaticArgs - , mkLamTypes + , mkLamTypes, extendInScopeSetBndrs ) import GHC.Core.Opt.Arity ( exprBotStrictness_maybe, isOneShotBndr ) import GHC.Core.FVs -- all of it @@ -1566,7 +1566,7 @@ initialEnv float_lams binds , le_subst = mkEmptySubst in_scope_toplvl , le_env = emptyVarEnv } where - in_scope_toplvl = emptyInScopeSet `extendInScopeSetList` bindersOfBinds binds + in_scope_toplvl = emptyInScopeSet `extendInScopeSetBndrs` binds -- The Simplifier (see Note [Glomming] in GHC.Core.Opt.OccurAnal) and -- the specialiser (see Note [Top level scope] in GHC.Core.Opt.Specialise) -- may both produce top-level bindings where an early binding refers ===================================== compiler/GHC/Core/Opt/Simplify/Env.hs ===================================== @@ -812,10 +812,6 @@ addJoinFloats floats join_floats , sfInScope = foldlOL extendInScopeSetBind (sfInScope floats) join_floats } -extendInScopeSetBind :: InScopeSet -> CoreBind -> InScopeSet -extendInScopeSetBind in_scope bind - = extendInScopeSetList in_scope (bindersOf bind) - addFloats :: SimplFloats -> SimplFloats -> SimplFloats -- Add both let-floats and join-floats for env2 to env1; -- *plus* the in-scope set for env2, which is bigger ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -949,8 +949,7 @@ initScEnv guts sc_vals = emptyVarEnv, sc_annotations = anns }) } where - init_subst = mkEmptySubst $ mkInScopeSet $ mkVarSet $ - bindersOfBinds (mg_binds guts) + init_subst = mkEmptySubst $ mkInScopeSetBndrs (mg_binds guts) -- Acccount for top-level bindings that are not in dependency order; -- see Note [Glomming] in GHC.Core.Opt.OccurAnal -- Easiest thing is to bring all the top level binders into scope at once, ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -28,7 +28,7 @@ import GHC.Core import GHC.Core.Rules import GHC.Core.Utils ( exprIsTrivial , mkCast, exprType - , stripTicksTop ) + , stripTicksTop, mkInScopeSetBndrs ) import GHC.Core.FVs import GHC.Core.TyCo.Rep (TyCoBinder (..)) import GHC.Core.Opt.Arity( collectBindersPushingCo ) @@ -601,8 +601,10 @@ 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 - ; let top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSetList $ - bindersOfBinds binds + ; let top_env = SE { se_subst = Core.mkEmptySubst $ + mkInScopeSetBndrs binds + -- mkInScopeSetList $ + -- bindersOfBinds binds , se_module = this_mod , se_dflags = dflags } ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -47,6 +47,9 @@ module GHC.Core.Utils ( stripTicksTop, stripTicksTopE, stripTicksTopT, stripTicksE, stripTicksT, + -- * InScopeSet things which work over CoreBinds + mkInScopeSetBndrs, extendInScopeSetBind, extendInScopeSetBndrs, + -- * StaticPtr collectMakeStaticArgs, @@ -2336,6 +2339,26 @@ normSplitTyConApp_maybe fam_envs ty = Just (tc, tc_args, co) normSplitTyConApp_maybe _ _ = Nothing +{- +***************************************************** +* +* InScopeSet things +* +***************************************************** +-} + + +extendInScopeSetBind :: InScopeSet -> CoreBind -> InScopeSet +extendInScopeSetBind (InScope in_scope) binds + = InScope $ foldBindersOfBindStrict extendVarSet in_scope binds + +extendInScopeSetBndrs :: InScopeSet -> [CoreBind] -> InScopeSet +extendInScopeSetBndrs (InScope in_scope) binds + = InScope $ foldBindersOfBindsStrict extendVarSet in_scope binds + +mkInScopeSetBndrs :: [CoreBind] -> InScopeSet +mkInScopeSetBndrs binds = foldBindersOfBindsStrict extendInScopeSet emptyInScopeSet binds + {- ***************************************************** * ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -47,7 +47,7 @@ module GHC.Types.Var.Env ( anyDVarEnv, -- * The InScopeSet type - InScopeSet, + InScopeSet(..), -- ** Operations on InScopeSets emptyInScopeSet, mkInScopeSet, mkInScopeSetList, delInScopeSet, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9cf405df488dde32e338052d5ef569d9ff310b20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9cf405df488dde32e338052d5ef569d9ff310b20 You're receiving 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 Oct 17 09:57:52 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 05:57:52 -0400 Subject: [Git][ghc/ghc][wip/andreask/opt-bindersof] 97 commits: Tag inference: Fix #21954 by retaining tagsigs of vars in function position. Message-ID: <634d2720d7ce1_8b90f517d4376725@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/opt-bindersof at Glasgow Haskell Compiler / GHC Commits: d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 156d7181 by Andreas Klebinger at 2022-10-17T11:55:11+02:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - 30 changed files: - .editorconfig - .gitlab/ci.sh - README.md - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/CFG/Dominators.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9cf405df488dde32e338052d5ef569d9ff310b20...156d71811421e3f7b19f63b63ff502bd373ee75f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9cf405df488dde32e338052d5ef569d9ff310b20...156d71811421e3f7b19f63b63ff502bd373ee75f You're receiving 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 Oct 17 10:02:12 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 06:02:12 -0400 Subject: [Git][ghc/ghc][wip/andreask/stgLintFix] 6 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <634d28245889f_8b90f5143c38203a@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/stgLintFix at Glasgow Haskell Compiler / GHC Commits: 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 545ce44f by Andreas Klebinger at 2022-10-17T10:02:04+00:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 20 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Stg/Lint.hs - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/posix/OSThreads.c - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -46,9 +46,18 @@ are as follows: t_1 :: TYPE r_1, ..., t_n :: TYPE r_n s_1 :: TYPE p_1, ..., a_n :: TYPE p_n -Then we must check that each r_i is compatible with s_i. Compatibility -is weaker than on-the-nose equality: for example, IntRep and WordRep are -compatible. See Note [Bad unsafe coercion] in GHC.Core.Lint. +Before unarisation, we must check that each r_i is compatible with s_i. +Compatibility is weaker than on-the-nose equality: for example, +IntRep and WordRep are compatible. See Note [Bad unsafe coercion] in GHC.Core.Lint. + +After unarisation, a single type might correspond to multiple arguments, e.g. + + (# Int# | Bool #) :: TYPE (SumRep '[ IntRep, LiftedRep ]) + +will result in two arguments: [Int# :: TYPE 'IntRep, Bool :: TYPE LiftedRep] +This means post unarise we potentially have to match up multiple arguments with +the reps of a single argument in the type's definition, because the type of the function +is *not* in unarised form. Wrinkle: it can sometimes happen that an argument type in the type of the function does not have a fixed runtime representation, i.e. @@ -119,7 +128,7 @@ import Data.Maybe import GHC.Utils.Misc import GHC.Core.Multiplicity (scaledThing) import GHC.Settings (Platform) -import GHC.Core.TyCon (primRepCompatible) +import GHC.Core.TyCon (primRepCompatible, primRepsCompatible) import GHC.Utils.Panic.Plain (panic) lintStgTopBindings :: forall a . (OutputablePass a, BinderP a ~ Id) @@ -332,14 +341,18 @@ lintStgAppReps _fun [] = return () lintStgAppReps fun args = do lf <- getLintFlags let platform = lf_platform lf + (fun_arg_tys, _res) = splitFunTys (idType fun) - fun_arg_tys' = map (scaledThing ) fun_arg_tys :: [Type] + fun_arg_tys' = map scaledThing fun_arg_tys :: [Type] + + -- Might be "wrongly" typed as polymorphic. See #21399 + -- In these cases typePrimRep_maybe will return Nothing + -- and we abort kind checking. fun_arg_tys_reps, actual_arg_reps :: [Maybe [PrimRep]] fun_arg_tys_reps = map typePrimRep_maybe fun_arg_tys' actual_arg_reps = map (typePrimRep_maybe . stgArgType) args match_args :: [Maybe [PrimRep]] -> [Maybe [PrimRep]] -> LintM () - -- Might be wrongly typed as polymorphic. See #21399 match_args (Nothing:_) _ = return () match_args (_) (Nothing:_) = return () match_args (Just actual_rep:actual_reps_left) (Just expected_rep:expected_reps_left) @@ -353,21 +366,36 @@ lintStgAppReps fun args = do -- Some reps are compatible *even* if they are not the same. E.g. IntRep and WordRep. -- We check for that here with primRepCompatible - | and $ zipWith (primRepCompatible platform) actual_rep expected_rep + | primRepsCompatible platform actual_rep expected_rep = match_args actual_reps_left expected_reps_left + -- We might distribute args from within one unboxed sum over multiple + -- single rep args. This means we might need to match up things like: + -- [Just [WordRep, LiftedRep]] with [Just [WordRep],Just [LiftedRep]] + -- which happens here. + -- See Note [Linting StgApp]. + | Just (actual,actuals) <- getOneRep actual_rep actual_reps_left + , Just (expected,expecteds) <- getOneRep expected_rep expected_reps_left + , primRepCompatible platform actual expected + = match_args actuals expecteds + | otherwise = addErrL $ hang (text "Function type reps and function argument reps mismatched") 2 $ (text "In application " <> ppr fun <+> ppr args $$ - text "argument rep:" <> ppr actual_rep $$ - text "expected rep:" <> ppr expected_rep $$ + text "argument rep:" <> ppr actual_arg_reps $$ + text "expected rep:" <> ppr fun_arg_tys_reps $$ -- text "expected reps:" <> ppr arg_ty_reps $$ text "unarised?:" <> ppr (lf_unarised lf)) where isVoidRep [] = True isVoidRep [VoidRep] = True isVoidRep _ = False - - -- n_arg_ty_reps = length arg_ty_reps + -- Try to strip one non-void arg rep from the current argument type returning + -- the remaining list of arguments. We return Nothing for invalid input which + -- will result in a lint failure in match_args. + getOneRep :: [PrimRep] -> [Maybe [PrimRep]] -> Maybe (PrimRep, [Maybe [PrimRep]]) + getOneRep [] _rest = Nothing -- Void rep args are invalid at this point. + getOneRep [rep] rest = Just (rep,rest) -- A single arg rep arg + getOneRep (rep:reps) rest = Just (rep,Just reps:rest) -- Multi rep arg. match_args _ _ = return () -- Functions are allowed to be over/under applied. ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -140,6 +140,11 @@ Runtime system - Updated to `Unicode 15.0.0 `_. +- Add standard Unicode case predicates :base-ref:`Data.Char.isUpperCase` and + :base-ref:`Data.Char.isLowerCase`. These predicates use the standard Unicode + case properties and are more intuitive than :base-ref:`Data.Char.isUpper` and + :base-ref:`Data.Char.isLower`. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ ===================================== libraries/base/Data/Char.hs ===================================== @@ -6,7 +6,7 @@ -- Module : Data.Char -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : stable -- Portability : portable @@ -24,7 +24,7 @@ module Data.Char -- punctuation, symbols, separators (including spaces) and others -- (including control characters). , isControl, isSpace - , isLower, isUpper, isAlpha, isAlphaNum, isPrint + , isLower, isLowerCase, isUpper, isUpperCase, isAlpha, isAlphaNum, isPrint , isDigit, isOctDigit, isHexDigit , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator ===================================== libraries/base/Data/OldList.hs ===================================== @@ -1249,6 +1249,7 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- The 'permutations' function is maximally lazy: -- for each @n@, the value of @'permutations' xs@ starts with those permutations -- that permute @'take' n xs@ and keep @'drop' n xs at . +-- -- This function is productive on infinite inputs: -- -- >>> take 6 $ map (take 3) $ permutations ['a'..] @@ -1259,21 +1260,25 @@ nonEmptySubsequences (x:xs) = [x] : foldr f [] (nonEmptySubsequences xs) -- -- > map (take n) (take (product [1..n]) (permutations ([1..n] ++ undefined))) == permutations [1..n] -- -permutations :: [a] -> [[a]] +permutations :: [a] -> [[a]] -- See https://stackoverflow.com/questions/24484348/what-does-this-list-permutations-implementation-in-haskell-exactly-do/24564307#24564307 -- for the analysis of this rather cryptic implementation. -- Related discussions: -- * https://mail.haskell.org/pipermail/haskell-cafe/2021-December/134920.html -- * https://mail.haskell.org/pipermail/libraries/2007-December/008788.html -permutations xs0 = xs0 : perms xs0 [] +permutations xs0 = xs0 : perms xs0 [] where + perms :: forall a. [a] -> [a] -> [[a]] perms [] _ = [] perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) - where interleave xs r = let (_,zs) = interleave' id xs r in zs - interleave' _ [] r = (ts, r) - interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r - in (y:us, f (t:y:us) : zs) - + where + interleave :: [a] -> [[a]] -> [[a]] + interleave xs r = let (_,zs) = interleave' id xs r in zs + + interleave' :: ([a] -> b) -> [a] -> [b] -> ([a], [b]) + interleave' _ [] r = (ts, r) + interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r + in (y:us, f (t:y:us) : zs) ------------------------------------------------------------------------------ -- Quick Sort algorithm taken from HBC's QSort library. ===================================== libraries/base/GHC/Unicode.hs ===================================== @@ -24,8 +24,8 @@ module GHC.Unicode ( GeneralCategory (..), generalCategory, isAscii, isLatin1, isControl, isAsciiUpper, isAsciiLower, - isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, + isPrint, isSpace, isUpper, isUpperCase, + isLower, isLowerCase, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, isPunctuation, isSymbol, toUpper, toLower, toTitle @@ -37,6 +37,7 @@ import GHC.Enum ( Enum (..), Bounded (..) ) import GHC.Ix ( Ix (..) ) import GHC.Num import GHC.Unicode.Internal.Version +import qualified GHC.Unicode.Internal.Char.DerivedCoreProperties as DCP import qualified GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory as GC import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping as C import qualified GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping as C @@ -236,18 +237,68 @@ isSpace c -- | Selects upper-case or title-case alphabetic Unicode characters (letters). -- Title case is used by a small number of letter ligatures like the -- single-character form of /Lj/. +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'UppercaseLetter' or 'TitlecaseLetter'. +-- +-- See 'isUpperCase' for a more intuitive predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). isUpper :: Char -> Bool isUpper c = case generalCategory c of UppercaseLetter -> True TitlecaseLetter -> True _ -> False +-- | Selects upper-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Uppercase@, which include letter-like characters such as: +-- @\'Ⓐ\'@ (@U+24B6@ circled Latin capital letter A) and +-- @\'Ⅳ\'@ (@U+2163@ Roman numeral four). +-- +-- See 'isUpper' for the legacy predicate. Note that +-- unlike 'isUpperCase', 'isUpper' does select /title-case/ characters such as +-- @\'Dž\'@ (@U+01C5@ Latin capital letter d with small letter z with caron) or +-- @\'ᾯ\'@ (@U+1FAF@ Greek capital letter omega with dasia and perispomeni and +-- prosgegrammeni). +-- +-- @since 4.18.0.0 +{-# INLINE isUpperCase #-} +isUpperCase :: Char -> Bool +isUpperCase = DCP.isUppercase + -- | Selects lower-case alphabetic Unicode characters (letters). +-- +-- __Note:__ this predicate does /not/ work for letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). This is due to selecting only +-- characters with the 'GeneralCategory' 'LowercaseLetter'. +-- +-- See 'isLowerCase' for a more intuitive predicate. isLower :: Char -> Bool isLower c = case generalCategory c of LowercaseLetter -> True _ -> False +-- | Selects lower-case Unicode letter-like characters. +-- +-- __Note:__ this predicate selects characters with the Unicode property +-- @Lowercase@, which includes letter-like characters such as: +-- @\'ⓐ\'@ (@U+24D0@ circled Latin small letter a) and +-- @\'ⅳ\'@ (@U+2173@ small Roman numeral four). +-- +-- See 'isLower' for the legacy predicate. +-- +-- @since 4.18.0.0 +{-# INLINE isLowerCase #-} +isLowerCase :: Char -> Bool +isLowerCase = DCP.isLowercase + -- | Selects alphabetic Unicode characters (lower-case, upper-case and -- title-case letters, plus letters of caseless scripts and modifiers letters). -- This function is equivalent to 'Data.Char.isLetter'. ===================================== libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs ===================================== @@ -0,0 +1,35 @@ +-- DO NOT EDIT: This file is automatically generated by the internal tool ucd2haskell, +-- with data from: https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt. + +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# OPTIONS_HADDOCK hide #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Unicode.Internal.Char.DerivedCoreProperties +-- Copyright : (c) 2020 Composewell Technologies and Contributors +-- License : BSD-3-Clause +-- Maintainer : streamly at composewell.com +-- Stability : internal +----------------------------------------------------------------------------- + +module GHC.Unicode.Internal.Char.DerivedCoreProperties +(isUppercase , isLowercase) +where + +import GHC.Base (Bool, Char, Ord(..), (&&), ord) +import GHC.Unicode.Internal.Bits (lookupBit64) + +{-# INLINE isUppercase #-} +isUppercase :: Char -> Bool +isUppercase = \c -> let n = ord c in n >= 65 && n <= 127369 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\255\255\127\127\0\0\0\0\85\85\85\85\85\85\85\170\170\84\85\85\85\85\85\43\214\206\219\177\213\210\174\17\144\164\170\74\85\85\210\85\85\85\85\85\85\85\5\108\122\85\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\69\128\64\215\254\255\251\15\0\0\0\128\28\85\85\85\144\230\255\255\255\255\255\255\0\0\0\0\0\0\85\85\85\85\1\84\85\85\85\85\85\85\171\42\85\85\85\85\85\85\85\85\85\85\85\85\254\255\255\255\127\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\231\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\85\21\64\85\85\85\85\85\85\85\85\85\85\85\85\0\255\0\63\0\255\0\255\0\63\0\170\0\255\0\0\0\0\0\0\0\0\0\15\0\15\0\15\0\31\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\132\56\39\62\80\61\15\192\32\0\0\0\255\255\0\0\8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\192\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\0\0\0\0\0\0\157\234\37\192\85\85\85\85\85\85\85\85\85\85\85\85\5\40\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\85\85\85\85\85\21\0\0\85\85\85\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\84\85\84\85\85\85\85\85\85\85\0\106\85\40\69\85\85\125\95\85\245\2\65\1\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\247\255\247\55\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\208\100\222\63\0\0\0\255\255\255\3\0\0\176\231\223\31\0\0\0\123\95\252\1\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\240\255\255\63\0\0\0\255\255\255\3\0\0\0\255\255\255\1\0\0\0\252\255\255\7\0\0\0\240\255\255\31\0\0\0\192\255\255\127\0\0\0\0\255\255\255\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\255\255\255\3\255\255\255\3"# + +{-# INLINE isLowercase #-} +isLowercase :: Char -> Bool +isLowercase = \c -> let n = ord c in n >= 97 && n <= 125251 && lookupBit64 bitmap# n + where + bitmap# = "\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\4\32\4\0\0\0\128\255\255\127\255\170\170\170\170\170\170\170\85\85\171\170\170\170\170\170\212\41\49\36\78\42\45\81\230\64\82\85\181\170\170\41\170\170\170\170\170\170\170\250\147\133\170\255\255\255\255\255\255\255\255\239\255\255\255\255\1\3\0\0\0\31\0\0\0\0\0\0\0\0\0\0\0\32\0\0\0\0\0\138\60\0\0\1\0\0\240\255\255\255\127\227\170\170\170\47\25\0\0\0\0\0\0\255\255\255\255\255\255\170\170\170\170\2\168\170\170\170\170\170\170\84\213\170\170\170\170\170\170\170\170\170\170\170\170\0\0\0\0\0\0\255\255\255\255\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\170\234\191\170\170\170\170\170\170\170\170\170\170\170\170\255\0\63\0\255\0\255\0\63\0\255\0\255\0\255\63\255\0\255\0\255\0\223\64\220\0\207\0\255\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\128\0\0\255\31\0\0\0\0\0\0\0\0\0\0\0\0\0\196\8\0\0\128\16\50\192\67\0\0\0\0\255\255\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\98\21\218\63\170\170\170\170\170\170\170\170\170\170\170\170\26\80\8\0\255\255\255\255\191\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\170\170\170\170\42\0\0\170\170\170\58\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\168\170\171\170\170\170\170\170\170\170\255\149\170\80\186\170\170\130\160\170\10\5\170\2\0\0\92\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\247\255\3\255\255\255\255\255\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\127\0\248\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\254\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\128\255\251\255\251\27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\185\255\255\255\255\255\253\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\15\0\0\192\223\255\255\0\0\0\252\255\255\15\0\0\192\235\239\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\15\0\0\192\255\255\255\0\0\0\252\255\255\63\0\0\0\252\255\255\247\3\0\0\240\255\255\223\15\0\0\192\255\255\127\63\0\0\0\255\255\255\253\0\0\0\252\255\255\247\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\251\255\127\224\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\255\255\255\255\255\255\255\63\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\255\255\255\15"# + ===================================== libraries/base/base.cabal ===================================== @@ -352,6 +352,7 @@ Library GHC.Event.Unique -- GHC.IOPort -- TODO: hide again after debug GHC.Unicode.Internal.Bits + GHC.Unicode.Internal.Char.DerivedCoreProperties GHC.Unicode.Internal.Char.UnicodeData.GeneralCategory GHC.Unicode.Internal.Char.UnicodeData.SimpleLowerCaseMapping GHC.Unicode.Internal.Char.UnicodeData.SimpleTitleCaseMapping ===================================== libraries/base/changelog.md ===================================== @@ -30,6 +30,10 @@ for the related discussion, as well as [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). + * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to + `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode + case properties and are more intuitive than `isUpper` and `isLower`. See + [CLC proposal #90](https://github.com/haskell/core-libraries-committee/issues/90). * Add `Eq` and `Ord` instances for `Generically1`. * Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking. See [CLC ===================================== libraries/base/tests/unicode001.hs ===================================== @@ -16,17 +16,45 @@ main = do f True = "X " f False = " " -strs = ["upper","lower","alpha","alnum","digit","print","space","cntrl"] +strs = + [ "upper", + "uppr2", + "lower", + "lowr2", + "alpha", + "alnum", + "digit", + "print", + "space", + "cntrl" ] -functions = [isUpper,isLower,isAlpha,isAlphaNum,isDigit,isPrint,isSpace,isControl] +functions = + [ isUpper, + isUpperCase, + isLower, + isLowerCase, + isAlpha, + isAlphaNum, + isDigit, + isPrint, + isSpace, + isControl ] chars = [backspace,tab,space,zero,lower_a,upper_a,delete, right_pointing_double_angle_quotation_mark, + latin_capital_letter_l_with_small_letter_j, + latin_small_letter_i_with_caron, + combining_acute_accent, greek_capital_letter_alpha, bengali_digit_zero, en_space, + roman_numeral_one, + small_roman_numeral_one, + circled_latin_capital_letter_a, + circled_latin_small_letter_a, gothic_letter_ahsa, - monospaced_digit_zero + monospaced_digit_zero, + squared_latin_capital_letter_a ] backspace = '\x08' @@ -37,10 +65,16 @@ lower_a = 'a' upper_a = 'A' delete = '\x7f' right_pointing_double_angle_quotation_mark = '\xBB' +latin_capital_letter_l_with_small_letter_j = '\x01C8' latin_small_letter_i_with_caron = '\x1D0' combining_acute_accent = '\x301' greek_capital_letter_alpha = '\x0391' bengali_digit_zero = '\x09E6' en_space = '\x2002' +roman_numeral_one = '\x2160' +small_roman_numeral_one = '\x2170' +circled_latin_capital_letter_a = '\x24B6' +circled_latin_small_letter_a = '\x24D6' gothic_letter_ahsa = '\x10330' monospaced_digit_zero = '\x1D7F6' +squared_latin_capital_letter_a = '\x1F130' ===================================== libraries/base/tests/unicode001.stdout ===================================== @@ -1,14 +1,22 @@ - upper lower alpha alnum digit print space cntrl -'\b' X -'\t' X X -' ' X X -'0' X X X -'a' X X X X -'A' X X X X -'\DEL' X -'\187' X -'\913' X X X X -'\2534' X X -'\8194' X X -'\66352' X X X -'\120822' X X + upper uppr2 lower lowr2 alpha alnum digit print space cntrl +'\b' X +'\t' X X +' ' X X +'0' X X X +'a' X X X X X +'A' X X X X X +'\DEL' X +'\187' X +'\456' X X X X +'\464' X X X X X +'\769' X +'\913' X X X X X +'\2534' X X +'\8194' X X +'\8544' X X X +'\8560' X X X +'\9398' X X +'\9430' X X +'\66352' X X X +'\120822' X X +'\127280' X X ===================================== libraries/base/tools/ucd2haskell/exe/Parser/Text.hs ===================================== @@ -22,12 +22,12 @@ module Parser.Text (genModules) where import Control.Exception (catch, IOException) import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO)) --- import Data.Bits (Bits(..)) [NOTE] Used by disabled generator +import Data.Bits (Bits(..)) import Data.Word (Word8) -import Data.Char (chr, ord {-, isSpace-}) +import Data.Char (chr, ord, isSpace) import Data.Functor ((<&>)) import Data.Function ((&)) --- import Data.List (unfoldr, intersperse) [NOTE] Used by disabled generator +import Data.List (intersperse, unfoldr) import Data.List.Split (splitWhen) import Numeric (showHex) import Streamly.Data.Fold (Fold) @@ -132,7 +132,6 @@ readCodePointM :: String -> Maybe Char readCodePointM "" = Nothing readCodePointM u = Just (readCodePoint u) -{- [NOTE] Used by disabled generator genSignature :: String -> String genSignature = (<> " :: Char -> Bool") @@ -189,7 +188,6 @@ bitMapToAddrLiteral bs cs = foldr encode cs (unfoldr mkChunks bs) toByte :: [Bool] -> Int toByte xs = sum $ map (\i -> if xs !! i then 1 `shiftL` i else 0) [0..7] --} genEnumBitmap :: forall a. (Bounded a, Enum a, Show a) => @@ -642,8 +640,6 @@ genSimpleCaseMappingModule moduleName funcName field = showHexChar c = showHex (ord c) -{- [NOTE] Disabled generator - genCorePropertiesModule :: Monad m => String -> (String -> Bool) -> Fold m (String, [Int]) String genCorePropertiesModule moduleName isProp = @@ -674,7 +670,6 @@ genCorePropertiesModule moduleName isProp = , "import GHC.Unicode.Internal.Bits (lookupBit64)" , "" ] --} {- [NOTE] Disabled generator genUnicode002TestResults :: Monad m => Fold m DetailedChar String @@ -778,8 +773,6 @@ genUnicode002TestResults = done <$> Fold.foldl' step initial -- Parsing property files ------------------------------------------------------------------------------- -{- [NOTE] Used by disabled generator - type PropertyLine = (String, [Int]) trim :: String -> String @@ -826,7 +819,6 @@ parsePropertyLines = Stream.splitOn isDivider $ Fold.lmap parsePropertyLine $ Fold.foldl' combinePropertyLines emptyPropertyLine --} -- | A range entry in @UnicodeData.txt at . data UnicodeDataRange @@ -1014,7 +1006,7 @@ runGenerator indir file transformLines outdir recipes = combinedFld = void $ Fold.distribute generatedFolds genModules :: String -> String -> [String] -> IO () -genModules indir outdir _props = do +genModules indir outdir props = do genUnicodeVersion outdir -- [NOTE] Disabled generator @@ -1060,13 +1052,12 @@ genModules indir outdir _props = do -- outdir -- [ uncurry ModuleRecipe propList ] - -- [NOTE] Disabled generator - -- runGenerator - -- indir - -- "DerivedCoreProperties.txt" - -- parsePropertyLines - -- outdir - -- [ uncurry ModuleRecipe derivedCoreProperties ] + runGenerator + indir + "DerivedCoreProperties.txt" + parsePropertyLines + outdir + [ uncurry ModuleRecipe derivedCoreProperties ] where @@ -1075,10 +1066,9 @@ genModules indir outdir _props = do -- ("GHC.Unicode.Internal.Char.PropList" -- , (`genCorePropertiesModule` (`elem` props))) - -- [NOTE] Disabled generator - -- derivedCoreProperties = - -- ("GHC.Unicode.Internal.Char.DerivedCoreProperties" - -- , (`genCorePropertiesModule` (`elem` props))) + derivedCoreProperties = + ("GHC.Unicode.Internal.Char.DerivedCoreProperties" + , (`genCorePropertiesModule` (`elem` props))) -- [NOTE] Disabled generator -- compositions exc non0 = ===================================== libraries/base/tools/ucd2haskell/tests/check_all_chars.py ===================================== @@ -10,6 +10,15 @@ from operator import methodcaller def parse_codepoint(s: str, base=16): return chr(int(s, base)) +def parse_bool(s: str): + match(s): + case "True": + return True + case "False": + return False + case _: + raise ValueError(s) + def general_category(c: str): match(unicodedata.category(c)): case "Lu": @@ -107,6 +116,11 @@ def check_case_mapping(case_mapping: str, char: str, raw_expected: str, verbosit f"“{expected}” (1 char)." ) +def check_case_predicate(case_predicate: str, char: str, raw_expected: str, verbosity: int): + got = methodcaller(case_predicate)(char) + expected = parse_bool(raw_expected) + check(got == expected, (char, got, expected)) + if __name__ == "__main__": parser = make_parser() @@ -125,10 +139,12 @@ if __name__ == "__main__": next(fp) reader = csv.reader(fp) for row in reader: - raw_code, gc, raw_lower, raw_upper, raw_title = row + raw_code, gc, raw_lower, raw_upper, raw_title, raw_islower, raw_isupper = row char = parse_codepoint(raw_code) codepoint = f"U+{raw_code.upper():0>4}" check(gc == general_category(char), (char, gc, general_category(char))) check_case_mapping("lower", char, raw_lower, verbosity) check_case_mapping("upper", char, raw_upper, verbosity) check_case_mapping("title", char, raw_title, verbosity) + check_case_predicate("islower", char, raw_islower, verbosity) + check_case_predicate("isupper", char, raw_isupper, verbosity) ===================================== libraries/base/tools/ucd2haskell/tests/export_all_chars.hs ===================================== @@ -26,7 +26,7 @@ main = do -- | File header header :: String -header = "Char,General Category,Lower Case,Upper Case,Title Case" +header = "Char,General Category,Lower Case,Upper Case,Title Case,isLowerCase,isUpperCase" -- | Convert a character to its (short) hexadecimal Unicode codepoint. mkCodePointHex :: Char -> String @@ -43,4 +43,8 @@ addEntry c = do putChar ',' putStr (mkCodePointHex (toUpper c)) putChar ',' - putStrLn (mkCodePointHex (toTitle c)) + putStr (mkCodePointHex (toTitle c)) + putChar ',' + putStr (show (isLowerCase c)) + putChar ',' + putStrLn (show (isUpperCase c)) ===================================== libraries/base/tools/ucd2haskell/ucd.sh ===================================== @@ -12,6 +12,7 @@ VERIFY_CHECKSUM=y # Filename:checksum FILES="\ + ucd/DerivedCoreProperties.txt:d367290bc0867e6b484c68370530bdd1a08b6b32404601b8c7accaf83e05628d \ ucd/UnicodeData.txt:806e9aed65037197f1ec85e12be6e8cd870fc5608b4de0fffd990f689f376a73" # Download the files @@ -58,10 +59,10 @@ run_generator() { # Compile and run ucd2haskell cabal run exe:ucd2haskell -- \ --input "$SCRIPT_DIR/ucd/" \ - --output "$GHC_MODULE_PATH/" - # [NOTE] disabled generaor - # --core-prop Uppercase \ - # --core-prop Lowercase \ + --output "$GHC_MODULE_PATH/" \ + --core-prop Uppercase \ + --core-prop Lowercase + # [NOTE] disabled generator # --core-prop Alphabetic # --core-prop White_Space \ # --core-prop ID_Start \ ===================================== rts/posix/OSThreads.c ===================================== @@ -186,22 +186,48 @@ shutdownThread(void) pthread_exit(NULL); } -int -createOSThread (OSThreadId* pId, char *name STG_UNUSED, - OSThreadProc *startProc, void *param) +struct ThreadDesc { + OSThreadProc *startProc; + void *param; + char *name; +}; + +// N.B. Darwin's pthread_setname_np only allows the name of the +// calling thread to be set. Consequently we must use this +// trampoline. +static void * +start_thread (void *param) { - int result = pthread_create(pId, NULL, startProc, param); - if (!result) { - pthread_detach(*pId); + struct ThreadDesc desc = *(struct ThreadDesc *) param; + stgFree(param); + #if defined(HAVE_PTHREAD_SET_NAME_NP) - pthread_set_name_np(*pId, name); + pthread_set_name_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP) - pthread_setname_np(*pId, name); + pthread_setname_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) - pthread_setname_np(name); + pthread_setname_np(desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) - pthread_setname_np(*pId, "%s", name); + pthread_setname_np(pthread_self(), "%s", desc.name); #endif + + return desc.startProc(desc.param); +} + +int +createOSThread (OSThreadId* pId, char *name STG_UNUSED, + OSThreadProc *startProc, void *param) +{ + struct ThreadDesc *desc = stgMallocBytes(sizeof(struct ThreadDesc), "createOSThread"); + desc->startProc = startProc; + desc->param = param; + desc->name = name; + + int result = pthread_create(pId, NULL, start_thread, desc); + if (!result) { + pthread_detach(*pId); + } else { + stgFree(desc); } return result; } ===================================== testsuite/tests/numeric/should_run/T22282.hs ===================================== @@ -0,0 +1,3 @@ +import T22282A + +main = print $ testF 217 161 ===================================== testsuite/tests/numeric/should_run/T22282.stdout ===================================== @@ -0,0 +1,2 @@ +217 + ===================================== testsuite/tests/numeric/should_run/T22282A.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE MagicHash #-} +module T22282A where + +import Data.Word +import GHC.Prim +import GHC.Word + +wtestF :: GHC.Prim.Word8# -> GHC.Prim.Word8# -> GHC.Prim.Word8# +wtestF a b = case word8ToWord# b of + 0## -> a + _ -> plusWord8# (timesWord8# (quotWord8# a b) b) (remWord8# a b) +{-# NOINLINE wtestF #-} + +testF :: Word8 -> Word8 -> Word8 +testF (W8# a) (W8# b) = W8# (wtestF a b) +{-# INLINE testF #-} + ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,3 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) +test('T22282', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ffe77879ac77a6be61b9efbc8d739b70f08a0c6...545ce44fb3d1c0b501c6bd8fd636494c980807a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ffe77879ac77a6be61b9efbc8d739b70f08a0c6...545ce44fb3d1c0b501c6bd8fd636494c980807a2 You're receiving 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 Oct 17 10:14:31 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 06:14:31 -0400 Subject: [Git][ghc/ghc][wip/fix-ubx-cast] Properly convert values before/after storing them in unboxed sums. Message-ID: <634d2b0739218_8b90f517d4386037@gitlab.mail> Andreas Klebinger pushed to branch wip/fix-ubx-cast at Glasgow Haskell Compiler / GHC Commits: fbdb8889 by Andreas Klebinger at 2022-10-17T12:11:21+02:00 Properly convert values before/after storing them in unboxed sums. See Note [Casting slot arguments] for the details. - - - - - 17 changed files: - + compiler/GHC/Builtin/PrimOps/Casts.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/Types/RepType.hs - compiler/GHC/Utils/Outputable.hs - compiler/ghc.cabal.in - docs/users_guide/debugging.rst - testsuite/driver/testlib.py - + testsuite/tests/unboxedsums/GenManyUbxSums.hs - + testsuite/tests/unboxedsums/ManyUbxSums.stdout - + testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs - + testsuite/tests/unboxedsums/T22208.hs - testsuite/tests/unboxedsums/all.T Changes: ===================================== compiler/GHC/Builtin/PrimOps/Casts.hs ===================================== @@ -0,0 +1,213 @@ +{- +This module contains helpers to cast variables +between different Int/WordReps in StgLand. + +-} + +module GHC.Builtin.PrimOps.Casts + ( getCasts ) +where + +import GHC.Prelude + +import GHC.Core.TyCon +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Utils.Panic.Plain +import GHC.Types.RepType +import GHC.Core.Type +import GHC.Builtin.Types.Prim +import GHC.Builtin.Types + +import GHC.Builtin.PrimOps +import GHC.Plugins (HasDebugCallStack) + +{- Note [PrimRep based casting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This module contains a number of utility functions useful when +converting between variables of differing PrimReps. + +The general pattern is: +* We have two primReps `from_rep` and `to_rep`. +* We want a list of PrimOps we can apply to a variable of rep `from_rep`. +Applying the list of primOps in order takes us to `to_rep` from `from_rep` giving +us a variable of the returned type at each step. + +E.g. we call `getCasts from_rep to_rep` and get back [(op1#,ty1),(op2#,ty2)]. +We can use this list of primOps to construct a function of type +`StgExpr -> StgExpr` by construction an expression + + case op1# of (x' :: ty1) -> case op2# x' of x' -> + +Ideally backends will compile the sequence of PrimOps to a no-op. E.g. by reusing +the same register but just relabeling it as another width. +However this is might not always be possible or the required optimizations +simply not implemented in the backend. This means currently many of these casts +will be cheap but not all of them will be completely zero-cost. + +-} + +-- | `getCasts from_rep to_rep` gives us a list of primops which when applied in order convert from_rep to to_rep. +-- See Note [PrimRep based casting] +getCasts :: PrimRep -> PrimRep -> [(PrimOp,Type)] +getCasts from_rep to_rep + -- No-op + | -- pprTrace "getCasts" (ppr (from_rep,to_rep)) $ + to_rep == from_rep + = [] + + -- Float <-> Double + | to_rep == FloatRep = + assertPpr (from_rep == DoubleRep) (ppr from_rep <+> ppr to_rep) $ + [(DoubleToFloatOp,floatPrimTy)] + | to_rep == DoubleRep = + assertPpr (from_rep == FloatRep) (ppr from_rep <+> ppr to_rep) $ + [(FloatToDoubleOp,doublePrimTy)] + + -- Addr <-> Word/Int + | to_rep == AddrRep = wordOrIntToAddrRep from_rep + | from_rep == AddrRep = addrToWordOrIntRep to_rep + + -- Int* -> Int* + | primRepIsInt from_rep + , primRepIsInt to_rep + = sizedIntToSizedInt from_rep to_rep + + -- Word* -> Word* + | primRepIsWord from_rep + , primRepIsWord to_rep + = sizedWordToSizedWord from_rep to_rep + + -- Word* -> Int* + | primRepIsWord from_rep + , primRepIsInt to_rep + = let (op1,r1) = wordToIntRep from_rep + in (op1,primRepToType r1):sizedIntToSizedInt r1 to_rep + + -- Int* -> Word* + | primRepIsInt from_rep + , primRepIsWord to_rep + = let (op1,r1) = intToWordRep from_rep + in (op1,primRepToType r1):sizedWordToSizedWord r1 to_rep + + | otherwise = pprPanic "getCasts:Unexpect rep combination" + (ppr (from_rep,to_rep)) + +wordOrIntToAddrRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)] +wordOrIntToAddrRep AddrRep = [] -- No-op argument is already AddrRep +wordOrIntToAddrRep IntRep = [(IntToAddrOp, addrPrimTy)] +wordOrIntToAddrRep WordRep = [(WordToIntOp,intPrimTy), (IntToAddrOp,addrPrimTy)] +wordOrIntToAddrRep r + | primRepIsInt r = (intToMachineInt r,intPrimTy):[(IntToAddrOp,addrPrimTy)] + | primRepIsWord r = + let (op1,r1) = wordToIntRep r + in (op1, primRepToType r1):[(intToMachineInt r1,intPrimTy), (IntToAddrOp,addrPrimTy)] + | otherwise = pprPanic "Rep not word or int rep" (ppr r) + +addrToWordOrIntRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)] +-- Machine sizes +addrToWordOrIntRep IntRep = [(AddrToIntOp, intPrimTy)] +addrToWordOrIntRep WordRep = [(AddrToIntOp,intPrimTy), (IntToWordOp,wordPrimTy)] +-- Explicitly sized reps +addrToWordOrIntRep r + | primRepIsWord r = (AddrToIntOp,intPrimTy) : (IntToWordOp,wordPrimTy) : sizedWordToSizedWord WordRep r + | primRepIsInt r = (AddrToIntOp,intPrimTy) : sizedIntToSizedInt IntRep r + | otherwise = pprPanic "Target rep not word or int rep" (ppr r) + + +-- WordX# -> IntX# (same size), argument is source rep +wordToIntRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep) +wordToIntRep rep + = case rep of + (WordRep) -> (WordToIntOp, IntRep) + (Word8Rep) -> (Word8ToInt8Op, Int8Rep) + (Word16Rep) -> (Word16ToInt16Op, Int16Rep) + (Word32Rep) -> (Word32ToInt32Op, Int32Rep) + (Word64Rep) -> (Word64ToInt64Op, Int64Rep) + _ -> pprPanic "Rep not a wordRep" (ppr rep) + +-- IntX# -> WordX#, argument is source rep +intToWordRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep) +intToWordRep rep + = case rep of + (IntRep) -> (IntToWordOp, WordRep) + (Int8Rep) -> (Int8ToWord8Op, Word8Rep) + (Int16Rep) -> (Int16ToWord16Op, Word16Rep) + (Int32Rep) -> (Int32ToWord32Op, Word32Rep) + (Int64Rep) -> (Int64ToWord64Op, Word64Rep) + _ -> pprPanic "Rep not a wordRep" (ppr rep) + +-- Casts between any size int to any other size of int +sizedIntToSizedInt :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)] +sizedIntToSizedInt r1 r2 + | r1 == r2 = [] +-- Cast to Int# +sizedIntToSizedInt r IntRep = [(intToMachineInt r,intTy)] +-- Cast from Int# +sizedIntToSizedInt IntRep r = [(intFromMachineInt r,primRepToType r)] +-- Sized to differently sized must go over machine word. +sizedIntToSizedInt r1 r2 = (intToMachineInt r1,intTy) : [(intFromMachineInt r2,primRepToType r2)] + +-- Casts between any size Word to any other size of Word +sizedWordToSizedWord :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)] +sizedWordToSizedWord r1 r2 + | r1 == r2 = [] +-- Cast to Word# +sizedWordToSizedWord r WordRep = [(wordToMachineWord r,wordPrimTy)] +-- Cast from Word# +sizedWordToSizedWord WordRep r = [(wordFromMachineWord r, primRepToType r)] +-- Conversion between different non-machine sizes must go via machine word. +sizedWordToSizedWord r1 r2 = (wordToMachineWord r1,wordPrimTy) : [(wordFromMachineWord r2, primRepToType r2)] + + +-- Prefer the definitions above this line if possible +---------------------- + + +-- Int*# to Int# +{-# INLINE intToMachineInt #-} +intToMachineInt :: HasDebugCallStack => PrimRep -> PrimOp +intToMachineInt r = + assertPpr (primRepIsInt r) (ppr r) $ + case r of + (Int8Rep) -> Int8ToIntOp + (Int16Rep) -> Int16ToIntOp + (Int32Rep) -> Int32ToIntOp + (Int64Rep) -> Int64ToIntOp + _ -> pprPanic "Source rep not int" $ ppr r + +-- Int# to Int*# +{-# INLINE intFromMachineInt #-} +intFromMachineInt :: HasDebugCallStack => PrimRep -> PrimOp +intFromMachineInt r = + assertPpr (primRepIsInt r) (ppr r) $ + case r of + Int8Rep -> IntToInt8Op + Int16Rep -> IntToInt16Op + Int32Rep -> IntToInt32Op + Int64Rep -> IntToInt64Op + _ -> pprPanic "Dest rep not sized int" $ ppr r + +-- Word# to Word*# +{-# INLINE wordFromMachineWord #-} +wordFromMachineWord :: HasDebugCallStack => PrimRep -> PrimOp +wordFromMachineWord r = + assert (primRepIsWord r) $ + case r of + Word8Rep -> WordToWord8Op + Word16Rep -> WordToWord16Op + Word32Rep -> WordToWord32Op + Word64Rep -> WordToWord64Op + _ -> pprPanic "Dest rep not sized word" $ ppr r + +-- Word*# to Word# +{-# INLINE wordToMachineWord #-} +wordToMachineWord :: HasDebugCallStack => PrimRep -> PrimOp +wordToMachineWord r = + assertPpr (primRepIsWord r) (text "Not a word rep:" <> ppr r) $ + case r of + Word8Rep -> Word8ToWordOp + Word16Rep -> Word16ToWordOp + Word32Rep -> Word32ToWordOp + Word64Rep -> Word64ToWordOp + _ -> pprPanic "Dest rep not sized word" $ ppr r \ No newline at end of file ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1399,7 +1399,10 @@ instance OutputableP Platform CLabel where pdoc !platform lbl = getPprStyle $ \pp_sty -> case pp_sty of PprDump{} -> pprCLabel platform CStyle lbl - _ -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl) + -- Workaround for #22218 + _ -> (pprCLabel platform CStyle lbl) + -- _ -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl) + pprCLabel :: Platform -> LabelStyle -> CLabel -> SDoc pprCLabel !platform !sty lbl = -- see Note [Bangs in CLabel] ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -129,6 +129,7 @@ module GHC.Core.TyCon( primRepIsFloat, primRepsCompatible, primRepCompatible, + primRepIsWord, primRepIsInt, ) where @@ -1785,6 +1786,24 @@ primRepIsFloat DoubleRep = Just True primRepIsFloat (VecRep _ _) = Nothing primRepIsFloat _ = Just False +-- Rep is one of the word reps. +primRepIsWord :: PrimRep -> Bool +primRepIsWord WordRep = True +primRepIsWord (Word8Rep) = True +primRepIsWord (Word16Rep) = True +primRepIsWord (Word32Rep) = True +primRepIsWord (Word64Rep) = True +primRepIsWord _ = False + +-- Rep is one of the int reps. +primRepIsInt :: PrimRep -> Bool +primRepIsInt (IntRep) = True +primRepIsInt (Int8Rep) = True +primRepIsInt (Int16Rep) = True +primRepIsInt (Int32Rep) = True +primRepIsInt (Int64Rep) = True +primRepIsInt _ = False + {- ************************************************************************ * * ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -422,6 +422,7 @@ data GeneralFlag -- variables that have otherwise identical names. | Opt_SuppressUniques | Opt_SuppressStgExts + | Opt_SuppressStgReps | Opt_SuppressTicks -- Replaces Opt_PprShowTicks | Opt_SuppressTimestamps -- ^ Suppress timestamps in dumps | Opt_SuppressCoreSizes -- ^ Suppress per binding Core size stats in dumps ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2393,6 +2393,7 @@ dynamic_flags_deps = [ setGeneralFlag Opt_SuppressIdInfo setGeneralFlag Opt_SuppressTicks setGeneralFlag Opt_SuppressStgExts + setGeneralFlag Opt_SuppressStgReps setGeneralFlag Opt_SuppressTypeSignatures setGeneralFlag Opt_SuppressCoreSizes setGeneralFlag Opt_SuppressTimestamps) @@ -3344,6 +3345,7 @@ dFlagsDeps = [ depFlagSpec' "suppress-stg-free-vars" Opt_SuppressStgExts (useInstead "-d" "suppress-stg-exts"), flagSpec "suppress-stg-exts" Opt_SuppressStgExts, + flagSpec "suppress-stg-reps" Opt_SuppressStgReps, flagSpec "suppress-coercions" Opt_SuppressCoercions, flagSpec "suppress-coercion-types" Opt_SuppressCoercionTypes, flagSpec "suppress-idinfo" Opt_SuppressIdInfo, @@ -3796,7 +3798,8 @@ defaultFlags settings Opt_VersionMacros, Opt_RPath, Opt_DumpWithWays, - Opt_CompactUnwind + Opt_CompactUnwind, + Opt_SuppressStgReps ] ++ [f | (ns,f) <- optLevelFlags, 0 `elem` ns] @@ -5020,6 +5023,7 @@ initSDocContext dflags style = SDC , sdocSuppressUniques = gopt Opt_SuppressUniques dflags , sdocSuppressModulePrefixes = gopt Opt_SuppressModulePrefixes dflags , sdocSuppressStgExts = gopt Opt_SuppressStgExts dflags + , sdocSuppressStgReps = gopt Opt_SuppressStgReps dflags , sdocErrorSpans = gopt Opt_ErrorSpans dflags , sdocStarIsType = xopt LangExt.StarIsType dflags , sdocLinearTypes = xopt LangExt.LinearTypes dflags ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -87,7 +87,7 @@ import GHC.Core.Ppr( {- instances -} ) import GHC.Builtin.PrimOps ( PrimOp, PrimCall ) import GHC.Core.TyCon ( PrimRep(..), TyCon ) import GHC.Core.Type ( Type ) -import GHC.Types.RepType ( typePrimRep1 ) +import GHC.Types.RepType ( typePrimRep1, typePrimRep ) import GHC.Utils.Panic.Plain {- @@ -740,12 +740,23 @@ pprStgTopBinding = pprGenStgTopBinding pprStgTopBindings :: OutputablePass pass => StgPprOpts -> [GenStgTopBinding pass] -> SDoc pprStgTopBindings = pprGenStgTopBindings +pprIdWithRep :: Id -> SDoc +pprIdWithRep v = ppr v <> pprTypeRep (idType v) + +pprTypeRep :: Type -> SDoc +pprTypeRep ty = + ppUnlessOption sdocSuppressStgReps $ + char ':' <> case typePrimRep ty of + [r] -> ppr r + r -> ppr r + + instance Outputable StgArg where ppr = pprStgArg pprStgArg :: StgArg -> SDoc -pprStgArg (StgVarArg var) = ppr var -pprStgArg (StgLitArg con) = ppr con +pprStgArg (StgVarArg var) = pprIdWithRep var +pprStgArg (StgLitArg con) = ppr con <> pprTypeRep (literalType con) instance OutputablePass pass => Outputable (GenStgExpr pass) where ppr = pprStgExpr panicStgPprOpts ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -186,6 +186,132 @@ So we pass type arguments of the DataCon's TyCon in StgConApp to decide what layout to use. Note that unlifted values can't be let-bound, so we don't need types in StgRhsCon. +Note [Casting slot arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider this function which selects between Float# and Double# from a unboxed sum. + + foo :: (# Float# | Double# #) -> FD + foo x = case x of + (# x1 | #) -> F x1 + (# | x2 #) -> D x2 + +Naturally we would expect x1 to have a PrimRep of FloatRep and x2 of DoubleRep. +However we used to generate this (bogus) code after Unarise giving rise to #22208: + + M.foo :: (# GHC.Prim.Float# | GHC.Prim.Double# #) -> M.FD + [GblId, Arity=1, Unf=OtherCon []] = + {} \r [sum_tag sum_field] + case sum_tag of tag_gsc { + __DEFAULT -> M.F [sum_field]; + 2# -> M.D [sum_field]; + }; + +Where sum_field is used both as Float# and Double# depending on the branch +because they share the same SlotTy. +This usually works out since we put floats/doubles in the same sort of register. +However this caused issues down the road where we would assign between variables +of different reps causing lint errors or in the case of #22208 even compiler panics. +For now our solution is to construct proper casts between the PrimRep of the slot and +the variables we want to store in, or read out of these slots. + +This means when we have a sum (# Float# | Double# #) if we want to store a float +we convert it to a double on construction of the tuple value, and convert it back +to a float once when want to use the field. +Conversion for values coming out of a strict field happen in mapSumIdBinders. While +conversion during the construction of sums happen inside mkUbxSum. + +------------- A full example of casting during sum construction ---------------- + +To give a full example if we *construct* a unboxed sum of +type (# Int32# | Int64# ) in an expression like `let sum = (# | #) x` +Then we will call mkUbxSum to determine which arguments we have to pass in which +order to the unboxed tuple that represents the unboxed sum. + +Int32# and Int# in this case will share the same slot in the unboxed sum. This +means we want to upcast the argument in order to match up the reps of the +variables. To do this mkUbxSum will produce a casting expression with a hole for +the original rhs to go into. That is the call to mkUbxSum and it's result will +look something like: + + >>> mkUbxSum (#|#) [Int32#, Int#] (x::Int32#) us(x') + ([x'::Double#], case int32ToInt# x of x' -> <_hole_> ) + +We will use the returned arguments to construct an application to an unboxed tuple: + + (# #) 1# x' + +Which we will then use to construct an expression that casts `x` to the right type +and places it into x': + + >>> (\_hole_ -> case int32ToInt# x of x' -> _hole_) ((# #) 1# x') + case int32ToInt# x of x' -> (# #) 1# x' + +Which results in the this definition for `sum` after all is said and done: + + let sum = case int32ToInt# x of { x' -> (# #) 1# x' } + +You might wonder why we bother renaming `x` to `x'`. It's quite subtle. Consider +a definition like this: + + let sum_shadow :: (# (# Int32#, Int32# ) | Int64# #) + let sum_shadow = (# |#) (# x, x #) + +We compute the required slots for the tuple and come up with +`[WordSlot, Word64Slot]`. For the first sum constructor we will place `x` both +in a Word and a Word64Slot. If we would not rename the constructor what we would +get would be: + + let sum_shadow = case int32ToInt# x of + { x -> + (# #) 1# x x -- With the unboxed tuple having type (# #) :: (# Int#, Int#, Int64 #) + } + +Clearly this is somewhat bogus, we would end up using the same `x` as a +Int# and a Int64# value! + +------------- A full example of casting during sum matching -------------------- + +When matching on the same unboxed sum constructor as above we start out with +something like this the pre-unarise: + + f sum = case sum of + (# x |#) -> ... x ... -- (# x |#) :: (# Int32, Int#) + ... + +We start desugaring and get: + + f sum_tag sum_slot_arg_1 = case sum_tag of + 1# -> ??? + +Now we need to match the slot arguments to binders in the original case +alternative. This is done by mapSumIdBinders which we we call for our +example alternative like this: + + >>> mapSumIdBinders [x] [sum_slot_arg_1] alt_rhs env + (env', alt_rhs') + +mapSumIdBinders first matches up the list of binders with the slots passed to +the function which is trivial in this case. Then we check if the slot and the +variable residing inside it agree on their Rep. If all binders and slot reps +agree we just extend the environment with a mapping from `x` to `sum_slot_arg_1` +and we return the rhs as is. +If the reps do not agree then we wrap the whole RHS in a case which casts the +bound variable to a type of the correct representation. Here `x` is of Int32Rep +while `sum_slot_arg_1` will be of IntRep. This means instead of retuning the +original alt_rhs we will return: + + case intToInt32# (x :: Int#) of + (x :: Int32#) -> original_alt_rhs + +We then run unarise on this expression, which will replace the first occurence +of `x` with sum_slot_arg_1 giving us post-unarise: + + f sum_tag sum_slot_arg_1 = + case sum_tag of + 1# -> case intToInt32# sum_slot_arg_1 of + x -> ... x ... + ... + Note [UnariseEnv] ~~~~~~~~~~~~~~~~~~ At any variable occurrence 'v', @@ -258,8 +384,8 @@ import GHC.Prelude import GHC.Types.Basic import GHC.Core import GHC.Core.DataCon -import GHC.Core.TyCon ( isVoidRep ) -import GHC.Data.FastString (FastString, mkFastString) +import GHC.Core.TyCon +import GHC.Data.FastString (FastString, mkFastString, fsLit, appendFS) import GHC.Types.Id import GHC.Types.Literal import GHC.Core.Make (aBSENT_SUM_FIELD_ERROR_ID) @@ -281,6 +407,10 @@ import GHC.Types.Var.Env import Data.Bifunctor (second) import Data.Maybe (mapMaybe) import qualified Data.IntMap as IM +import GHC.Builtin.PrimOps +import GHC.Builtin.PrimOps.Casts +import Data.List (mapAccumL) +import GHC.Types.Name -------------------------------------------------------------------------------- @@ -306,8 +436,10 @@ import qualified Data.IntMap as IM -- INVARIANT: OutStgArgs in the range only have NvUnaryTypes -- (i.e. no unboxed tuples, sums or voids) -- -type UnariseEnv = VarEnv UnariseVal +newtype UnariseEnv = UnariseEnv { ue_rho :: (VarEnv UnariseVal) } +initUnariseEnv :: VarEnv UnariseVal -> UnariseEnv +initUnariseEnv = UnariseEnv data UnariseVal = MultiVal [OutStgArg] -- MultiVal to tuple. Can be empty list (void). | UnaryVal OutStgArg -- See Note [Renaming during unarisation]. @@ -320,25 +452,27 @@ instance Outputable UnariseVal where -- The id is mapped to one or more things. -- See Note [UnariseEnv] extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv -extendRho rho x (MultiVal args) +extendRho env x (MultiVal args) = assert (all (isNvUnaryType . stgArgType) args) - extendVarEnv rho x (MultiVal args) -extendRho rho x (UnaryVal val) + env { ue_rho = extendVarEnv (ue_rho env) x (MultiVal args) } +extendRho env x (UnaryVal val) = assert (isNvUnaryType (stgArgType val)) - extendVarEnv rho x (UnaryVal val) + env { ue_rho = extendVarEnv (ue_rho env) x (UnaryVal val) } -- Properly shadow things from an outer scope. -- See Note [UnariseEnv] -- The id stands for itself so we don't record a mapping. -- See Note [UnariseEnv] extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv -extendRhoWithoutValue rho x = delVarEnv rho x +extendRhoWithoutValue env x = env { ue_rho = delVarEnv (ue_rho env) x } +lookupRho :: UnariseEnv -> Id -> Maybe UnariseVal +lookupRho env v = lookupVarEnv (ue_rho env) v -------------------------------------------------------------------------------- unarise :: UniqSupply -> [StgTopBinding] -> [StgTopBinding] -unarise us binds = initUs_ us (mapM (unariseTopBinding emptyVarEnv) binds) +unarise us binds = initUs_ us (mapM (unariseTopBinding (initUnariseEnv emptyVarEnv)) binds) unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding unariseTopBinding rho (StgTopLifted bind) @@ -366,7 +500,7 @@ unariseRhs rho (StgRhsCon ccs con mu ts args) unariseExpr :: UnariseEnv -> StgExpr -> UniqSM StgExpr unariseExpr rho e@(StgApp f []) - = case lookupVarEnv rho f of + = case lookupRho rho f of Just (MultiVal args) -- Including empty tuples -> return (mkTuple args) Just (UnaryVal (StgVarArg f')) @@ -379,7 +513,7 @@ unariseExpr rho e@(StgApp f []) unariseExpr rho e@(StgApp f args) = return (StgApp f' (unariseFunArgs rho args)) where - f' = case lookupVarEnv rho f of + f' = case lookupRho rho f of Just (UnaryVal (StgVarArg f')) -> f' Nothing -> f err -> pprPanic "unariseExpr - app2" (pprStgExpr panicStgPprOpts e $$ ppr err) @@ -390,12 +524,17 @@ unariseExpr _ (StgLit l) = return (StgLit l) unariseExpr rho (StgConApp dc n args ty_args) - | Just args' <- unariseMulti_maybe rho dc args ty_args - = return (mkTuple args') - - | otherwise - , let args' = unariseConArgs rho args - = return (StgConApp dc n args' (map stgArgType args')) + | isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc + = do + us <- getUniqueSupplyM + case unariseUbxSumOrTupleArgs rho us dc args ty_args of + (args', Just cast_wrapper) + -> return $ cast_wrapper (mkTuple args') + (args', Nothing) + -> return $ (mkTuple args') + | otherwise = + let args' = unariseConArgs rho args in + return $ (StgConApp dc n args' (map stgArgType args')) unariseExpr rho (StgOpApp op args ty) = return (StgOpApp op (unariseFunArgs rho args) ty) @@ -403,15 +542,19 @@ unariseExpr rho (StgOpApp op args ty) unariseExpr rho (StgCase scrut bndr alt_ty alts) -- tuple/sum binders in the scrutinee can always be eliminated | StgApp v [] <- scrut - , Just (MultiVal xs) <- lookupVarEnv rho v + , Just (MultiVal xs) <- lookupRho rho v = elimCase rho xs bndr alt_ty alts -- Handle strict lets for tuples and sums: -- case (# a,b #) of r -> rhs -- and analogously for sums | StgConApp dc _n args ty_args <- scrut - , Just args' <- unariseMulti_maybe rho dc args ty_args - = elimCase rho args' bndr alt_ty alts + , isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc + = do + us <- getUniqueSupplyM + case unariseUbxSumOrTupleArgs rho us dc args ty_args of + (args',Just wrapper) -> wrapper <$> elimCase rho args' bndr alt_ty alts + (args',Nothing) -> elimCase rho args' bndr alt_ty alts -- See (3) of Note [Rubbish literals] in GHC.Types.Literal | StgLit lit <- scrut @@ -436,17 +579,21 @@ unariseExpr rho (StgTick tick e) = StgTick tick <$> unariseExpr rho e -- Doesn't return void args. -unariseMulti_maybe :: UnariseEnv -> DataCon -> [InStgArg] -> [Type] -> Maybe [OutStgArg] -unariseMulti_maybe rho dc args ty_args +unariseUbxSumOrTupleArgs :: UnariseEnv -> UniqSupply -> DataCon -> [InStgArg] -> [Type] + -> ( [OutStgArg] -- Arguments representing the unboxed sum + , Maybe (StgExpr -> StgExpr)) -- Transformation to apply to the arguments, to bring them + -- into the right Rep +unariseUbxSumOrTupleArgs rho us dc args ty_args | isUnboxedTupleDataCon dc - = Just (unariseConArgs rho args) + = (unariseConArgs rho args, Nothing) | isUnboxedSumDataCon dc , let args1 = assert (isSingleton args) (unariseConArgs rho args) - = Just (mkUbxSum dc ty_args args1) + = let (args2, cast_wrapper) = mkUbxSum dc ty_args args1 us + in (args2, Just cast_wrapper) | otherwise - = Nothing + = panic "unariseUbxSumOrTupleArgs: Constructor not a unboxed sum or tuple" -- Doesn't return void args. unariseRubbish_maybe :: Literal -> Maybe [OutStgArg] @@ -473,15 +620,15 @@ elimCase rho args bndr (MultiValAlt _) [GenStgAlt{ alt_con = _ , alt_bndrs = bndrs , alt_rhs = rhs}] = do let rho1 = extendRho rho bndr (MultiVal args) - rho2 + (rho2, rhs') | isUnboxedTupleBndr bndr - = mapTupleIdBinders bndrs args rho1 + = (mapTupleIdBinders bndrs args rho1, rhs) | otherwise = assert (isUnboxedSumBndr bndr) $ - if null bndrs then rho1 - else mapSumIdBinders bndrs args rho1 + if null bndrs then (rho1, rhs) + else mapSumIdBinders bndrs args rhs rho1 - unariseExpr rho2 rhs + unariseExpr rho2 rhs' elimCase rho args bndr (MultiValAlt _) alts | isUnboxedSumBndr bndr @@ -576,12 +723,12 @@ unariseSumAlt rho args GenStgAlt{ alt_con = DataAlt sumCon , alt_bndrs = bs , alt_rhs = e } - = do let rho' = mapSumIdBinders bs args rho - lit_case = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon))) - GenStgAlt lit_case mempty <$> unariseExpr rho' e + = do let (rho',e') = mapSumIdBinders bs args e rho + lit_case = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon))) + GenStgAlt lit_case mempty <$> unariseExpr rho' e' unariseSumAlt _ scrt alt - = pprPanic "unariseSumAlt" (ppr scrt $$ pprPanicAlt alt) + = pprPanic "unariseSumAlt3" (ppr scrt $$ pprPanicAlt alt) -------------------------------------------------------------------------------- @@ -623,24 +770,80 @@ mapSumIdBinders -- only have one binder, so this list should be a singleton) -> [OutStgArg] -- Arguments that form the sum (NOT including the tag). -- Can't have void args. + -> InStgExpr -> UnariseEnv - -> UnariseEnv + -> (UnariseEnv, OutStgExpr) -mapSumIdBinders [id] args rho0 +mapSumIdBinders [id] args rhs rho0 = assert (not (any (isZeroBitTy . stgArgType) args)) $ let + -- Slots representing the whole sum arg_slots = map primRepSlot $ concatMap (typePrimRep . stgArgType) args + -- The slots representing the field of the sum we bind. id_slots = map primRepSlot $ typePrimRep (idType id) layout1 = layoutUbxSum arg_slots id_slots + + -- See Note [Casting slot arguments] + -- Arg id's which make up the field. + id_arg_exprs = [ args !! i | i <- layout1 ] + id_vars = [v | StgVarArg v <- id_arg_exprs] + + update_id_type v ty + | (typePrimRep $ idType v) == (typePrimRep ty) = v + | otherwise = setIdType v ty + + -- types for the field binders based on their rep + id_tys = map primRepToType $ typePrimRep (idType id) + -- Arg id's with the typ set to one matching the fields rep. + typed_id_args = zipWithEqual "typed_id_args" (\var t -> StgVarArg (update_id_type var t)) id_vars id_tys + -- We can shadow the original argument id here since the binder for the field will only be used + -- at one specific type in this branch. + (rhs_with_casts) = foldr castArgShadow rhs $ zip id_vars id_tys in + -- pprTrace "mapSumIdBinders" + -- (text "id_tys" <+> ppr id_tys $$ + -- text "id_args" <+> ppr id_arg_exprs $$ + -- text "rhs" <+> ppr rhs $$ + -- text "rhs_with_casts" <+> ppr rhs_with_casts + -- ) $ if isMultiValBndr id - then extendRho rho0 id (MultiVal [ args !! i | i <- layout1 ]) - else assert (layout1 `lengthIs` 1) - extendRho rho0 id (UnaryVal (args !! head layout1)) + then (extendRho rho0 id (MultiVal typed_id_args), rhs_with_casts) + else assert (typed_id_args `lengthIs` 1) + (extendRho rho0 id (UnaryVal (head typed_id_args)), rhs_with_casts) -mapSumIdBinders ids sum_args _ +mapSumIdBinders ids sum_args _rhs _ = pprPanic "mapSumIdBinders" (ppr ids $$ ppr sum_args) +-- Convert the argument to the given type, and wrap the case doing the +-- conversion around the given expression. +castArgShadow :: (Id,Type) -> StgExpr -> StgExpr +castArgShadow (arg, target_ty) (in_rhs) = + let ops = getCasts (typePrimRep1 $ idType arg) (typePrimRep1 target_ty) + in foldr (mkCast (StgVarArg arg) arg) (in_rhs) ops + +-- Convert the argument to the given type, and wrap the conversion +-- around the given expression. Use the given Id as a name for the +-- converted value. +castArgRename :: StgArg -> Id -> StgExpr -> StgExpr +castArgRename in_arg out_id in_rhs = + case ops of + [] -> in_rhs + op1:rest_ops -> + mkCast in_arg out_id op1 $ + foldr (mkCast (StgVarArg out_id) out_id) in_rhs rest_ops + -- pprTrace "castArgRename" (ppr (in_arg,out_id)) $ + where ops = getCasts (typePrimRep1 $ stgArgType in_arg) $ typePrimRep1 (idType out_id) + -- in foldr (mkCast in_arg out_id) (in_rhs) ops + +-- Variable to cast, (type to cast to, result_ty), rhs +mkCast :: StgArg -> OutId -> (PrimOp,Type) -> (StgExpr) -> (StgExpr) +mkCast arg_in out_id (cast_op,ty2) (in_rhs) = + let r2 = typePrimRep1 ty2 + scrut = StgOpApp (StgPrimOp cast_op) [arg_in] ty2 + alt = GenStgAlt { alt_con = DEFAULT, alt_bndrs = [], alt_rhs = in_rhs} + alt_ty = PrimAlt r2 + in (StgCase scrut (setIdType out_id ty2) alt_ty [alt]) + -- | Build a unboxed sum term from arguments of an alternative. -- -- Example, for (# x | #) :: (# (# #) | Int #) we call @@ -655,8 +858,11 @@ mkUbxSum :: DataCon -- Sum data con -> [Type] -- Type arguments of the sum data con -> [OutStgArg] -- Actual arguments of the alternative. - -> [OutStgArg] -- Final tuple arguments -mkUbxSum dc ty_args args0 + -> UniqSupply + -> ([OutStgArg] -- Final tuple arguments + ,(StgExpr->StgExpr) -- We might need to cast the args first + ) +mkUbxSum dc ty_args args0 us = let (_ : sum_slots) = ubxSumRepType (map typePrimRep ty_args) -- drop tag slot @@ -667,16 +873,50 @@ mkUbxSum dc ty_args args0 tag_arg = StgLitArg (LitNumber LitNumInt (fromIntegral tag)) arg_idxs = IM.fromList (zipEqual "mkUbxSum" layout' args0) - mkTupArgs :: Int -> [SlotTy] -> IM.IntMap StgArg -> [StgArg] - mkTupArgs _ [] _ - = [] - mkTupArgs arg_idx (slot : slots_left) arg_map - | Just stg_arg <- IM.lookup arg_idx arg_map - = stg_arg : mkTupArgs (arg_idx + 1) slots_left arg_map - | otherwise - = ubxSumRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map + ((_idx,_idx_map,_us,wrapper),slot_args) + = assert (length arg_idxs <= length sum_slots ) $ + mapAccumL mkTupArg (0,arg_idxs,us,id) sum_slots + + mkTupArg :: (Int, IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr) + -> SlotTy + -> ((Int,IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr), StgArg) + mkTupArg (arg_idx, arg_map, us, wrapper) slot + | Just stg_arg <- IM.lookup arg_idx arg_map + = case castArg us slot stg_arg of + Just (casted_arg,us',wrapper') -> + ( (arg_idx+1, arg_map, us', wrapper') + , casted_arg) + Nothing -> + ( (arg_idx+1, arg_map, us, wrapper) + , stg_arg) + | otherwise + = ( (arg_idx+1, arg_map, us, wrapper) + , ubxSumRubbishArg slot) + + castArg :: UniqSupply -> SlotTy -> StgArg -> Maybe (StgArg,UniqSupply,StgExpr -> StgExpr) + castArg us slot_ty arg + -- Cast the argument to the type of the slot if required + | slotPrimRep slot_ty /= typePrimRep1 (stgArgType arg) + = let (u1,us') = takeUniqFromSupply us + out_ty = primRepToType $ slotPrimRep slot_ty + out_name_fs + | (StgVarArg v_arg) <- arg + = getOccFS v_arg `appendFS` fsLit "_cst" + | otherwise = fsLit "cst_lit" + out_id = mkSysLocal out_name_fs u1 Many out_ty :: Id + casts = castArgRename arg out_id :: StgExpr -> StgExpr + in Just (arg,us',casts) + -- No need for casting + | otherwise = Nothing + + tup_args = tag_arg : slot_args in - tag_arg : mkTupArgs 0 sum_slots arg_idxs + -- pprTrace "mkUbxSum" ( + -- text "ty_args (slots)" <+> ppr ty_args $$ + -- text "args0" <+> ppr args0 $$ + -- text "wrapper" <+> + -- (ppr $ wrapper $ StgLit $ LitChar '_')) + (tup_args, wrapper) -- | Return a rubbish value for the given slot type. @@ -787,7 +1027,7 @@ unariseArgBinder is_con_arg rho x = -- | MultiVal a function argument. Never returns an empty list. unariseFunArg :: UnariseEnv -> StgArg -> [StgArg] unariseFunArg rho (StgVarArg x) = - case lookupVarEnv rho x of + case lookupRho rho x of Just (MultiVal []) -> [voidArg] -- NB: do not remove void args Just (MultiVal as) -> as Just (UnaryVal arg) -> [arg] @@ -809,7 +1049,7 @@ unariseFunArgBinder = unariseArgBinder False -- | MultiVal a DataCon argument. Returns an empty list when argument is void. unariseConArg :: UnariseEnv -> InStgArg -> [OutStgArg] unariseConArg rho (StgVarArg x) = - case lookupVarEnv rho x of + case lookupRho rho x of Just (UnaryVal arg) -> [arg] Just (MultiVal as) -> as -- 'as' can be empty Nothing ===================================== compiler/GHC/Types/RepType.hs ===================================== @@ -245,7 +245,8 @@ ubxSumRepType constrs0 in sumRep -layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag. +layoutUbxSum :: HasDebugCallStack + => SortedSlotTys -- Layout of sum. Does not include tag. -- We assume that they are in increasing order -> [SlotTy] -- Slot types of things we want to map to locations in the -- sum layout @@ -268,7 +269,8 @@ layoutUbxSum sum_slots0 arg_slots0 = | otherwise = findSlot arg (slot_idx + 1) slots useds findSlot _ _ [] _ - = pprPanic "findSlot" (text "Can't find slot" $$ ppr sum_slots0 $$ ppr arg_slots0) + = pprPanic "findSlot" (text "Can't find slot" $$ text "sum_slots:" <> ppr sum_slots0 + $$ text "arg_slots:" <> ppr arg_slots0 ) -------------------------------------------------------------------------------- ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -387,6 +387,7 @@ data SDocContext = SDC , sdocSuppressUniques :: !Bool , sdocSuppressModulePrefixes :: !Bool , sdocSuppressStgExts :: !Bool + , sdocSuppressStgReps :: !Bool , sdocErrorSpans :: !Bool , sdocStarIsType :: !Bool , sdocLinearTypes :: !Bool @@ -447,6 +448,7 @@ defaultSDocContext = SDC , sdocSuppressUniques = False , sdocSuppressModulePrefixes = False , sdocSuppressStgExts = False + , sdocSuppressStgReps = True , sdocErrorSpans = False , sdocStarIsType = False , sdocLinearTypes = False ===================================== compiler/ghc.cabal.in ===================================== @@ -168,6 +168,7 @@ Library GHC.Builtin.Names GHC.Builtin.Names.TH GHC.Builtin.PrimOps + GHC.Builtin.PrimOps.Casts GHC.Builtin.PrimOps.Ids GHC.Builtin.Types GHC.Builtin.Types.Literals ===================================== docs/users_guide/debugging.rst ===================================== @@ -946,6 +946,16 @@ parts that you are not interested in. Suppress the printing of core size stats per binding +.. ghc-flag:: -dsuppress-stg-reps + :shortdesc: Suppress rep annotations on STG args. + :type: dynamic + + :since: 9.6.1 + + default: enabled + + Disabling this will annoate certain stg arguments with their prim rep. + .. _checking-consistency: ===================================== testsuite/driver/testlib.py ===================================== @@ -1447,7 +1447,8 @@ def compile_cmp_asm(name: TestName, ext: str, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile only, extra args = ', extra_hc_opts) result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): @@ -1474,7 +1475,8 @@ def compile_grep_asm(name: TestName, is_substring: bool, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile and grep asm, extra args = ', extra_hc_opts) result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): @@ -1495,7 +1497,8 @@ def compile_grep_core(name: TestName, way: WayName, extra_hc_opts: str ) -> PassFail: - print('Compile only, extra args = ', extra_hc_opts) + if extra_hc_opts: + print('Compile only, extra args = ', extra_hc_opts) result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): ===================================== testsuite/tests/unboxedsums/GenManyUbxSums.hs ===================================== @@ -0,0 +1,104 @@ +#!/usr/bin/env runghc +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnboxedSums #-} + +-- This little piece of code constructs a large set of functions +-- constructing and deconstructing unboxed tuples of various types. +module Main where + +import GHC.Exts +import System.IO + +inputs = ["Int", "Word"] +sizes = ["","8","16","32","64"] + +-- ["Addr#","Int#","Int8#","Int16#","Int32#","Int64#","Word#","Word8#","Word16#","Word32#","Word64#"] +types = "Addr#" : do + r <- inputs + s <- sizes + return $ r++s++"#" + +-- We eventually build two sums, one of type (# t1 | t2 #) and one of (# t1 | t3). +-- So we build all possible combinations of three types here. +combos = do + t1 <- types + t2 <- types + t3 <- types + return (t1,t2,t3) + +mkCon ty = case ty of + "Addr#" -> "Addr" + "Int#" -> "I#" + "Int8#" -> "I8#" + "Int16#" -> "I16#" + "Int32#" -> "I32#" + "Int64#" -> "I64#" + "Word#" -> "W#" + "Word8#" -> "W8#" + "Word16#" -> "W16#" + "Word32#" -> "W32#" + "Word64#" -> "W64#" + +-- Construct a function like the one below, varying the types in the sums based on the +-- given type tuples. +-- We need to NOINLINE or the function will be constant folded away. +-- {-# NOINLINE fun0 #-} +-- fun0 :: (# Addr# | I16# #) -> (# Addr# | I# #) +-- fun0 x = case x of +-- (# x1 | #) -> (# x1 | #) :: (# Addr# | I# #) +mkFun n (t1,t2,t3) = + "{-# NOINLINE fun" ++ show n ++ " #-}\n" ++ + "fun" ++ show n ++ " :: (# " ++ t1 ++" | " ++ t2 ++ " #) -> (# " ++ t1 ++" | " ++ t3 ++ " #)\n" ++ + "fun" ++ show n ++ " x = case x of\n" ++ + " (# x1 | #) -> (# x1 | #) :: (# " ++ t1 ++ " | " ++ t3 ++ " #)" + +-- Generate functions for all the tuple combinations. +mkFuns _ [] = "" +mkFuns n (combo:combos) = + mkFun n combo ++ "\n" ++ mkFuns (n+1) combos + +-- generate a test that will put a value into a unboxed sum and then retrieve it later on. +-- It generates code like the one below: +-- test0 = +-- let in_val = maxBound +-- out_val = case in_val of I# x -> case fun0 (# x | #) of (# y | #) -> I# y +-- in in_val == out_val +mkTest n (t1,_,_)= + "test" ++ show n ++ " =\n" ++ + " let in_val = (maxBound)\n" ++ + " out_val = case in_val of " ++ mkCon t1 ++ " x -> case fun" ++ show n ++ " (# x | #) of (# y | #) -> " ++ mkCon t1 ++ " y\n" ++ + " in in_val == out_val" + +-- Test all the tuples +mkTests n [] = "" +mkTests n (combo:combos) = + mkTest n combo ++ "\n" ++ mkTests (n+1) combos + + +header = + "{-# LANGUAGE MagicHash #-}\n\ + \{-# LANGUAGE UnboxedTuples #-}\n\ + \{-# LANGUAGE UnboxedSums #-}\n\ + \module Main where\n\ + \import GHC.Exts\n\ + \import GHC.Word\n\ + \import GHC.Int\n\ + \import ManyUbxSums_Addr\n" +main = do + out <- openFile "ManyUbxSums.hs" WriteMode + hPutStrLn out header + + let combo:_ = combos + -- putStrLn $ mkFun 1 combo + hPutStrLn out $ mkFuns 0 combos + + hPutStrLn out $ mkTests 0 combos + hPutStrLn out "main = do" + + -- Actually invoke all the tests + let runTest n = + hPutStrLn out $ " putStrLn $ \"test" ++ show n ++ " \" ++ (show test" ++ show n ++ ")" + mapM runTest [0 .. length combos - 1] + + hClose out ===================================== testsuite/tests/unboxedsums/ManyUbxSums.stdout ===================================== @@ -0,0 +1,1331 @@ +test0 True +test1 True +test2 True +test3 True +test4 True +test5 True +test6 True +test7 True +test8 True +test9 True +test10 True +test11 True +test12 True +test13 True +test14 True +test15 True +test16 True +test17 True +test18 True +test19 True +test20 True +test21 True +test22 True +test23 True +test24 True +test25 True +test26 True +test27 True +test28 True +test29 True +test30 True +test31 True +test32 True +test33 True +test34 True +test35 True +test36 True +test37 True +test38 True +test39 True +test40 True +test41 True +test42 True +test43 True +test44 True +test45 True +test46 True +test47 True +test48 True +test49 True +test50 True +test51 True +test52 True +test53 True +test54 True +test55 True +test56 True +test57 True +test58 True +test59 True +test60 True +test61 True +test62 True +test63 True +test64 True +test65 True +test66 True +test67 True +test68 True +test69 True +test70 True +test71 True +test72 True +test73 True +test74 True +test75 True +test76 True +test77 True +test78 True +test79 True +test80 True +test81 True +test82 True +test83 True +test84 True +test85 True +test86 True +test87 True +test88 True +test89 True +test90 True +test91 True +test92 True +test93 True +test94 True +test95 True +test96 True +test97 True +test98 True +test99 True +test100 True +test101 True +test102 True +test103 True +test104 True +test105 True +test106 True +test107 True +test108 True +test109 True +test110 True +test111 True +test112 True +test113 True +test114 True +test115 True +test116 True +test117 True +test118 True +test119 True +test120 True +test121 True +test122 True +test123 True +test124 True +test125 True +test126 True +test127 True +test128 True +test129 True +test130 True +test131 True +test132 True +test133 True +test134 True +test135 True +test136 True +test137 True +test138 True +test139 True +test140 True +test141 True +test142 True +test143 True +test144 True +test145 True +test146 True +test147 True +test148 True +test149 True +test150 True +test151 True +test152 True +test153 True +test154 True +test155 True +test156 True +test157 True +test158 True +test159 True +test160 True +test161 True +test162 True +test163 True +test164 True +test165 True +test166 True +test167 True +test168 True +test169 True +test170 True +test171 True +test172 True +test173 True +test174 True +test175 True +test176 True +test177 True +test178 True +test179 True +test180 True +test181 True +test182 True +test183 True +test184 True +test185 True +test186 True +test187 True +test188 True +test189 True +test190 True +test191 True +test192 True +test193 True +test194 True +test195 True +test196 True +test197 True +test198 True +test199 True +test200 True +test201 True +test202 True +test203 True +test204 True +test205 True +test206 True +test207 True +test208 True +test209 True +test210 True +test211 True +test212 True +test213 True +test214 True +test215 True +test216 True +test217 True +test218 True +test219 True +test220 True +test221 True +test222 True +test223 True +test224 True +test225 True +test226 True +test227 True +test228 True +test229 True +test230 True +test231 True +test232 True +test233 True +test234 True +test235 True +test236 True +test237 True +test238 True +test239 True +test240 True +test241 True +test242 True +test243 True +test244 True +test245 True +test246 True +test247 True +test248 True +test249 True +test250 True +test251 True +test252 True +test253 True +test254 True +test255 True +test256 True +test257 True +test258 True +test259 True +test260 True +test261 True +test262 True +test263 True +test264 True +test265 True +test266 True +test267 True +test268 True +test269 True +test270 True +test271 True +test272 True +test273 True +test274 True +test275 True +test276 True +test277 True +test278 True +test279 True +test280 True +test281 True +test282 True +test283 True +test284 True +test285 True +test286 True +test287 True +test288 True +test289 True +test290 True +test291 True +test292 True +test293 True +test294 True +test295 True +test296 True +test297 True +test298 True +test299 True +test300 True +test301 True +test302 True +test303 True +test304 True +test305 True +test306 True +test307 True +test308 True +test309 True +test310 True +test311 True +test312 True +test313 True +test314 True +test315 True +test316 True +test317 True +test318 True +test319 True +test320 True +test321 True +test322 True +test323 True +test324 True +test325 True +test326 True +test327 True +test328 True +test329 True +test330 True +test331 True +test332 True +test333 True +test334 True +test335 True +test336 True +test337 True +test338 True +test339 True +test340 True +test341 True +test342 True +test343 True +test344 True +test345 True +test346 True +test347 True +test348 True +test349 True +test350 True +test351 True +test352 True +test353 True +test354 True +test355 True +test356 True +test357 True +test358 True +test359 True +test360 True +test361 True +test362 True +test363 True +test364 True +test365 True +test366 True +test367 True +test368 True +test369 True +test370 True +test371 True +test372 True +test373 True +test374 True +test375 True +test376 True +test377 True +test378 True +test379 True +test380 True +test381 True +test382 True +test383 True +test384 True +test385 True +test386 True +test387 True +test388 True +test389 True +test390 True +test391 True +test392 True +test393 True +test394 True +test395 True +test396 True +test397 True +test398 True +test399 True +test400 True +test401 True +test402 True +test403 True +test404 True +test405 True +test406 True +test407 True +test408 True +test409 True +test410 True +test411 True +test412 True +test413 True +test414 True +test415 True +test416 True +test417 True +test418 True +test419 True +test420 True +test421 True +test422 True +test423 True +test424 True +test425 True +test426 True +test427 True +test428 True +test429 True +test430 True +test431 True +test432 True +test433 True +test434 True +test435 True +test436 True +test437 True +test438 True +test439 True +test440 True +test441 True +test442 True +test443 True +test444 True +test445 True +test446 True +test447 True +test448 True +test449 True +test450 True +test451 True +test452 True +test453 True +test454 True +test455 True +test456 True +test457 True +test458 True +test459 True +test460 True +test461 True +test462 True +test463 True +test464 True +test465 True +test466 True +test467 True +test468 True +test469 True +test470 True +test471 True +test472 True +test473 True +test474 True +test475 True +test476 True +test477 True +test478 True +test479 True +test480 True +test481 True +test482 True +test483 True +test484 True +test485 True +test486 True +test487 True +test488 True +test489 True +test490 True +test491 True +test492 True +test493 True +test494 True +test495 True +test496 True +test497 True +test498 True +test499 True +test500 True +test501 True +test502 True +test503 True +test504 True +test505 True +test506 True +test507 True +test508 True +test509 True +test510 True +test511 True +test512 True +test513 True +test514 True +test515 True +test516 True +test517 True +test518 True +test519 True +test520 True +test521 True +test522 True +test523 True +test524 True +test525 True +test526 True +test527 True +test528 True +test529 True +test530 True +test531 True +test532 True +test533 True +test534 True +test535 True +test536 True +test537 True +test538 True +test539 True +test540 True +test541 True +test542 True +test543 True +test544 True +test545 True +test546 True +test547 True +test548 True +test549 True +test550 True +test551 True +test552 True +test553 True +test554 True +test555 True +test556 True +test557 True +test558 True +test559 True +test560 True +test561 True +test562 True +test563 True +test564 True +test565 True +test566 True +test567 True +test568 True +test569 True +test570 True +test571 True +test572 True +test573 True +test574 True +test575 True +test576 True +test577 True +test578 True +test579 True +test580 True +test581 True +test582 True +test583 True +test584 True +test585 True +test586 True +test587 True +test588 True +test589 True +test590 True +test591 True +test592 True +test593 True +test594 True +test595 True +test596 True +test597 True +test598 True +test599 True +test600 True +test601 True +test602 True +test603 True +test604 True +test605 True +test606 True +test607 True +test608 True +test609 True +test610 True +test611 True +test612 True +test613 True +test614 True +test615 True +test616 True +test617 True +test618 True +test619 True +test620 True +test621 True +test622 True +test623 True +test624 True +test625 True +test626 True +test627 True +test628 True +test629 True +test630 True +test631 True +test632 True +test633 True +test634 True +test635 True +test636 True +test637 True +test638 True +test639 True +test640 True +test641 True +test642 True +test643 True +test644 True +test645 True +test646 True +test647 True +test648 True +test649 True +test650 True +test651 True +test652 True +test653 True +test654 True +test655 True +test656 True +test657 True +test658 True +test659 True +test660 True +test661 True +test662 True +test663 True +test664 True +test665 True +test666 True +test667 True +test668 True +test669 True +test670 True +test671 True +test672 True +test673 True +test674 True +test675 True +test676 True +test677 True +test678 True +test679 True +test680 True +test681 True +test682 True +test683 True +test684 True +test685 True +test686 True +test687 True +test688 True +test689 True +test690 True +test691 True +test692 True +test693 True +test694 True +test695 True +test696 True +test697 True +test698 True +test699 True +test700 True +test701 True +test702 True +test703 True +test704 True +test705 True +test706 True +test707 True +test708 True +test709 True +test710 True +test711 True +test712 True +test713 True +test714 True +test715 True +test716 True +test717 True +test718 True +test719 True +test720 True +test721 True +test722 True +test723 True +test724 True +test725 True +test726 True +test727 True +test728 True +test729 True +test730 True +test731 True +test732 True +test733 True +test734 True +test735 True +test736 True +test737 True +test738 True +test739 True +test740 True +test741 True +test742 True +test743 True +test744 True +test745 True +test746 True +test747 True +test748 True +test749 True +test750 True +test751 True +test752 True +test753 True +test754 True +test755 True +test756 True +test757 True +test758 True +test759 True +test760 True +test761 True +test762 True +test763 True +test764 True +test765 True +test766 True +test767 True +test768 True +test769 True +test770 True +test771 True +test772 True +test773 True +test774 True +test775 True +test776 True +test777 True +test778 True +test779 True +test780 True +test781 True +test782 True +test783 True +test784 True +test785 True +test786 True +test787 True +test788 True +test789 True +test790 True +test791 True +test792 True +test793 True +test794 True +test795 True +test796 True +test797 True +test798 True +test799 True +test800 True +test801 True +test802 True +test803 True +test804 True +test805 True +test806 True +test807 True +test808 True +test809 True +test810 True +test811 True +test812 True +test813 True +test814 True +test815 True +test816 True +test817 True +test818 True +test819 True +test820 True +test821 True +test822 True +test823 True +test824 True +test825 True +test826 True +test827 True +test828 True +test829 True +test830 True +test831 True +test832 True +test833 True +test834 True +test835 True +test836 True +test837 True +test838 True +test839 True +test840 True +test841 True +test842 True +test843 True +test844 True +test845 True +test846 True +test847 True +test848 True +test849 True +test850 True +test851 True +test852 True +test853 True +test854 True +test855 True +test856 True +test857 True +test858 True +test859 True +test860 True +test861 True +test862 True +test863 True +test864 True +test865 True +test866 True +test867 True +test868 True +test869 True +test870 True +test871 True +test872 True +test873 True +test874 True +test875 True +test876 True +test877 True +test878 True +test879 True +test880 True +test881 True +test882 True +test883 True +test884 True +test885 True +test886 True +test887 True +test888 True +test889 True +test890 True +test891 True +test892 True +test893 True +test894 True +test895 True +test896 True +test897 True +test898 True +test899 True +test900 True +test901 True +test902 True +test903 True +test904 True +test905 True +test906 True +test907 True +test908 True +test909 True +test910 True +test911 True +test912 True +test913 True +test914 True +test915 True +test916 True +test917 True +test918 True +test919 True +test920 True +test921 True +test922 True +test923 True +test924 True +test925 True +test926 True +test927 True +test928 True +test929 True +test930 True +test931 True +test932 True +test933 True +test934 True +test935 True +test936 True +test937 True +test938 True +test939 True +test940 True +test941 True +test942 True +test943 True +test944 True +test945 True +test946 True +test947 True +test948 True +test949 True +test950 True +test951 True +test952 True +test953 True +test954 True +test955 True +test956 True +test957 True +test958 True +test959 True +test960 True +test961 True +test962 True +test963 True +test964 True +test965 True +test966 True +test967 True +test968 True +test969 True +test970 True +test971 True +test972 True +test973 True +test974 True +test975 True +test976 True +test977 True +test978 True +test979 True +test980 True +test981 True +test982 True +test983 True +test984 True +test985 True +test986 True +test987 True +test988 True +test989 True +test990 True +test991 True +test992 True +test993 True +test994 True +test995 True +test996 True +test997 True +test998 True +test999 True +test1000 True +test1001 True +test1002 True +test1003 True +test1004 True +test1005 True +test1006 True +test1007 True +test1008 True +test1009 True +test1010 True +test1011 True +test1012 True +test1013 True +test1014 True +test1015 True +test1016 True +test1017 True +test1018 True +test1019 True +test1020 True +test1021 True +test1022 True +test1023 True +test1024 True +test1025 True +test1026 True +test1027 True +test1028 True +test1029 True +test1030 True +test1031 True +test1032 True +test1033 True +test1034 True +test1035 True +test1036 True +test1037 True +test1038 True +test1039 True +test1040 True +test1041 True +test1042 True +test1043 True +test1044 True +test1045 True +test1046 True +test1047 True +test1048 True +test1049 True +test1050 True +test1051 True +test1052 True +test1053 True +test1054 True +test1055 True +test1056 True +test1057 True +test1058 True +test1059 True +test1060 True +test1061 True +test1062 True +test1063 True +test1064 True +test1065 True +test1066 True +test1067 True +test1068 True +test1069 True +test1070 True +test1071 True +test1072 True +test1073 True +test1074 True +test1075 True +test1076 True +test1077 True +test1078 True +test1079 True +test1080 True +test1081 True +test1082 True +test1083 True +test1084 True +test1085 True +test1086 True +test1087 True +test1088 True +test1089 True +test1090 True +test1091 True +test1092 True +test1093 True +test1094 True +test1095 True +test1096 True +test1097 True +test1098 True +test1099 True +test1100 True +test1101 True +test1102 True +test1103 True +test1104 True +test1105 True +test1106 True +test1107 True +test1108 True +test1109 True +test1110 True +test1111 True +test1112 True +test1113 True +test1114 True +test1115 True +test1116 True +test1117 True +test1118 True +test1119 True +test1120 True +test1121 True +test1122 True +test1123 True +test1124 True +test1125 True +test1126 True +test1127 True +test1128 True +test1129 True +test1130 True +test1131 True +test1132 True +test1133 True +test1134 True +test1135 True +test1136 True +test1137 True +test1138 True +test1139 True +test1140 True +test1141 True +test1142 True +test1143 True +test1144 True +test1145 True +test1146 True +test1147 True +test1148 True +test1149 True +test1150 True +test1151 True +test1152 True +test1153 True +test1154 True +test1155 True +test1156 True +test1157 True +test1158 True +test1159 True +test1160 True +test1161 True +test1162 True +test1163 True +test1164 True +test1165 True +test1166 True +test1167 True +test1168 True +test1169 True +test1170 True +test1171 True +test1172 True +test1173 True +test1174 True +test1175 True +test1176 True +test1177 True +test1178 True +test1179 True +test1180 True +test1181 True +test1182 True +test1183 True +test1184 True +test1185 True +test1186 True +test1187 True +test1188 True +test1189 True +test1190 True +test1191 True +test1192 True +test1193 True +test1194 True +test1195 True +test1196 True +test1197 True +test1198 True +test1199 True +test1200 True +test1201 True +test1202 True +test1203 True +test1204 True +test1205 True +test1206 True +test1207 True +test1208 True +test1209 True +test1210 True +test1211 True +test1212 True +test1213 True +test1214 True +test1215 True +test1216 True +test1217 True +test1218 True +test1219 True +test1220 True +test1221 True +test1222 True +test1223 True +test1224 True +test1225 True +test1226 True +test1227 True +test1228 True +test1229 True +test1230 True +test1231 True +test1232 True +test1233 True +test1234 True +test1235 True +test1236 True +test1237 True +test1238 True +test1239 True +test1240 True +test1241 True +test1242 True +test1243 True +test1244 True +test1245 True +test1246 True +test1247 True +test1248 True +test1249 True +test1250 True +test1251 True +test1252 True +test1253 True +test1254 True +test1255 True +test1256 True +test1257 True +test1258 True +test1259 True +test1260 True +test1261 True +test1262 True +test1263 True +test1264 True +test1265 True +test1266 True +test1267 True +test1268 True +test1269 True +test1270 True +test1271 True +test1272 True +test1273 True +test1274 True +test1275 True +test1276 True +test1277 True +test1278 True +test1279 True +test1280 True +test1281 True +test1282 True +test1283 True +test1284 True +test1285 True +test1286 True +test1287 True +test1288 True +test1289 True +test1290 True +test1291 True +test1292 True +test1293 True +test1294 True +test1295 True +test1296 True +test1297 True +test1298 True +test1299 True +test1300 True +test1301 True +test1302 True +test1303 True +test1304 True +test1305 True +test1306 True +test1307 True +test1308 True +test1309 True +test1310 True +test1311 True +test1312 True +test1313 True +test1314 True +test1315 True +test1316 True +test1317 True +test1318 True +test1319 True +test1320 True +test1321 True +test1322 True +test1323 True +test1324 True +test1325 True +test1326 True +test1327 True +test1328 True +test1329 True +test1330 True ===================================== testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs ===================================== @@ -0,0 +1,26 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnboxedSums #-} + +{-# OPTIONS_GHC -Wno-missing-methods #-} + +module ManyUbxSums_Addr where + +import GHC.Exts +-- import GHC.Word +-- import GHC.Int +--import GHC.Utils.Misc + +data Addr = Addr Addr# + +instance Eq Addr where + (Addr x) == (Addr y) = case (eqAddr# x y) of + 1# -> True + 0# -> False + +instance Num Addr where + fromInteger x = case fromIntegral x of I# x1 -> Addr (int2Addr# x1) + +instance Bounded Addr where + maxBound = fromIntegral (maxBound :: Word) + minBound = 0 \ No newline at end of file ===================================== testsuite/tests/unboxedsums/T22208.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedSums #-} +{-# LANGUAGE UnboxedTuples #-} +module M where + +import GHC.Base + +-- Reproducer from #22208 +foo :: (# Float# | Double# #) -> (# Float# | Float #) +foo (# x | #) = (# x | #) +bar :: (# Word# | Int64# #) -> (# Double# | Word# #) +bar (# y | #) = let x = y in (# | x #) +baz :: (# Word# | Word64# #) -> (# Word# | (##) #) +baz (# x | #) = (# x | #) + +foo1 :: (# Float# | Double# #) -> (# Float# | Float #) +foo1 (# x | #) = (# x | #) +bar1 :: (# Word# | Int64# #) -> (# Double# | Word# #) +bar1 (# y | #) = let x = y in (# | x #) +baz1 :: (# Word# | Word64# #) -> (# Word# | (##) #) +baz1 (# x | #) = (# x | #) + +-- i8 value from w64 slot +baz2 :: (# Int8# | Word64# #) -> (# Int8# | (##) #) +baz2 (# x | #) = (# x | #) + +-- w8 value from w64 slot +baz3 :: (# Word8# | Word64# #) -> (# Word8# | (##) #) +baz3 (# x | #) = (# x | #) + +-- w8 from w slot +baz4 :: (# Word8# | Word# #) -> (# Word8# | (##) #) +baz4 (# x | #) = (# x | #) + +-- w from w slot +baz5 :: (# Word8# | Word# #) -> (# Word# | (##) #) +baz5 (# | x #) = (# x | #) + +-- addr from w slot +baz6 :: (# Addr# | Word# #) -> (# Addr# | (##) #) +baz6 (# x | #) = (# x | #) \ No newline at end of file ===================================== testsuite/tests/unboxedsums/all.T ===================================== @@ -35,3 +35,12 @@ test('T20858b', [extra_files(['T20858.hs']) ,extra_hc_opts("-fprint-explicit-runtime-reps -fprint-explicit-kinds")] , ghci_script, ['T20858b.script']) test('T20859', normal, compile, ['']) +test('T22208', normal, compile, ['-dstg-lint -dcmm-lint']) +test('ManyUbxSums', + [ pre_cmd('runghc ./GenManyUbxSums.hs'), + extra_files(['GenManyUbxSums.hs', 'ManyUbxSums_Addr.hs']), + ], + multi_compile_and_run, + ['ManyUbxSums', + [('ManyUbxSums_Addr.hs','')] + , '-v0 -dstg-lint -dcmm-lint']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbdb88894da94855380d185f3455f04243ccc724 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fbdb88894da94855380d185f3455f04243ccc724 You're receiving 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 Oct 17 10:19:04 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 06:19:04 -0400 Subject: [Git][ghc/ghc][wip/andreask/opt-getlevity] Apply 1 suggestion(s) to 1 file(s) Message-ID: <634d2c1840793_8b90f517d4386467@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/opt-getlevity at Glasgow Haskell Compiler / GHC Commits: 6af67cb7 by sheaf at 2022-10-17T10:19:02+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - compiler/GHC/Core/Type.hs Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2543,6 +2543,8 @@ getLevity_maybe ty | Just rep <- getRuntimeRep_maybe ty , TyConApp tc [lev] <- coreFullView rep , boxedRepDataConTyCon == tc + -- Directly matching on TyConApp after expanding type synonyms + -- saves allocations compared to `splitTyConApp_maybe`. See #22254. = Just lev | otherwise = Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6af67cb77a96f783075e26267360c702443dc7c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6af67cb77a96f783075e26267360c702443dc7c6 You're receiving 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 Oct 17 10:32:20 2022 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Mon, 17 Oct 2022 06:32:20 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/emb-type Message-ID: <634d2f34c9c88_8b90f517d4390591@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/emb-type at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/emb-type You're receiving 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 Oct 17 10:48:11 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Oct 2022 06:48:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: rts: Use pthread_setname_np correctly on Darwin Message-ID: <634d32eb9f905_8b90f517c03981d2@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - e09bd1d3 by Sebastian Graf at 2022-10-17T06:48:00-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 15 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/9.6.1-notes.rst - rts/Schedule.c - rts/posix/OSThreads.c - rts/sm/GC.c - + testsuite/tests/numeric/should_run/T22282.hs - + testsuite/tests/numeric/should_run/T22282.stdout - + testsuite/tests/numeric/should_run/T22282A.hs - testsuite/tests/numeric/should_run/all.T - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -664,10 +664,11 @@ getRegister' config plat expr -- See Note [Signed arithmetic on AArch64]. negate code w reg = do let w' = opRegWidth w + (reg', code_sx) <- signExtendReg w w' reg return $ Any (intFormat w) $ \dst -> code `appOL` - signExtendReg w w' reg `snocOL` - NEG (OpReg w' dst) (OpReg w' reg) `appOL` + code_sx `snocOL` + NEG (OpReg w' dst) (OpReg w' reg') `appOL` truncateReg w' w dst ss_conv from to reg code = @@ -817,15 +818,17 @@ getRegister' config plat expr -- should be performed. let w' = opRegWidth w signExt r - | not is_signed = nilOL + | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r + (reg_x_sx, code_x_sx) <- signExt reg_x + (reg_y_sx, code_y_sx) <- signExt reg_y return $ Any (intFormat w) $ \dst -> code_x `appOL` code_y `appOL` -- sign-extend both operands - signExt reg_x `appOL` - signExt reg_y `appOL` - op (OpReg w' dst) (OpReg w' reg_x) (OpReg w' reg_y) `appOL` + code_x_sx `appOL` + code_y_sx `appOL` + op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do @@ -1021,16 +1024,21 @@ getRegister' config plat expr -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. -signExtendReg :: Width -> Width -> Reg -> OrdList Instr +signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) signExtendReg w w' r = case w of - W64 -> nilOL + W64 -> noop W32 - | w' == W32 -> nilOL - | otherwise -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W16 -> unitOL $ SXTH (OpReg w' r) (OpReg w' r) - W8 -> unitOL $ SXTB (OpReg w' r) (OpReg w' r) + | w' == W32 -> noop + | otherwise -> extend SXTH + W16 -> extend SXTH + W8 -> extend SXTB _ -> panic "intOp" + where + noop = return (r, nilOL) + extend instr = do + r' <- getNewRegNat II64 + return (r', unitOL $ instr (OpReg w' r') (OpReg w' r)) -- | Instructions to truncate the value in the given register from width @w@ -- down to width @w'@. ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -553,13 +553,16 @@ analysing their unfolding. A few reasons for the change: *workers*, because their transformers need to adapt to CPR for their arguments in 'cprTransformDataConWork' to enable Note [Nested CPR]. Better keep it all in this module! The alternative would be that - 'GHC.Types.Id.Make' depends on DmdAnal. + 'GHC.Types.Id.Make' depends on CprAnal. 3. In the future, Nested CPR could take a better account of incoming args in cprAnalApp and do some beta-reduction on the fly, like !1866 did. If any of those args had the CPR property, then we'd even get Nested CPR for DataCon wrapper calls, for free. Not so if we simply give the wrapper a single CPR sig in 'GHC.Types.Id.Make.mkDataConRep'! +DmdAnal also looks through the wrapper's unfolding: +See Note [DmdAnal for DataCon wrappers]. + Note [Trimming to mAX_CPR_SIZE] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We do not treat very big tuples as CPR-ish: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,10 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + -- See Note [DmdAnal for DataCon wrappers] + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1388,6 +1392,45 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +Note [DmdAnal for DataCon wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We give DataCon wrappers a (necessarily flat) demand signature in +`GHC.Types.Id.Make.mkDataConRep`, so that passes such as the Simplifier can +exploit it via the call to `GHC.Core.Opt.Simplify.Utils.isStrictArgInfo` in +`GHC.Core.Opt.Simplify.Iteration.rebuildCall`. But during DmdAnal, we *ignore* +the demand signature of a DataCon wrapper, and instead analyse its unfolding at +every call site. + +The reason is that DataCon *worker*s have very precise demand transformers, +computed by `dmdTransformDataConSig`. It would be awkward if DataCon *wrappers* +would behave much less precisely during DmdAnal. Example: + + data T1 = MkT1 { get_x1 :: Int, get_y1 :: Int } + data T2 = MkT2 { get_x2 :: !Int, get_y2 :: Int } + f1 x y = get_x1 (MkT1 x y) + f2 x y = get_x2 (MkT2 x y) + +Here `MkT1` has no wrapper. `get_x1` puts a demand `!P(1!L,A)` on its argument, +and `dmdTransformDataConSig` will transform that demand to an absent demand on +`y` in `f1` and an unboxing demand on `x`. +But `MkT2` has a wrapper (to evaluate the first field). If demand analysis deals +with `MkT2` only through its demand signature, demand signatures can't transform +an incoming demand `P(1!L,A)` in a useful way, so we won't get an absent demand +on `y` in `f2` or see that `x` can be unboxed. That's a serious loss. + +The example above will not actually occur, because $WMkT2 would be inlined. +Nevertheless, we can get interesting sub-demands on DataCon wrapper +applications in boring contexts; see T22241. + +You might worry about the efficiency cost of demand-analysing datacon wrappers +at every call site. But in fact they are inlined /anyway/ in the Final phase, +which happens before DmdAnal, so few wrappers remain. And analysing the +unfoldings for the remaining calls (which are those in a boring context) will be +exactly as (in)efficent as if we'd inlined those calls. It turns out to be not +measurable in practice. + +See also Note [CPR for DataCon wrappers] in `GHC.Core.Opt.CprAnal`. + Note [Boxity for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider (A) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -477,9 +477,9 @@ mkDictSelId name clas -- See Note [Type classes and linear types] base_info = noCafIdInfo - `setArityInfo` 1 - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` 1 + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig info | new_tycon = base_info `setInlinePragInfo` alwaysInlinePragma @@ -697,6 +697,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + -- The signature is purely for passes like the Simplifier, not for + -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv wrap_arg_dmds = @@ -1321,9 +1323,9 @@ mkFCallId uniq fcall ty name = mkFCallName uniq occ_str info = noCafIdInfo - `setArityInfo` arity - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` arity + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty arity = count isAnonTyCoBinder bndrs ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -121,6 +121,12 @@ Runtime system by library authors directly, who may wrap them a safe API that maintains the necessary invariants. See the documentation in ``GHC.Prim`` for more details. +- The behaviour of the ``-M`` flag has been made more strict. It will now trigger + a heap overflow if the total amount of memory used by the Haskell heap exceeds the limit. + Previously only live blocks were taken into account. + This makes it more likely to trigger promptly when the heap is highly fragmented. + + ``base`` library ~~~~~~~~~~~~~~~~ ===================================== rts/Schedule.c ===================================== @@ -1592,9 +1592,13 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, heap_census = scheduleNeedHeapProfile(true); + // We force a major collection if the size of the heap exceeds maxHeapSize. + // We will either return memory until we are below maxHeapSize or trigger heapOverflow. + bool mblock_overflow = RtsFlags.GcFlags.maxHeapSize != 0 && mblocks_allocated > BLOCKS_TO_MBLOCKS(RtsFlags.GcFlags.maxHeapSize); + // Figure out which generation we are collecting, so that we can // decide whether this is a parallel GC or not. - collect_gen = calcNeeded(force_major || heap_census, NULL); + collect_gen = calcNeeded(force_major || heap_census || mblock_overflow , NULL); major_gc = (collect_gen == RtsFlags.GcFlags.generations-1); #if defined(THREADED_RTS) ===================================== rts/posix/OSThreads.c ===================================== @@ -186,22 +186,48 @@ shutdownThread(void) pthread_exit(NULL); } -int -createOSThread (OSThreadId* pId, char *name STG_UNUSED, - OSThreadProc *startProc, void *param) +struct ThreadDesc { + OSThreadProc *startProc; + void *param; + char *name; +}; + +// N.B. Darwin's pthread_setname_np only allows the name of the +// calling thread to be set. Consequently we must use this +// trampoline. +static void * +start_thread (void *param) { - int result = pthread_create(pId, NULL, startProc, param); - if (!result) { - pthread_detach(*pId); + struct ThreadDesc desc = *(struct ThreadDesc *) param; + stgFree(param); + #if defined(HAVE_PTHREAD_SET_NAME_NP) - pthread_set_name_np(*pId, name); + pthread_set_name_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP) - pthread_setname_np(*pId, name); + pthread_setname_np(pthread_self(), desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) - pthread_setname_np(name); + pthread_setname_np(desc.name); #elif defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) - pthread_setname_np(*pId, "%s", name); + pthread_setname_np(pthread_self(), "%s", desc.name); #endif + + return desc.startProc(desc.param); +} + +int +createOSThread (OSThreadId* pId, char *name STG_UNUSED, + OSThreadProc *startProc, void *param) +{ + struct ThreadDesc *desc = stgMallocBytes(sizeof(struct ThreadDesc), "createOSThread"); + desc->startProc = startProc; + desc->param = param; + desc->name = name; + + int result = pthread_create(pId, NULL, start_thread, desc); + if (!result) { + pthread_detach(*pId); + } else { + stgFree(desc); } return result; } ===================================== rts/sm/GC.c ===================================== @@ -1061,6 +1061,13 @@ GarbageCollect (uint32_t collect_gen, returned = returnMemoryToOS(got - need); } traceEventMemReturn(cap, got, need, returned); + + // Ensure that we've returned enough mblocks to place us under maxHeapSize. + // This may fail for instance due to block fragmentation. + W_ after = got - returned; + if (RtsFlags.GcFlags.maxHeapSize != 0 && after > BLOCKS_TO_MBLOCKS(RtsFlags.GcFlags.maxHeapSize)) { + heapOverflow(); + } } // extra GC trace info ===================================== testsuite/tests/numeric/should_run/T22282.hs ===================================== @@ -0,0 +1,3 @@ +import T22282A + +main = print $ testF 217 161 ===================================== testsuite/tests/numeric/should_run/T22282.stdout ===================================== @@ -0,0 +1,2 @@ +217 + ===================================== testsuite/tests/numeric/should_run/T22282A.hs ===================================== @@ -0,0 +1,18 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE MagicHash #-} +module T22282A where + +import Data.Word +import GHC.Prim +import GHC.Word + +wtestF :: GHC.Prim.Word8# -> GHC.Prim.Word8# -> GHC.Prim.Word8# +wtestF a b = case word8ToWord# b of + 0## -> a + _ -> plusWord8# (timesWord8# (quotWord8# a b) b) (remWord8# a b) +{-# NOINLINE wtestF #-} + +testF :: Word8 -> Word8 -> Word8 +testF (W8# a) (W8# b) = W8# (wtestF a b) +{-# INLINE testF #-} + ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -78,3 +78,4 @@ test('T19931', normal, compile_and_run, ['-O2']) test('IntegerToFloat', normal, compile_and_run, ['']) test('T20291', normal, compile_and_run, ['']) +test('T22282', normal, compile_and_run, ['']) ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,31 @@ +module T22241 where + +data D = D { unD :: !Int } + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} + + + +data T a = T Int !a +get (T _ x) = x + +-- Here, the goal is to discard `unD (f True z)` and thus `z` as absent by +-- looking through $WT in `j` *during the first pass of DmdAnal*! +g :: Bool -> Int -> Int -> Bool +g x y z | even y = get (fst t) + | y > 13 = not (get (fst t)) + | otherwise = False + where + t | x = j (unD (f True z)) + | otherwise = j (unD (f False z)) + where + j a = (T a x, True) + {-# NOINLINE j #-} +{-# NOINLINE g #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,24 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + + +==================== Cpr signatures ==================== +T22241.f: 1 +T22241.g: +T22241.get: +T22241.unD: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb334f8e669a0d7ae3f6ba3e3089af7a116d224d...e09bd1d388e06a978410886d3d998ba5ce64e1cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb334f8e669a0d7ae3f6ba3e3089af7a116d224d...e09bd1d388e06a978410886d3d998ba5ce64e1cf You're receiving 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 Oct 17 11:38:01 2022 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Mon, 17 Oct 2022 07:38:01 -0400 Subject: [Git][ghc/ghc][wip/int-index/emb-type] 38 commits: Add a newline before since pragma in Data.Array.Byte Message-ID: <634d3e99ccae5_8b90f51414419519@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/emb-type at Glasgow Haskell Compiler / GHC Commits: 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - f7ec2804 by Vladislav Zavialov at 2022-10-17T15:37:34+04:00 WIP: vdq - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3ff98921ee8bc9c8c35225eaa4bee3dc4e76a4a...f7ec2804dbcaf6fb8963cff5ea907ac9a9ded04f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3ff98921ee8bc9c8c35225eaa4bee3dc4e76a4a...f7ec2804dbcaf6fb8963cff5ea907ac9a9ded04f You're receiving 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 Oct 17 13:00:28 2022 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Mon, 17 Oct 2022 09:00:28 -0400 Subject: [Git][ghc/ghc][wip/diagnostics-config] 136 commits: DmdAnal: Don't panic in addCaseBndrDmd (#22039) Message-ID: <634d51ecc055a_8b90f517844243bb@gitlab.mail> sheaf pushed to branch wip/diagnostics-config at Glasgow Haskell Compiler / GHC Commits: d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 2e2ab950 by Matthew Pickering at 2022-10-17T14:53:30+02:00 Allow configuration of error message printing This MR implements the idea of #21731 that the printing of a diagnostic method should be configurable at the printing time. The interface of the `Diagnostic` class is modified from: ``` class Diagnostic a where diagnosticMessage :: a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` to ``` class Diagnostic a where type DiagnosticOpts a defaultDiagnosticOpts :: DiagnosticOpts a diagnosticMessage :: DiagnosticOpts a -> a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` and so each `Diagnostic` can implement their own configuration record which can then be supplied by a client in order to dictate how to print out the error message. At the moment this only allows us to implement #21722 nicely but in future it is more natural to separate the configuration of how much information we put into an error message and how much we decide to print out of it. Updates Haddock submodule - - - - - 48d25e34 by Matthew Pickering at 2022-10-17T14:58:20+02:00 Add -fsuppress-error-contexts to disable printing error contexts in errors In many development environments, the source span is the primary means of seeing what an error message relates to, and the In the expression: and In an equation for: clauses are not particularly relevant. However, they can grow to be quite long, which can make the message itself both feel overwhelming and interact badly with limited-space areas. It's simple to implement this flag so we might as well do it and give the user control about how they see their messages. Fixes #21722 - - - - - 30 changed files: - − .appveyor.sh - .editorconfig - .gitlab-ci.yml - .gitlab/ci.sh - README.md - − appveyor.yml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Liveness.hs - compiler/GHC/Cmm/Node.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Reg.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/Switch.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d817ea0a9072c0f1d6d7b1f79b75448e6734742...48d25e34841884a78d368d1274606b122b8efbbf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d817ea0a9072c0f1d6d7b1f79b75448e6734742...48d25e34841884a78d368d1274606b122b8efbbf You're receiving 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 Oct 17 13:25:16 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 17 Oct 2022 09:25:16 -0400 Subject: [Git][ghc/ghc][wip/js-staging] 3 commits: Refactor symbol generation. Message-ID: <634d57bcac8af_8b90f517984285a8@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: e5e5fa36 by Sylvain Henry at 2022-10-17T13:30:43+02:00 Refactor symbol generation. Avoid concatenating Strings or FastStrings. Concatenate ByteString instead. - - - - - fb2482e8 by Sylvain Henry at 2022-10-17T14:49:37+02:00 Enhance Label symbol generation - - - - - 660ebb57 by Sylvain Henry at 2022-10-17T15:27:02+02:00 Rename fresh idents with their FastString unique Reduce by 2x the size of the generated file (on Cabal's Setup). - - - - - 10 changed files: - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Ids.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/StgToJS/Printer.hs - compiler/GHC/StgToJS/Profiling.hs - + compiler/GHC/StgToJS/Symbols.hs - − compiler/GHC/StgToJS/UnitUtils.hs - compiler/GHC/Types/Unique.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/StgToJS/CodeGen.hs ===================================== @@ -30,7 +30,7 @@ import GHC.StgToJS.Monad import GHC.StgToJS.Profiling import GHC.StgToJS.Regs import GHC.StgToJS.StaticPtr -import GHC.StgToJS.UnitUtils +import GHC.StgToJS.Symbols import GHC.StgToJS.Stack import GHC.StgToJS.Ids ===================================== compiler/GHC/StgToJS/Ids.hs ===================================== @@ -41,7 +41,7 @@ import GHC.Prelude import GHC.StgToJS.Types import GHC.StgToJS.Monad import GHC.StgToJS.CoreUtils -import GHC.StgToJS.UnitUtils +import GHC.StgToJS.Symbols import GHC.JS.Syntax import GHC.JS.Make @@ -52,7 +52,6 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Name import GHC.Unit.Module -import GHC.Utils.Encoding (zEncodeString) import GHC.Data.FastString import GHC.Data.FastMutInt @@ -61,6 +60,7 @@ import Control.Monad.IO.Class import qualified Control.Monad.Trans.State.Strict as State import qualified Data.Map as M import Data.Maybe +import qualified Data.ByteString.Char8 as BSC -- | Get fresh unique number freshUnique :: G Int @@ -77,20 +77,10 @@ freshIdent :: G Ident freshIdent = do i <- freshUnique mod <- State.gets gsModule - let !name = mkFastString $ mconcat - [ "h$$" - , zEncodeString (unitModuleString mod) - , "_" - , encodeUnique i - ] + let !name = mkFreshJsSymbol mod i return (TxtI name) - --- | Encode a Unique number as a base-62 String -encodeUnique :: Int -> String -encodeUnique = reverse . iToBase62 -- reversed is more compressible - -- | Generate unique Ident for the given ID (uncached!) -- -- The ident has the following forms: @@ -113,24 +103,35 @@ makeIdentForId i num id_type current_module = TxtI ident where exported = isExportedId i name = getName i - !ident = mkFastString $ mconcat - [ "h$" - , if exported then "" else "$" - , zEncodeString $ unitModuleString $ case exported of - True | Just m <- nameModule_maybe name -> m - _ -> current_module - , zEncodeString "." - , zString (zEncodeFS (occNameFS (nameOccName name))) + mod + | exported + , Just m <- nameModule_maybe name + = m + | otherwise + = current_module + + !ident = mkFastStringByteString $ mconcat + [ mkJsSymbolBS exported mod (occNameFS (nameOccName name)) + + ------------- + -- suffixes + + -- suffix for Ids represented with more than one JS var ("_0", "_1", etc.) , case num of - Nothing -> "" - Just v -> "_" ++ show v + Nothing -> mempty + Just v -> mconcat [BSC.pack "_", intBS v] + + -- suffix for entry and constructor entry , case id_type of - IdPlain -> "" - IdEntry -> "_e" - IdConEntry -> "_con_e" + IdPlain -> mempty + IdEntry -> BSC.pack "_e" + IdConEntry -> BSC.pack "_con_e" + + -- unique suffix for non-exported Ids , if exported - then "" - else "_" ++ encodeUnique (getKey (getUnique i)) + then mempty + else let (c,u) = unpkUnique (getUnique i) + in mconcat [BSC.pack ['_',c,'_'], intBS u] ] -- | Retrieve the cached Ident for the given Id if there is one. Otherwise make ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -45,7 +45,7 @@ import GHC.StgToJS.Linker.Utils import GHC.StgToJS.Rts.Rts import GHC.StgToJS.Object import GHC.StgToJS.Types hiding (LinkableUnit) -import GHC.StgToJS.UnitUtils +import GHC.StgToJS.Symbols import GHC.StgToJS.Printer import GHC.StgToJS.Arg import GHC.StgToJS.Closure @@ -56,7 +56,6 @@ import GHC.Unit.Home import GHC.Unit.Types import GHC.Unit.Module (moduleStableString) -import GHC.Utils.Encoding import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Utils.Error @@ -701,16 +700,7 @@ mkExportedFuns :: UnitId -> FastString -> [FastString] -> [ExportedFun] mkExportedFuns uid mod_name symbols = map mk_fun symbols where mod = mkModule (RealUnit (Definite uid)) (mkModuleNameFS mod_name) - mk_fun sym = ExportedFun mod (LexicalFastString (mkJsSymbol mod sym)) - --- | Make JS symbol corresponding to the given Haskell symbol in the given --- module -mkJsSymbol :: Module -> FastString -> FastString -mkJsSymbol mod s = mkFastString $ mconcat - [ "h$" - , zEncodeString (unitModuleString mod <> ".") - , zString (zEncodeFS s) - ] + mk_fun sym = ExportedFun mod (LexicalFastString (mkJsSymbol True mod sym)) -- | read all dependency data from the to-be-linked files loadObjDeps :: [LinkedObj] -- ^ object files to link ===================================== compiler/GHC/StgToJS/Literal.hs ===================================== @@ -15,6 +15,7 @@ import GHC.JS.Make import GHC.StgToJS.Types import GHC.StgToJS.Monad import GHC.StgToJS.Ids +import GHC.StgToJS.Symbols import GHC.Data.FastString import GHC.Types.Literal @@ -59,10 +60,10 @@ genLit = \case LitDouble r -> return [ toJExpr (r2d r) ] LitLabel name _size fod | fod == IsFunction -> return [ ApplExpr (var "h$mkFunctionPtr") - [var (mkFastString $ "h$" ++ unpackFS name)] + [var (mkRawSymbol True name)] , ValExpr (JInt 0) ] - | otherwise -> return [ toJExpr (TxtI . mkFastString $ "h$" ++ unpackFS name) + | otherwise -> return [ toJExpr (TxtI (mkRawSymbol True name)) , ValExpr (JInt 0) ] LitRubbish _rep -> return [ null_ ] @@ -89,7 +90,7 @@ genStaticLit = \case LitNumBigNat -> panic "genStaticLit: unexpected BigNat that should have been removed in CorePrep" LitFloat r -> return [ DoubleLit . SaneDouble . r2f $ r ] LitDouble r -> return [ DoubleLit . SaneDouble . r2d $ r ] - LitLabel name _size fod -> return [ LabelLit (fod == IsFunction) (mkFastString $ "h$" ++ unpackFS name) + LitLabel name _size fod -> return [ LabelLit (fod == IsFunction) (mkRawSymbol True name) , IntLit 0 ] l -> pprPanic "genStaticLit" (ppr l) ===================================== compiler/GHC/StgToJS/Printer.hs ===================================== @@ -1,4 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -24,7 +26,8 @@ module GHC.StgToJS.Printer where import GHC.Prelude - +import GHC.Int +import GHC.Exts import GHC.JS.Syntax import GHC.JS.Ppr @@ -34,15 +37,59 @@ import GHC.Data.FastString import GHC.Types.Unique.Map import Data.List (sortOn) -import Data.Char (isAlpha,isDigit) +import Data.Char (isAlpha,isDigit,ord) +import qualified Data.ByteString.Short as SBS pretty :: JStat -> Doc pretty = jsToDocR ghcjsRenderJs ghcjsRenderJs :: RenderJs -ghcjsRenderJs = defaultRenderJs { renderJsV = ghcjsRenderJsV - , renderJsS = ghcjsRenderJsS - } +ghcjsRenderJs = defaultRenderJs + { renderJsV = ghcjsRenderJsV + , renderJsS = ghcjsRenderJsS + , renderJsI = ghcjsRenderJsI + } + +hdd :: SBS.ShortByteString +hdd = SBS.pack (map (fromIntegral . ord) "h$$") + +ghcjsRenderJsI :: RenderJs -> Ident -> Doc +ghcjsRenderJsI _ (TxtI fs) + -- Fresh symbols are prefixed with "h$$". They aren't explicitly referred by + -- name in user code, only in compiled code. Hence we can rename them if we do + -- it consistently in all the linked code. + -- + -- These symbols are usually very large because their name includes the + -- unit-id, the module name, and some unique number. So we rename these + -- symbols with a much shorter globally unique number. + -- + -- Here we reuse their FastString unique for this purpose! Note that it only + -- works if we pretty-print all the JS code linked together at once, which we + -- currently do. GHCJS used to maintain a CompactorState to support + -- incremental linking: it contained the mapping between original symbols and + -- their renaming. + | hdd `SBS.isPrefixOf` fastStringToShortByteString fs + , u <- uniqueOfFS fs + = text "h$$" <> hexDoc (fromIntegral u) + | otherwise + = ftext fs + +-- | Render as an hexadecimal number in reversed order (because it's faster and we +-- don't care about the actual value). +hexDoc :: Word -> Doc +hexDoc 0 = char '0' +hexDoc v = text $ go v + where + sym (I# i) = C# (indexCharOffAddr# chars i) + chars = "0123456789abcdef"# + go = \case + 0 -> [] + n -> sym (fromIntegral (n .&. 0x0F)) + : sym (fromIntegral ((n .&. 0xF0) `shiftR` 4)) + : go (n `shiftR` 8) + + + -- attempt to resugar some of the common constructs ghcjsRenderJsS :: RenderJs -> JStat -> Doc ===================================== compiler/GHC/StgToJS/Profiling.hs ===================================== @@ -31,7 +31,7 @@ import GHC.JS.Make import GHC.StgToJS.Regs import GHC.StgToJS.Types -import GHC.StgToJS.UnitUtils +import GHC.StgToJS.Symbols import GHC.StgToJS.Monad import GHC.Types.CostCentre ===================================== compiler/GHC/StgToJS/Symbols.hs ===================================== @@ -0,0 +1,89 @@ + +-- | JS symbol generation +module GHC.StgToJS.Symbols + ( moduleGlobalSymbol + , moduleExportsSymbol + , mkJsSymbol + , mkJsSymbolBS + , mkFreshJsSymbol + , mkRawSymbol + , intBS + ) where + +import GHC.Prelude + +import GHC.Data.FastString +import GHC.Unit.Module +import Data.ByteString (ByteString) +import qualified Data.ByteString.Char8 as BSC +import qualified Data.ByteString.Builder as BSB +import qualified Data.ByteString.Lazy as BSL + +-- | Hexadecimal representation of an int +-- +-- Used for uniques. We could use base-62 as GHC usually does but this is likely +-- faster. +intBS :: Int -> ByteString +intBS = BSL.toStrict . BSB.toLazyByteString . BSB.wordHex . fromIntegral + +-- | Return z-encoded unit:module +unitModuleStringZ :: Module -> ByteString +unitModuleStringZ mod = mconcat + [ fastZStringToByteString (zEncodeFS (unitIdFS (moduleUnitId mod))) + , BSC.pack "ZC" -- z-encoding for ":" + , fastZStringToByteString (zEncodeFS (moduleNameFS (moduleName mod))) + ] + +-- | the global linkable unit of a module exports this symbol, depend on it to +-- include that unit (used for cost centres) +moduleGlobalSymbol :: Module -> FastString +moduleGlobalSymbol m = mkFastStringByteString $ mconcat + [ hd + , unitModuleStringZ m + , BSC.pack "_" + ] + +moduleExportsSymbol :: Module -> FastString +moduleExportsSymbol m = mkFastStringByteString $ mconcat + [ hd + , unitModuleStringZ m + , BSC.pack "_" + ] + +-- | Make JS symbol corresponding to the given Haskell symbol in the given +-- module +mkJsSymbolBS :: Bool -> Module -> FastString -> ByteString +mkJsSymbolBS exported mod s = mconcat + [ if exported then hd else hdd + , unitModuleStringZ mod + , BSC.pack "zi" -- z-encoding of "." + , fastZStringToByteString (zEncodeFS s) + ] + +-- | Make JS symbol corresponding to the given Haskell symbol in the given +-- module +mkJsSymbol :: Bool -> Module -> FastString -> FastString +mkJsSymbol exported mod s = mkFastStringByteString (mkJsSymbolBS exported mod s) + +-- | Make JS symbol for given module and unique. +mkFreshJsSymbol :: Module -> Int -> FastString +mkFreshJsSymbol mod i = mkFastStringByteString $ mconcat + [ hdd + , unitModuleStringZ mod + , BSC.pack "_" + , intBS i + ] + +-- | Make symbol "h$XYZ" or "h$$XYZ" +mkRawSymbol :: Bool -> FastString -> FastString +mkRawSymbol exported fs + | exported = mkFastStringByteString $ mconcat [ hd, bytesFS fs ] + | otherwise = mkFastStringByteString $ mconcat [ hdd, bytesFS fs ] + +-- | "h$$" constant string +hdd :: ByteString +hdd = BSC.pack "h$$" + +-- | "h$" constant string +hd :: ByteString +hd = BSC.take 2 hdd ===================================== compiler/GHC/StgToJS/UnitUtils.hs deleted ===================================== @@ -1,36 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module GHC.StgToJS.UnitUtils - ( unitModuleString - , moduleGlobalSymbol - , moduleExportsSymbol - ) where - -import GHC.Prelude - -import GHC.Data.FastString -import GHC.Unit.Module -import GHC.Utils.Encoding - -unitModuleString :: Module -> String -unitModuleString mod = mconcat - [ unitIdString (moduleUnitId mod) - , ":" - , moduleNameString (moduleName mod) - ] - --- | the global linkable unit of a module exports this symbol, depend on it to --- include that unit (used for cost centres) -moduleGlobalSymbol :: Module -> FastString -moduleGlobalSymbol m = mconcat -- TODO: Is there a better way to concatenate FastStrings? - [ "h$" - , mkFastString (zEncodeString $ unitModuleString m) - , "_" - ] - -moduleExportsSymbol :: Module -> FastString -moduleExportsSymbol m = mconcat -- TODO: Is there a better way to concatenate FastStrings? - [ "h$" - , mkFastString (zEncodeString $ unitModuleString m) - , "_" - ] ===================================== compiler/GHC/Types/Unique.hs ===================================== @@ -40,8 +40,6 @@ module GHC.Types.Unique ( nonDetCmpUnique, isValidKnownKeyUnique, - iToBase62, - -- ** Local uniques -- | These are exposed exclusively for use by 'GHC.Types.Var.Env.uniqAway', which -- has rather peculiar needs. See Note [Local uniques]. ===================================== compiler/ghc.cabal.in ===================================== @@ -659,8 +659,8 @@ Library GHC.StgToJS.Stack GHC.StgToJS.StaticPtr GHC.StgToJS.StgUtils + GHC.StgToJS.Symbols GHC.StgToJS.Types - GHC.StgToJS.UnitUtils GHC.StgToJS.Utils GHC.StgToJS.Linker.Linker GHC.StgToJS.Linker.Types View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d049e360c124ab632408637e0d30e291b99aa20f...660ebb578b4fce1d9a0ceb6beee36d23c332590e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d049e360c124ab632408637e0d30e291b99aa20f...660ebb578b4fce1d9a0ceb6beee36d23c332590e You're receiving 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 Oct 17 14:50:16 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 17 Oct 2022 10:50:16 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable more tests Message-ID: <634d6ba8caf8e_8b90f517d4450545@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: b7b68b67 by Sylvain Henry at 2022-10-17T16:53:40+02:00 Disable more tests - - - - - 5 changed files: - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/driver/T12674/all.T - testsuite/tests/driver/all.T - testsuite/tests/driver/fat-iface/all.T - testsuite/tests/ffi/should_run/all.T Changes: ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -17,7 +17,10 @@ test('conc069a', only_threaded_ways, compile_and_run, ['']) # those for now. test('conc070', only_threaded_ways, compile_and_run, ['']) -test('conc071', omit_ways(concurrent_ways), compile_and_run, ['']) +test('conc071', + [ omit_ways(concurrent_ways) + , js_skip # JS RTS doesn't report the same cap/locked status + ] , compile_and_run, ['']) test('conc072', only_ways(concurrent_ways), compile_and_run, ['']) test('conc073', normal, compile_and_run, ['']) ===================================== testsuite/tests/driver/T12674/all.T ===================================== @@ -1,6 +1,10 @@ test('T12674', [extra_files(['-T12674.hs', '-T12674c.c']), - when(opsys('darwin') and arch('aarch64'), skip)], + when(opsys('darwin') and arch('aarch64'), skip), + js_skip # require support for C sources + ], makefile_test, []) test('T12674w', [extra_files(['-T12674.hs', '-T12674c.c']), - unless(opsys('mingw32'), skip)], + unless(opsys('mingw32'), skip), + js_skip # require support for C sources + ], makefile_test, []) ===================================== testsuite/tests/driver/all.T ===================================== @@ -138,7 +138,10 @@ test('T5313', test('T2464', normal, compile, ['']) test('T3674', [], makefile_test, []) -test('rtsopts001', [extra_files(['rtsOpts.hs'])], makefile_test, []) +test('rtsopts001', + [ extra_files(['rtsOpts.hs']) + , js_skip # JS RTS doesn't support -rtsopts + ], makefile_test, []) test('rtsopts002', normal, makefile_test, []) test('withRtsOpts', [], makefile_test, []) @@ -267,10 +270,12 @@ test('json', normal, compile_fail, ['-ddump-json']) # won't tell. It looks unrelated and is annoying to debug. Hence we disable the # warning to prevent spurious errors. test('json2', normalise_version('base','ghc-prim'), compile, ['-ddump-types -ddump-json -Wno-unsupported-llvm-version']) -test('T16167', exit_code(1), run_command, +test('T16167', [req_interp,exit_code(1)], run_command, ['{compiler} -x hs -e ":set prog T16167.hs" -ddump-json T16167.hs']) test('T13604', [], makefile_test, []) -test('T13604a', [], makefile_test, []) +test('T13604a', + [ js_broken(22261) # require HPC support + ], makefile_test, []) # omitting hpc and profasm because they affect the # inlining and unfoldings test('inline-check', omit_ways(['hpc', 'profasm']) @@ -294,7 +299,7 @@ test('FullGHCVersion', normal, compile_and_run, ['-package ghc-boot']) test('OneShotTH', req_th, makefile_test, []) test('T17481', normal, makefile_test, []) test('T20084', normal, makefile_test, []) -test('RunMode', extra_files(['RunMode/Test.hs']), run_command, ['{compiler} --run -iRunMode/ -ignore-dot-ghci RunMode.hs -- hello']) +test('RunMode', [req_interp, extra_files(['RunMode/Test.hs'])], run_command, ['{compiler} --run -iRunMode/ -ignore-dot-ghci RunMode.hs -- hello']) test('T20439', normal, run_command, ['echo "module Foo where" >> Foo.hs && \ {compiler} -E -fno-code -XCPP -v Foo.hs 2>&1 | grep "Copying" | sed "s/.*to//" ']) ===================================== testsuite/tests/driver/fat-iface/all.T ===================================== @@ -3,17 +3,17 @@ test('fat005', [extra_files(['Fat.hs']), filter_stdout_lines(r'= Proto-BCOs')], test('fat006', [extra_files(['Fat.hs'])], makefile_test, ['fat006']) test('fat006a', [extra_files(['Fat.hs'])], makefile_test, ['fat006a']) test('fat007', [extra_files(['Fat.hs'])], makefile_test, ['fat007']) -test('fat008', [unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs']), copy_files], makefile_test, ['fat008']) -test('fat009', [extra_files(['FatTH.hs', 'FatQuote.hs']), copy_files], makefile_test, ['fat009']) +test('fat008', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs']), copy_files], makefile_test, ['fat008']) +test('fat009', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs']), copy_files], makefile_test, ['fat009']) test('fat010', [extra_files(['THA.hs', 'THB.hs', 'THC.hs']), copy_files], makefile_test, ['fat010']) # Check linking works when using -fbyte-code-and-object-code -test('fat011', [extra_files(['FatMain.hs', 'FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatMain', '-fbyte-code-and-object-code -fprefer-byte-code']) +test('fat011', [req_th, extra_files(['FatMain.hs', 'FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatMain', '-fbyte-code-and-object-code -fprefer-byte-code']) # Check that we use interpreter rather than enable dynamic-too if needed for TH -test('fat012', [unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code']) +test('fat012', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code']) # Check that no objects are generated if using -fno-code and -fprefer-byte-code -test('fat013', [extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fno-code -fprefer-byte-code']) +test('fat013', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fno-code -fprefer-byte-code']) # When using interpreter should not produce objects -test('fat014', [extra_files(['FatTH.hs', 'FatQuote.hs'])], makefile_test, ['fat014']) -test('fat015', [unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface']) +test('fat014', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs'])], makefile_test, ['fat014']) +test('fat015', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface']) ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -7,9 +7,12 @@ test('fed001', normal, compile_and_run, ['']) # Omit GHCi for these two, as they use foreign export -test('ffi001', omit_ways(['ghci']), compile_and_run, ['']) -test('ffi002', [ omit_ways(['ghci']), - pre_cmd('$MAKE -s --no-print-directory ffi002_setup') ], +test('ffi001', [ omit_ways(['ghci']) + , js_skip # JS backend doesn't support foreign export yet + ], compile_and_run, ['']) +test('ffi002', [ omit_ways(['ghci']) + , js_skip # JS backend doesn't support foreign export yet + , pre_cmd('$MAKE -s --no-print-directory ffi002_setup') ], # The ffi002_setup hack is to ensure that we generate # ffi002_stub.h before compiling ffi002_c.c, which # needs it. @@ -43,7 +46,9 @@ test('ffi006', normal, compile_and_run, ['']) # Sometimes we end up with the wrong exit code, or get an extra # 'interrupted' message from the GHCi thread shutting down. -test('ffi007', omit_ways(['ghci']), compile_and_run, ['']) +test('ffi007', [ omit_ways(['ghci']) + , js_skip # foreign "dynamic" call + ], compile_and_run, ['']) test('ffi008', [exit_code(1), omit_ways(['ghci'])], compile_and_run, ['']) # On i386, we need -msse2 to get reliable floating point results @@ -76,7 +81,9 @@ test('ffi014', [only_ways(['threaded1', 'threaded2'])], compile_and_run, test('ffi015', [omit_ways(['ghci']), js_skip_csources], compile_and_run, ['ffi015_cbits.c']) # GHCi can't handle foreign import "&" -test('ffi016', omit_ways(['ghci']), compile_and_run, ['']) +test('ffi016', [ omit_ways(['ghci']) + , js_skip # foreign exports + ], compile_and_run, ['']) test('ffi017', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7b68b6785d38020b7b880482db0563b1fc6d4db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7b68b6785d38020b7b880482db0563b1fc6d4db You're receiving 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 Oct 17 14:51:14 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 17 Oct 2022 10:51:14 -0400 Subject: [Git][ghc/ghc][wip/ghc-io-uring] 495 commits: ghc-heap: Add (broken) test for #21622 Message-ID: <634d6be211703_8b90f5179845091@gitlab.mail> Ben Gamari pushed to branch wip/ghc-io-uring at Glasgow Haskell Compiler / GHC Commits: 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergo ERDI at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Bodigrim at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - 241be1a1 by Ben Gamari at 2022-10-14T13:40:41-04:00 GHC.IOArray: Introduce unsafeFreezeIOArray - - - - - 90915b3b by Ben Gamari at 2022-10-14T13:40:42-04:00 Add GHC.PerCapability - - - - - f2511ad4 by Ben Gamari at 2022-10-14T16:55:29-04:00 Port MIO to use PerCapability - - - - - e42ba325 by Ben Gamari at 2022-10-14T16:55:29-04:00 Implement I/O event manager based on io_uring This adds an I/O event manager backend based on the io_uring interface available in modern Linux kernels. The relevant code is in /libraries/base/GHC/Event/IoUring.hsc. It also contains the following changes to support the new backend: * Port over the io_uring bindings from @bgamari into base. * Add a new HAVE_IO_URING check similar to HAVE_EPOLL, HAVE_KQUEUE etc. All changes are no-opped if this flag is not set. See also: #18390 - - - - - 19195ac0 by Wander Hillen at 2022-10-14T16:55:29-04:00 Remove unneeded (?) int narrowing bits - - - - - e1386394 by Ben Gamari at 2022-10-14T16:55:29-04:00 Clean up superfluous CPP guards - - - - - 8d6078ff by Ben Gamari at 2022-10-14T16:55:29-04:00 Drop blocking support in submit - - - - - 7d3b9e17 by Ben Gamari at 2022-10-14T16:55:29-04:00 uring: read and write support - - - - - 2a9db19c by Ben Gamari at 2022-10-14T16:55:29-04:00 uring fixes - - - - - 57c1f975 by Ben Gamari at 2022-10-14T16:55:29-04:00 hi - - - - - b3f7871b by Ben Gamari at 2022-10-14T16:55:29-04:00 Hack it together - - - - - 1048b310 by Ben Gamari at 2022-10-14T16:55:29-04:00 Consolidate feature test - - - - - 2c21b52c by Ben Gamari at 2022-10-14T16:55:29-04:00 Handle full SQ/SQE - - - - - 66694c8c by Ben Gamari at 2022-10-14T16:55:29-04:00 Port URing to use PerCapability - - - - - ac053ca7 by Ben Gamari at 2022-10-14T16:55:29-04:00 base: Move TVar things to GHC.Conc.TVar - - - - - 35ea5465 by Ben Gamari at 2022-10-14T16:55:29-04:00 base: Initial commit of RWLock - - - - - 5ec79517 by Ben Gamari at 2022-10-14T16:55:29-04:00 base: Fix #21651 - - - - - de721b67 by Ben Gamari at 2022-10-14T16:55:29-04:00 URing: Label completion threads - - - - - cb40ec70 by Ben Gamari at 2022-10-14T16:55:29-04:00 Clean up imports - - - - - d6ebd097 by Ben Gamari at 2022-10-14T16:55:29-04:00 iouring feature check - - - - - 9711b23c by Ben Gamari at 2022-10-14T16:55:29-04:00 iouring: Fix completion - - - - - 4c8c3f50 by Ben Gamari at 2022-10-14T16:55:29-04:00 Feature test - - - - - 19e3255f by Ben Gamari at 2022-10-16T10:46:09-04:00 Whitespace - - - - - 1c134c13 by Ben Gamari at 2022-10-16T10:46:25-04:00 Fix T16916 - - - - - 29 changed files: - − .appveyor.sh - .editorconfig - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - − MAKEHELP.md - − Makefile - README.md - − appveyor.yml - − bindisttest/ghc.mk - boot - compiler/CodeGen.Platform.h - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cbd5329ade0325ab60096467704069217b25173...1c134c134713b2ccc4d6f71b5502693d1d56f90f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7cbd5329ade0325ab60096467704069217b25173...1c134c134713b2ccc4d6f71b5502693d1d56f90f You're receiving 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 Oct 17 15:10:33 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 11:10:33 -0400 Subject: [Git][ghc/ghc][wip/andreask/ghci-tag-nullary] 6 commits: Add standard Unicode case predicates isUpperCase and isLowerCase. Message-ID: <634d7069e1bd6_8b90f517d445433a@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/ghci-tag-nullary at Glasgow Haskell Compiler / GHC Commits: 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 046b93fd by Andreas Klebinger at 2022-10-17T15:10:31+00:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 30 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Driver/GenerateCgIPEStub.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/InferTags/TagSig.hs - compiler/GHC/Stg/Pipeline.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/9.6.1-notes.rst - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/posix/OSThreads.c - testsuite/tests/ghci.debugger/scripts/T12458.stdout - testsuite/tests/ghci.debugger/scripts/print018.stdout - + testsuite/tests/numeric/should_run/T22282.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c5ac51ffeb84312a8b63f61a9d34f3e443054ce...046b93fd86980e3bc0e4514c15589d9a580aee6d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c5ac51ffeb84312a8b63f61a9d34f3e443054ce...046b93fd86980e3bc0e4514c15589d9a580aee6d You're receiving 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 Oct 17 15:31:21 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 17 Oct 2022 11:31:21 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable more tests Message-ID: <634d75491ca0a_8b90f5143c46202@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: f7d84d1c by Sylvain Henry at 2022-10-17T17:34:40+02:00 Disable more tests - - - - - 5 changed files: - testsuite/tests/hpc/all.T - testsuite/tests/hsc2hs/all.T - testsuite/tests/numeric/should_run/all.T - testsuite/tests/profiling/should_run/all.T - testsuite/tests/rts/all.T Changes: ===================================== testsuite/tests/hpc/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_skip) # JS backend doesn't support HPC yet + test('T10138', [extra_files(['.keepme.hpc.T10138/']), ignore_stdout], run_command, # Using --hpcdir with an absolute path should work (exit code 0). ===================================== testsuite/tests/hsc2hs/all.T ===================================== @@ -12,8 +12,12 @@ test('T3837', [], makefile_test, []) # These are broken on CI (and potentially elsewhere) since we # are building ARMv7 # binaries on an AArch64 machine. -test('T4340', when(arch('arm'), expect_broken(17556)), makefile_test, []) -test('T10272', when(arch('arm'), expect_broken(17556)), makefile_test, []) +test('T4340', [ when(arch('arm'), expect_broken(17556)) + , js_broken(17556) + ], makefile_test, []) +test('T10272', [ when(arch('arm'), expect_broken(17556)) + , js_broken(17556) + ], makefile_test, []) test('T11004', [], makefile_test, []) ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -63,7 +63,7 @@ test('T9407', normal, compile_and_run, ['']) test('T9810', normal, compile_and_run, ['']) test('T10011', normal, compile_and_run, ['']) test('T10962', omit_ways(['ghci']), compile_and_run, ['-O2']) -test('T11702', extra_ways(['optasm']), compile_and_run, ['']) +test('T11702', [unless(arch("js"),extra_ways(['optasm']))], compile_and_run, ['']) test('T12136', normal, compile_and_run, ['']) test('T15301', normal, compile_and_run, ['-O2']) test('T497', normal, compile_and_run, ['-O']) ===================================== testsuite/tests/profiling/should_run/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_skip) # JS backend doesn't support profiling yet + # Test for #1227, #1418 test('heapprof002', ===================================== testsuite/tests/rts/all.T ===================================== @@ -164,7 +164,9 @@ test('rtsflags002', [ only_ways(['normal']) ], compile_and_run, ['-with-rtsopts= # omit dyn and profiling ways, because we don't build dyn_l or p_l # variants of the RTS by default test('traceEvent', [ omit_ways(['dyn', 'ghci'] + prof_ways), - extra_run_opts('+RTS -ls -RTS') ], + extra_run_opts('+RTS -ls -RTS'), + js_skip # JS backend has no payload size limit + ], compile_and_run, ['']) test('traceBinaryEvent', [ omit_ways(['dyn', 'ghci'] + prof_ways), @@ -359,7 +361,10 @@ test('T9839_05', # ignore_stderr as RTS reports slightly different error messages # in 'epoll' and 'select' backends on reading from EBADF # mingw32 skip as UNIX pipe and close(fd) is used to exercise the problem -test('T10590', [ignore_stderr, when(opsys('mingw32'), skip)], compile_and_run, ['']) +test('T10590', [ ignore_stderr + , when(opsys('mingw32'), skip) + , js_skip # JS backend doesn't support pipes + ], compile_and_run, ['']) # 20000 was easily enough to trigger the bug with 7.10 test('T10904', [ omit_ways(['ghci']), extra_run_opts('20000'), js_skip_csources ], @@ -370,7 +375,7 @@ test('T10728', [extra_run_opts('+RTS -maxN3 -RTS'), only_ways(['threaded2'])], test('T9405', [when(opsys('mingw32'), expect_broken(21361))], makefile_test, ['T9405']) -test('T11788', when(ghc_dynamic(), skip), +test('T11788', [req_interp, when(ghc_dynamic(), skip)], makefile_test, ['T11788']) test('T10296a', [req_smp], makefile_test, ['T10296a']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d84d1cd6648de9986a7a3326774d4dc7d5fa7c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d84d1cd6648de9986a7a3326774d4dc7d5fa7c You're receiving 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 Oct 17 15:33:53 2022 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Mon, 17 Oct 2022 11:33:53 -0400 Subject: [Git][ghc/ghc][wip/js-staging] Disable ghc-heap tests Message-ID: <634d75e13ef36_8b90f51428462248@gitlab.mail> Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC Commits: f3883547 by Sylvain Henry at 2022-10-17T17:37:21+02:00 Disable ghc-heap tests - - - - - 1 changed file: - libraries/ghc-heap/tests/all.T Changes: ===================================== libraries/ghc-heap/tests/all.T ===================================== @@ -1,3 +1,5 @@ +setTestOpts(js_skip) # ghc-heap not supported by the JS backend + test('heap_all', [when(have_profiling(), extra_ways(['prof'])), # These ways produce slightly different heap representations. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f38835472ddf4cea0a0ca2612d066d2ec8f1f603 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f38835472ddf4cea0a0ca2612d066d2ec8f1f603 You're receiving 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 Oct 17 15:36:31 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 17 Oct 2022 11:36:31 -0400 Subject: [Git][ghc/ghc][wip/az/ghc-9.4-epa-backports-2] 163 commits: Improve BUILD_PAP comments Message-ID: <634d767f61c48_8b90f517844655fc@gitlab.mail> Ben Gamari pushed to branch wip/az/ghc-9.4-epa-backports-2 at Glasgow Haskell Compiler / GHC Commits: 82c0cc6c by Andreas Klebinger at 2022-07-13T10:04:43+02:00 Improve BUILD_PAP comments - - - - - 8143fdf3 by Andreas Klebinger at 2022-07-13T10:04:52+02:00 Make dropTail comment a haddock comment - - - - - 16956d22 by Andreas Klebinger at 2022-07-13T10:05:01+02:00 Add one more sanity check in stg_restore_cccs - - - - - ee1b3cb5 by Andreas Klebinger at 2022-07-13T10:05:09+02:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - 664fded7 by Andreas Klebinger at 2022-07-13T19:52:59+02:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - 41374d55 by Matthew Pickering at 2022-07-13T19:53:07+02:00 Give Cmm files fake ModuleNames which include full filepath This fixes the initialisation functions when using -prof or -finfo-table-map. Fixes #21370 - - - - - 72364127 by Ben Gamari at 2022-07-14T14:02:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. (cherry picked from commit dfa95eccf7b45a8961e034710d5e3ca45a36bf5e) - - - - - a463659c by Matthew Pickering at 2022-07-14T14:02:08-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 (cherry picked from commit 2b0e0862ff57125963b3bb023642d1c86b7aeca2) - - - - - 41615501 by Matthew Pickering at 2022-07-14T14:02:08-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 (cherry picked from commit 456e477225908b300dbc5359d64b7a601ac82e5a) - - - - - 78623f8f by Zubin Duggal at 2022-07-14T14:02:08-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 (cherry picked from commit fb73b5f4ba3cb76e381c7e43f9c12840f779eab5) - - - - - a5e8523c by Matthew Pickering at 2022-07-14T14:02:08-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 (cherry picked from commit 665fa5a73e385bdfce13180048701a179ec3f36a) - - - - - 723e381f by Matthew Pickering at 2022-07-14T14:02:08-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 (cherry picked from commit b151b65ec469405dcf25f9358e7e99bcc8c2b3ac) - - - - - cec4d01d by Tamar Christina at 2022-07-14T14:02:08-04:00 winio: make consoleReadNonBlocking not wait for any events at all. (cherry picked from commit fa59223b05e24d6e477e3ab0ab296e32b2b65a8b) - - - - - 41a39b37 by Ben Gamari at 2022-07-14T14:02:08-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. (cherry picked from commit 980d19547fe3d4e3f03e7d0d35dd4c18b6aa6506) - - - - - 71f74009 by Simon Peyton Jones at 2022-07-14T17:40:12-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. (cherry picked from commit 7b9be6c8b94b3c2eb3441febb4a8005a03fa34a5) - - - - - 58ad696d by Matthew Pickering at 2022-07-14T17:40:15-04:00 Fix tcSplitNestedSigmaTys When I did the shallow-subusmptuion patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect all to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. (cherry picked from commit 936fe7435d9da63f78c032b027179e1f1f22a482) - - - - - 363be362 by Ben Gamari at 2022-07-14T17:40:15-04:00 Fix hlint warning in GHC.Types.Demand - - - - - 639e5c09 by Zubin Duggal at 2022-07-14T21:41:10+00:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) (cherry picked from commit e9d9f0784e8670c6b85f1bf80e26b571b08519b5) - - - - - b5f38510 by Zubin Duggal at 2022-07-14T21:41:10+00:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. (cherry picked from commit c4989131563efca8692c341e7b08096ac9a3b53b) - - - - - 79b48898 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. (cherry picked from commit f4919e6fd22dae59cb51a13c25f89ebe9d6f856d) - - - - - 3b3f755b by Ben Gamari at 2022-07-14T19:49:10-04:00 testsuite: Add T20494 (cherry picked from commit 65eab273f8b22f7548f12bdcaad718ac395ce891) - - - - - 99a4c1d6 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". (cherry picked from commit f8fef29f9a46b0a9ffd925377bdec5a8a84cc96d) - - - - - 76adb450 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. (cherry picked from commit fc13142da02835cf90198145def98c667218d2ee) - - - - - 445482bc by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. (cherry picked from commit aa3de0cfbc74671f9f22970aead9c430548dd05e) - - - - - a1395984 by Ben Gamari at 2022-07-14T19:49:10-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. (cherry picked from commit 27b27cd487d5ba9ddc8b9d70ad782186931157fe) - - - - - 2b7d4b00 by Ben Gamari at 2022-07-14T19:49:10-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. (cherry picked from commit 91a6d53ba77ce7d977b137b69690567dd9f92d98) - - - - - 43b7997b by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. (cherry picked from commit 8c8dfa3e9558c2a198195c8b9c2bf638d2ca6d05) - - - - - 669d60cf by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. (cherry picked from commit 6f2d9164d366a76f5ae2cf9a110836b5b629bee5) - - - - - 7c5a8ca6 by Ben Gamari at 2022-07-14T19:49:10-04:00 testsuite: Add test for #21618 and #21847 (cherry picked from commit 3480b973833ac2826f2aa175a155bb76dc67c008) - - - - - 5a69a9ff by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. (cherry picked from commit 8ad577ddad66f2a7a9bb334b6ee7f0837e0c19be) - - - - - 7c481f0f by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/MachO: Drop dead code (cherry picked from commit 0115b0b141611f5ad9a22ac0d77212000e209504) - - - - - 88ad0503 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/MachO: Use section flags to identify initializers (cherry picked from commit 14f6dc27a46936b8aa99829436d0aca6ba4f16b4) - - - - - a82a8f46 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/MachO: Introduce finalizer support (cherry picked from commit 8ce5db8c2544268f05385995ffb6e31a02fd804f) - - - - - a2f00909 by Ben Gamari at 2022-07-14T19:49:10-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl (cherry picked from commit a4ca19aba198fdbed4b1ec4215411a3fc7cee14e) - - - - - 7334e380 by Ben Gamari at 2022-07-14T19:49:10-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. (cherry picked from commit e950217c2d19267a84f1ba27cf623bd7832ef002) - - - - - a32f4d6f by Ben Gamari at 2022-07-14T19:49:10-04:00 Bump text submodule (cherry picked from commit 8734727d83756cc2ba6e5a77d2aac12d8ff4fda7) - - - - - 114b9bc4 by Ben Gamari at 2022-07-14T19:49:10-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin (cherry picked from commit 9811dafb9436e9a8ccc19b78ea41baea71adfaa3) - - - - - ae428688 by Ben Gamari at 2022-07-14T19:49:11-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. (cherry picked from commit 1790cc8d6193ea08526b0ae556167aa4146f2cc4) - - - - - 26955304 by Ben Gamari at 2022-07-14T19:49:11-04:00 rts/linker: Clean up section kinds (cherry picked from commit f2d1b447abf73e878cdbe3d4ab55554c6edc6ea4) - - - - - 4b5812a0 by Ben Gamari at 2022-07-14T19:49:11-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload (cherry picked from commit 443df82ea3e5095b7d25b03c1e8b7dbdb16e3874) - - - - - 805a4b1f by Matthew Pickering at 2022-07-14T23:02:07-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. (cherry picked from commit 468f919b1bd27d8a58a789a6bb1be4295097388c) - - - - - 06ea642a by Greg Steuck at 2022-07-15T22:22:52-04:00 Suppress extra output from configure check for c++ libraries (cherry picked from commit ac6a1a1366d6b9c045b3837c832f7e0fa312d42b) - - - - - d339b68f by Luite Stegeman at 2022-07-15T22:22:52-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 (cherry picked from commit fcc964ad5cf7141449ad487102b7c19f0798e73f) - - - - - 3e58f0ba by Sergei Trofimovich at 2022-07-15T22:22:52-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 (cherry picked from commit 03cc5d0258294fc83f65479e78dbe937622cfc88) - - - - - 22a3efa2 by Ben Gamari at 2022-07-15T22:22:52-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - 41714736 by Ben Gamari at 2022-07-16T00:40:55-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 T13701 T14697 (cherry picked from commit d75c540d439510491b45f64c1113762dcb251ae1) - - - - - 96559c8b by Ben Gamari at 2022-07-16T00:41:03-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. (cherry picked from commit 582bde433879042a42ad8a1862b1c46d6832b00b) - - - - - 2e8dec67 by Ben Gamari at 2022-07-16T00:41:03-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. (cherry picked from commit 3d5f9ba19fea5455d778d2ee9c3fdcaad77d1db7) - - - - - 11782f0f by sheaf at 2022-07-16T13:27:40-04:00 Make withDict noinline As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch gives withDict a NOINLINE pragma, to circumvent this issue. This is not entirely satisfactory, as it causes a performance penalty. Hopefully in the future a better fix can be implemented. Fixes #21575 (cherry picked from commit 1bbbbab816a5beda01bf97deb50651263db58ca0) - - - - - 11441162 by Colten Webb at 2022-07-19T15:19:36+05:30 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 (cherry picked from commit 5434d1a355e127d44c6f116b4b7f8a1d254815d4) - - - - - b2d4feb4 by Colten Webb at 2022-07-19T15:21:49+05:30 Add record-dot-syntax test (cherry picked from commit 89d169ec0c4e9c1e6cf4a6373a1992dad7474d55) - - - - - ddf6c670 by Ben Gamari at 2022-07-20T22:30:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - b889f123 by Matthew Pickering at 2022-07-20T22:30:53-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption (cherry picked from commit 5c4fbaf53f258d64aeb66a8172e13dc559eb8d8b) - - - - - ed6aabc4 by Ben Gamari at 2022-07-20T22:30:53-04:00 upload_ghc_libs: Fix path to documentation - - - - - 00d4bf22 by Ben Gamari at 2022-07-20T22:30:54-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. (cherry picked from commit 028f081e4e748794d7a0e6359987ec799c3dc404) - - - - - 3d3f3dcf by Ben Gamari at 2022-07-20T22:30:54-04:00 Bump bytestring submodule to 0.11.3.1 - - - - - 086ecfa2 by Ben Gamari at 2022-07-20T22:30:54-04:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - 8d491b78 by Ben Gamari at 2022-07-20T22:30:54-04:00 Add dates to base, ghc-prim changelogs - - - - - e294c22f by Ben Gamari at 2022-07-20T22:30:54-04:00 testsuite: Normalise versions in UnusedPackages - - - - - 8af3a682 by Ben Gamari at 2022-07-20T22:30:54-04:00 Bump unix submodule to 2.7.3 - - - - - 55f9ff5b by Ben Gamari at 2022-07-20T22:30:54-04:00 Bump text submodule - - - - - 2deb51b7 by Ben Gamari at 2022-07-20T22:30:54-04:00 Bump deepseq submodule to 1.4.8.0 - - - - - 85b99a00 by Ben Gamari at 2022-07-20T22:37:31-04:00 cmm: Add surface syntax for MO_MulMayOflo (cherry picked from commit 6dd8a3ca1d96a662d9a0c19c5b769536fa6472b8) - - - - - 82090ac3 by Ben Gamari at 2022-07-20T22:37:31-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. (cherry picked from commit 70895c3782ecf7dfe12e4534777084344ba2968f) - - - - - 7f1fcfd7 by Ben Gamari at 2022-07-20T22:37:31-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. (cherry picked from commit 07c75704f014f62f9ea332319da2e14803263216) - - - - - a51b5001 by Ben Gamari at 2022-07-20T22:37:31-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. (cherry picked from commit 5dcc2c84409c2c3f97198b4116c47e861aafd1fb) - - - - - 126e3753 by Ben Gamari at 2022-07-20T22:37:31-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. (cherry picked from commit 83e0efe12874108cf957ab5cdd49b7da217d3bb8) - - - - - 99f6655e by Matthew Pickering at 2022-07-20T22:39:31-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 (cherry picked from commit 18326ad29b315ed9f086672c38b2c8f611bc7d19) - - - - - 2023d7d8 by Ben Gamari at 2022-07-20T22:40:18-04:00 base: Drop changelog entry for traceWith, et al. This won't be introduced until 9.6. Closes #21542. - - - - - 8a682037 by Matthew Pickering at 2022-07-20T23:43:50-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 (cherry picked from commit e8c07aa91f0f05816b455457e3781c247b7399ca) - - - - - 7757465f by Andreas Klebinger at 2022-07-20T23:43:50-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. (cherry picked from commit 2b2e30203a125dc5bfe70f3df7b39787aaf62b1e) - - - - - 19d8c3c2 by Ben Gamari at 2022-07-23T09:00:07-04:00 Release notes and changelog wibbles - - - - - 133c4405 by Ben Gamari at 2022-07-27T11:29:55+01:00 Bump directory submodule to 1.3.7.1 - - - - - bcfdc07d by Douglas Wilson at 2022-07-27T11:29:56+01:00 bump text submodule to 2.0.1 - - - - - cd8a85fb by Ben Gamari at 2022-07-27T11:29:56+01:00 user guide: Mention DeepSubsumpion in the release notes - - - - - a9c0b989 by Simon Jakobi at 2022-07-27T11:29:56+01:00 docs: Fix documentation of \cases Fixes #21902. (cherry picked from commit 79f1b0219f5c00f5c8eb7884bd33993bd98680a0) - - - - - 1198d751 by sternenseemann at 2022-07-27T11:29:56+01:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. (cherry picked from commit 42147534320f9ac22f16ffc226148ae553337d2e) - - - - - e4522c03 by sternenseemann at 2022-07-27T11:29:56+01:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 (cherry picked from commit e4bf95920a9bbcb5b6ac3715282c69f612137156) - - - - - 6bb1e4bc by Zubin Duggal at 2022-07-27T11:29:56+01:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe (cherry picked from commit 3bbde95769aa2986adb8bef7d718aa0e8731f9fd) - - - - - 2c64742b by Ben Gamari at 2022-07-27T11:29:56+01:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) (cherry picked from commit 82a0991a73130f2cb70bd8ccaaff30cffd1dd2b0) - - - - - 4c678ffb by Ben Gamari at 2022-07-27T11:29:56+01:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) (cherry picked from commit 4b08797380a0a0a789844c17c6ed1570b62dc119) - - - - - 094221ef by Ben Gamari at 2022-07-27T11:29:56+01:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) (cherry picked from commit 54a5c32d9d0792d8f3f80728edf6f39db5321fe5) - - - - - ed9c4c6a by Ben Gamari at 2022-07-27T11:29:56+01:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) (cherry picked from commit 25c24535ad51aa22b9cae425c6ac4ad9a8f1e1e9) - - - - - 9187b984 by Ben Gamari at 2022-07-27T11:38:09+01:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. (cherry picked from commit e2f0094c315746ff15b8d9650cf318f81d8416d7) - - - - - 388ec68f by Krzysztof Gogolewski at 2022-07-28T10:31:44+01:00 Update 9.4 release notes regarding withDict The type was changed in !8249 and this was backported to 9.4. (cherry picked from commit b0d98619a3bc01246bd5b23e6d4afb340df46150) - - - - - 6971ec58 by Matthew Pickering at 2022-07-28T10:32:34+01:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 (cherry picked from commit abd62256ea2fb78990ee83464abc7e2a291a7731) - - - - - a5590869 by sternenseemann at 2022-07-28T10:40:23+01:00 hadrian: also include boot-generated files only needed for make For some libraries the `boot` script generates a `ghc.mk` and `GNUmakefile` which is required for the make build system. We also should include these files in the source-dist to save make users from having to run the `./boot.source` script in the tarball (which confusingly has a different name to previous GHC releases, thanks to hadrian). With this change, the source-dist should be on parity with GHC 9.2.2 and earlier releases again after the regression in GHC 9.2.3. Closes #21626. (cherry picked from commit 90ccdb9c84fe7133244d661766f1aa7a29a94a72) - - - - - 16c0829a by Douglas Wilson at 2022-07-28T11:06:14+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 - - - - - c3a9ac29 by Matthew Pickering at 2022-08-02T10:16:45+01:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. (cherry picked from commit 30a3a1de9eb4ad3a5697f99c4933f9f7386c598b) - - - - - 43eb4c6d by Douglas Wilson at 2022-08-03T09:31:56+01:00 Update submodule process to 1.6.15.0 - - - - - 3646d6b1 by Douglas Wilson at 2022-08-03T09:31:56+01:00 Update submodule containers to 0.6.6 - - - - - e5a895de by Douglas Wilson at 2022-08-03T09:44:29+01:00 Update submodule haddock to commit 7484cf8 - - - - - 55f8541f by Matthew Pickering at 2022-08-03T10:37:58+01:00 ghc-9.4: make buildsystem: build stage0 cabal with older process Cabal has grown a bound process >= 1.6.14.0 to work around a bug in process. Making process a stage0 package proved difficult, so instead we carefully build stage0 cabal --exact-configuration including boot package-db's process. This is very ugly, but is only necessary on the 9.4 branch as the make build system will not be supported in the future. - - - - - c18d64bb by Douglas Wilson at 2022-08-03T16:40:04+01:00 ghc-9.4: make build system: Detect too-new boot compiler and docs - - - - - b147ac16 by Greg Steuck at 2022-08-03T16:40:04+01:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 12ae2a9c by Douglas Wilson at 2022-08-03T17:17:36+01:00 ghc-9.4: make build system: add container module dependencies on template-haskell - - - - - c62e65b7 by Douglas Wilson at 2022-08-04T10:17:16+01:00 Update submodule nofib to upstream master - - - - - 14bf0f22 by Douglas Wilson at 2022-08-04T10:33:52+01:00 ghc-9.4: update llvm-targets These updates were generated with: clang version 13.0.1 Target: x86_64-unknown-linux-gnu Thread model: posix Windows targets are omitted because the script errored with: clang-13: error: unsupported option '-fPIC' for target 'x86_64-unknown-windows-msvc' - - - - - f20c2c91 by Douglas Wilson at 2022-08-04T10:45:06+01:00 ghc-9.4.1: RELEASE=YES - - - - - 2205c225 by Ben Gamari at 2022-08-04T16:35:48-04:00 users-guide: Clean up release notes Moving breaking changes into their own section, as suggested in #21630. - - - - - 6747655d by Ben Gamari at 2022-08-04T16:35:48-04:00 users-guide: Document system-cxx-std-lib - - - - - 1446be75 by Douglas Wilson at 2022-08-04T16:51:23-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. - - - - - b39f0e0d by Matthew Pickering at 2022-08-04T18:20:10-04:00 make: Add directory dependency on hs-boot copying rules We need to create these directories before attempting the copy, apparently this race could be observed in systems under high load. Fixes #21934 - - - - - 258e68b1 by Ben Gamari at 2022-08-04T18:20:15-04:00 Accept performance shifts Metric Decrease: T18923 Metric Increase: ManyAlternatives ManyConstructors MultiComponentModules MultiComponentModulesRecomp T10421 T12234 T12425 T12707 T13035 T13056 T13379 T13719 T14697 T15703 T16875 T18698a T1969 T3294 T4801 T4978 T5321FD T5321Fun T7257 T783 T9020 T9198 T9233 T9961 WWRec - - - - - f17b56bb by Ben Gamari at 2022-08-04T18:53:59-04:00 Bump stm submodule to 2.5.1.0 - - - - - e00b823d by Ben Gamari at 2022-08-04T19:02:11-04:00 Bump binary submodule to 0.8.9.1 - - - - - d1558383 by Ben Gamari at 2022-08-05T11:46:40-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - d24765e4 by Ben Gamari at 2022-08-05T12:53:40-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. (cherry picked from commit b4342e32823bb0bfc8e83b53055647d64e0431ab) - - - - - 69db7406 by Ben Gamari at 2022-08-06T16:32:09-04:00 users-guide: Mention representation change of Word64 and Int64 Closes #21641. - - - - - f08a73a0 by Ben Gamari at 2022-08-06T16:32:09-04:00 make: Fix too-old bootstrap compiler error - - - - - 669fd338 by Ben Gamari at 2022-08-06T16:32:09-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. (cherry picked from commit 4d8e0fd3fe3d648c6d37b3eb43b89e1bdbef36af) - - - - - cc715935 by Ben Gamari at 2022-08-06T16:32:09-04:00 hadrian: Fix installation of system-cxx-std-lib package conf (cherry picked from commit 119ee22dd09d8977de67939de7324af941ae7196) - - - - - cb320017 by Ben Gamari at 2022-08-06T22:58:44-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit a30ef212790e41ba01f92f24e3be4d645502d9ee) - - - - - 6d01245c by Ben Gamari at 2022-08-06T22:58:44-04:00 Bump haddock submodule - - - - - 616c77fa by Ben Gamari at 2022-08-07T17:42:19-04:00 configure: Set RELEASE=NO - - - - - 2441c2f4 by Ben Gamari at 2022-08-12T09:44:50-04:00 users-guide: Fix typo in release notes - - - - - dae00493 by Ben Gamari at 2022-08-12T09:44:50-04:00 users-guide: Fix incorrect directives - - - - - ddd0a67f by Ben Gamari at 2022-08-12T09:44:50-04:00 relnotes: Reintroduce "included libraries" section As requested in #21988. - - - - - 05a86964 by Ben Gamari at 2022-08-12T09:44:50-04:00 make: Fix bootstrapping with profiling enabled 12ae2a9cf89af3ae9e4df051818b631cf213a1b8 attempted to work around a make build system deficiency by adding some dependencies from modules of `containers` which contain TH splices to the `template-haskell` package. However, it only did this for the vanilla way. Here we add similar edges for profiled objects. Fixes #21987. - - - - - 05eef6e2 by Ben Gamari at 2022-08-15T17:03:18-04:00 make: Add another missing build dependency on template-haskell This time the culprit is Data.Sequence.Internal. Closes #22047. - - - - - c2043b0a by normalcoder at 2022-08-15T17:11:26-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms (cherry picked from commit 67575f2004340564d6e52af055ed6fb43d3f9711) - - - - - 44b60e03 by Ben Gamari at 2022-08-15T17:11:26-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. (cherry picked from commit c1c08bd829fb33a185f0a71f08babe5d7e6556fc) - - - - - 658d3fd5 by Ben Gamari at 2022-08-15T17:11:26-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. (cherry picked from commit 1c582f44e41f534a8506a76618f6cffe5d71ed42) - - - - - e2832cbd by Ben Gamari at 2022-08-15T17:11:26-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. (cherry picked from commit 681aa076259c05c626266cf516de7e7c5524eadb) - - - - - cdf69083 by Ben Gamari at 2022-08-15T17:11:26-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. (cherry picked from commit 844df61e8de5e2d9a058e6cbe388802755fc0305) (cherry picked from commit d8961a2dc974b7f8f8752781c4aec261ae8f8c0f) - - - - - 4f1e1a30 by Ben Gamari at 2022-08-15T17:11:26-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt (cherry picked from commit 5d66a0ce39f47b7b9f6c732a18ac6e102a21ee6b) - - - - - 573569d5 by Ben Gamari at 2022-08-15T17:11:26-04:00 gitlab-ci: Bump to use freebsd13 runners (cherry picked from commit ea90e61dc3c6ba0433e008284dc6c3970ead98a7) - - - - - 12244700 by Douglas Wilson at 2022-08-15T17:11:26-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. (cherry picked from commit 76b52cf0c52ee05c20f7d1b80f5600eecab3c42a) - - - - - feceab56 by Douglas Wilson at 2022-08-15T17:11:26-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. (cherry picked from commit 7589ee7241d46b393979d98d4ded17a15ee974fb) - - - - - 088071e5 by Jens Petersen at 2022-08-15T17:11:26-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally (cherry picked from commit 823fe5b56450a7eefbf41ce8ece34095bf2217ee) - - - - - f7322f2a by Ben Gamari at 2022-08-15T17:11:26-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. (cherry picked from commit 7cabea7c9b10d2d15a4798be9f3130994393dd9c) - - - - - a77c7462 by Ben Gamari at 2022-08-15T17:11:26-04:00 relnotes: Fix typo - - - - - d87e0545 by Matthew Pickering at 2022-08-15T17:11:27-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 (cherry picked from commit ef30e21594e44af309c627052f63aea6fd575c9e) - - - - - 0bea62ff by Ben Gamari at 2022-08-15T17:11:27-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - 4f70fbff by Ben Gamari at 2022-08-17T16:39:43+00:00 linters-common: Add LICENSE - - - - - d04c592d by Ben Gamari at 2022-08-17T17:50:22+00:00 make: Fix bindist installation - - - - - aeb04c72 by Ben Gamari at 2022-08-18T15:59:46-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. (cherry picked from commit 5bc489cac104717f09be73f2b578719bcc1e3fcb) - - - - - c534eb5d by Ben Gamari at 2022-08-18T16:06:45-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used (cherry picked from commit 596db9a5f966643bcc9994d45f2f6ffb4037ad74) - - - - - ed84e10b by Matthew Pickering at 2022-08-18T16:06:45-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 (cherry picked from commit a740a4c56416c7c1bc914a7a9207207e17833573) - - - - - 0868c8a5 by Andreas Klebinger at 2022-08-19T10:21:04-04:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - b9ed1a48 by Matthew Pickering at 2022-08-19T16:31:33-04:00 Update haddock submodule to revert quickjump breakage Fixes #21984 - - - - - 42aff86e by Ben Gamari at 2022-08-20T12:07:08-04:00 Bump haddock submodule Bumps haddock-api version to 2.27.1 - - - - - 6466747b by Ben Gamari at 2022-08-20T12:07:08-04:00 Add release notes for 9.4.2 - - - - - 8e6b979c by Ben Gamari at 2022-08-20T12:07:08-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ (cherry picked from commit 37c61cc05f82f4cdc43aece152df8630b7c0419d) - - - - - ed1f88eb by Ben Gamari at 2022-08-20T12:07:08-04:00 users-guide: Add :ghc-flag: reference (cherry picked from commit 14853adf9571c9fe57d70456a4e8470299a81b8e) - - - - - ba137e8b by Ben Gamari at 2022-08-20T12:07:08-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. (cherry picked from commit f0dc6f3e2333cc4625bdfb75990f80ef0ef96638) - - - - - 0ce2dc79 by Ben Gamari at 2022-08-20T12:07:08-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. (cherry picked from commit c57075ebbed5dc8ae82902999b9f5ae5f3e83b0e) - - - - - b67d4ac6 by Ben Gamari at 2022-08-20T12:07:08-04:00 Release 9.4.2 - - - - - c126db99 by Ben Gamari at 2022-08-20T12:07:46-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - e8a889a7 by Ben Gamari at 2022-08-20T12:20:29-04:00 Document -no-link - - - - - 2cf828e8 by Simon Peyton Jones at 2022-09-15T10:28:17+02:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] This is the 9.4 packport based on commit 4945953823620b223a0b51b2b1275a1de8f4a851 - - - - - 15c496c5 by Sebastian Graf at 2022-10-12T19:20:16-04:00 Ignore .hie-bios (cherry picked from commit 2563b95cda983cd6be23a5be01fe1f1873f1fa4f) - - - - - 26af15a0 by Sebastian Graf at 2022-10-12T19:20:16-04:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. (cherry picked from commit 94f2e92a2510a3338c5201a4dcc69666fa9575f8) - - - - - ecb6accd by Sebastian Graf at 2022-10-14T16:16:07-04:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. (cherry picked from commit b570da84b7aad5ca3f90f2d1c1a690c927e99fe9) - - - - - c0b5736c by Sebastian Graf at 2022-10-14T17:10:27-04:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 (cherry picked from commit 49fb2f9b16ca987648d2ac57eecf1892d49852ec) - - - - - ccdaa83c by Ben Gamari at 2022-10-14T17:10:27-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. (cherry picked from commit cd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3) - - - - - 671491cc by Matthew Pickering at 2022-10-14T17:10:27-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 (cherry picked from commit 2361b3bc08811b0d2fb8f8fc5635b7c2fec157c6) - - - - - 6bf992e6 by Ryan Scott at 2022-10-14T17:10:27-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. (cherry picked from commit 8a666ad2a89a8ad2aa24a6406b88f516afaec671) - - - - - 3eace272 by Ryan Scott at 2022-10-14T17:10:27-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. (cherry picked from commit 3a815f30bcba5672085e823aeef90863253b0b1a) - - - - - 9ae4865b by Cheng Shao at 2022-10-14T17:10:27-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh (cherry picked from commit ee471dfb8a4a4bb5131a5baa61d1d0d22c933d5f) - - - - - 6af677a9 by Matthew Pickering at 2022-10-14T17:10:27-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 (cherry picked from commit 7f0decd5063a853fc8f38a8944b2c91995cd5e48) - - - - - 9a12e496 by Ben Gamari at 2022-10-16T10:41:41-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. (cherry picked from commit 25f68acedf822e9ea21d1659b1f897fcfc96e5d4) - - - - - fa55c566 by Alan Zimmerman at 2022-10-17T15:36:19+00:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 (cherry picked from commit 792ef44d455c6e987f342fb61515464322a9fa77) - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/toolchain.nix - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/upload_ghc_libs.py - compiler/CodeGen.Platform.h - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/Utils.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/63a15e3e04e761c1e7a101bc89c2db38adf83553...fa55c5662fc2ce8ea03152a21cd00c268d3d6741 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63a15e3e04e761c1e7a101bc89c2db38adf83553...fa55c5662fc2ce8ea03152a21cd00c268d3d6741 You're receiving 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 Oct 17 15:58:41 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Oct 2022 11:58:41 -0400 Subject: [Git][ghc/ghc][master] 3 commits: rts: ensure we are below maxHeapSize after returning megablocks Message-ID: <634d7bb13767c_8b90f5143c48277a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - 3 changed files: - docs/users_guide/9.6.1-notes.rst - rts/Schedule.c - rts/sm/GC.c Changes: ===================================== docs/users_guide/9.6.1-notes.rst ===================================== @@ -121,6 +121,12 @@ Runtime system by library authors directly, who may wrap them a safe API that maintains the necessary invariants. See the documentation in ``GHC.Prim`` for more details. +- The behaviour of the ``-M`` flag has been made more strict. It will now trigger + a heap overflow if the total amount of memory used by the Haskell heap exceeds the limit. + Previously only live blocks were taken into account. + This makes it more likely to trigger promptly when the heap is highly fragmented. + + ``base`` library ~~~~~~~~~~~~~~~~ ===================================== rts/Schedule.c ===================================== @@ -1592,9 +1592,13 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, heap_census = scheduleNeedHeapProfile(true); + // We force a major collection if the size of the heap exceeds maxHeapSize. + // We will either return memory until we are below maxHeapSize or trigger heapOverflow. + bool mblock_overflow = RtsFlags.GcFlags.maxHeapSize != 0 && mblocks_allocated > BLOCKS_TO_MBLOCKS(RtsFlags.GcFlags.maxHeapSize); + // Figure out which generation we are collecting, so that we can // decide whether this is a parallel GC or not. - collect_gen = calcNeeded(force_major || heap_census, NULL); + collect_gen = calcNeeded(force_major || heap_census || mblock_overflow , NULL); major_gc = (collect_gen == RtsFlags.GcFlags.generations-1); #if defined(THREADED_RTS) ===================================== rts/sm/GC.c ===================================== @@ -1061,6 +1061,13 @@ GarbageCollect (uint32_t collect_gen, returned = returnMemoryToOS(got - need); } traceEventMemReturn(cap, got, need, returned); + + // Ensure that we've returned enough mblocks to place us under maxHeapSize. + // This may fail for instance due to block fragmentation. + W_ after = got - returned; + if (RtsFlags.GcFlags.maxHeapSize != 0 && after > BLOCKS_TO_MBLOCKS(RtsFlags.GcFlags.maxHeapSize)) { + heapOverflow(); + } } // extra GC trace info View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62a550010ed94e1969c96150f2781854a0802766...4a4641ca2f2a157dab0fe2df5316f79ffb52c047 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62a550010ed94e1969c96150f2781854a0802766...4a4641ca2f2a157dab0fe2df5316f79ffb52c047 You're receiving 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 Oct 17 15:59:09 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Oct 2022 11:59:09 -0400 Subject: [Git][ghc/ghc][master] DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Message-ID: <634d7bcd70309_8b90f514144880b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 6 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -553,13 +553,16 @@ analysing their unfolding. A few reasons for the change: *workers*, because their transformers need to adapt to CPR for their arguments in 'cprTransformDataConWork' to enable Note [Nested CPR]. Better keep it all in this module! The alternative would be that - 'GHC.Types.Id.Make' depends on DmdAnal. + 'GHC.Types.Id.Make' depends on CprAnal. 3. In the future, Nested CPR could take a better account of incoming args in cprAnalApp and do some beta-reduction on the fly, like !1866 did. If any of those args had the CPR property, then we'd even get Nested CPR for DataCon wrapper calls, for free. Not so if we simply give the wrapper a single CPR sig in 'GHC.Types.Id.Make.mkDataConRep'! +DmdAnal also looks through the wrapper's unfolding: +See Note [DmdAnal for DataCon wrappers]. + Note [Trimming to mAX_CPR_SIZE] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We do not treat very big tuples as CPR-ish: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -985,6 +985,10 @@ dmdTransform env var sd | isDataConWorkId var = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ dmdTransformDataConSig (idArity var) sd + -- See Note [DmdAnal for DataCon wrappers] + | isDataConWrapId var, let rhs = uf_tmpl (realIdUnfolding var) + , WithDmdType dmd_ty _rhs' <- dmdAnal env sd rhs + = dmd_ty -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1388,6 +1392,45 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +Note [DmdAnal for DataCon wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We give DataCon wrappers a (necessarily flat) demand signature in +`GHC.Types.Id.Make.mkDataConRep`, so that passes such as the Simplifier can +exploit it via the call to `GHC.Core.Opt.Simplify.Utils.isStrictArgInfo` in +`GHC.Core.Opt.Simplify.Iteration.rebuildCall`. But during DmdAnal, we *ignore* +the demand signature of a DataCon wrapper, and instead analyse its unfolding at +every call site. + +The reason is that DataCon *worker*s have very precise demand transformers, +computed by `dmdTransformDataConSig`. It would be awkward if DataCon *wrappers* +would behave much less precisely during DmdAnal. Example: + + data T1 = MkT1 { get_x1 :: Int, get_y1 :: Int } + data T2 = MkT2 { get_x2 :: !Int, get_y2 :: Int } + f1 x y = get_x1 (MkT1 x y) + f2 x y = get_x2 (MkT2 x y) + +Here `MkT1` has no wrapper. `get_x1` puts a demand `!P(1!L,A)` on its argument, +and `dmdTransformDataConSig` will transform that demand to an absent demand on +`y` in `f1` and an unboxing demand on `x`. +But `MkT2` has a wrapper (to evaluate the first field). If demand analysis deals +with `MkT2` only through its demand signature, demand signatures can't transform +an incoming demand `P(1!L,A)` in a useful way, so we won't get an absent demand +on `y` in `f2` or see that `x` can be unboxed. That's a serious loss. + +The example above will not actually occur, because $WMkT2 would be inlined. +Nevertheless, we can get interesting sub-demands on DataCon wrapper +applications in boring contexts; see T22241. + +You might worry about the efficiency cost of demand-analysing datacon wrappers +at every call site. But in fact they are inlined /anyway/ in the Final phase, +which happens before DmdAnal, so few wrappers remain. And analysing the +unfoldings for the remaining calls (which are those in a boring context) will be +exactly as (in)efficent as if we'd inlined those calls. It turns out to be not +measurable in practice. + +See also Note [CPR for DataCon wrappers] in `GHC.Core.Opt.CprAnal`. + Note [Boxity for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider (A) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -477,9 +477,9 @@ mkDictSelId name clas -- See Note [Type classes and linear types] base_info = noCafIdInfo - `setArityInfo` 1 - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` 1 + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig info | new_tycon = base_info `setInlinePragInfo` alwaysInlinePragma @@ -697,6 +697,8 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + -- The signature is purely for passes like the Simplifier, not for + -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv wrap_arg_dmds = @@ -1321,9 +1323,9 @@ mkFCallId uniq fcall ty name = mkFCallName uniq occ_str info = noCafIdInfo - `setArityInfo` arity - `setDmdSigInfo` strict_sig - `setCprSigInfo` topCprSig + `setArityInfo` arity + `setDmdSigInfo` strict_sig + `setCprSigInfo` topCprSig (bndrs, _) = tcSplitPiTys ty arity = count isAnonTyCoBinder bndrs ===================================== testsuite/tests/stranal/sigs/T22241.hs ===================================== @@ -0,0 +1,31 @@ +module T22241 where + +data D = D { unD :: !Int } + +-- We should unbox y here, which only happens if DmdAnal sees that $WD will +-- unbox it. +f :: Bool -> Int -> D +f x y = D (go x) + where + go False = y + go True = go False +{-# NOINLINE f #-} + + + +data T a = T Int !a +get (T _ x) = x + +-- Here, the goal is to discard `unD (f True z)` and thus `z` as absent by +-- looking through $WT in `j` *during the first pass of DmdAnal*! +g :: Bool -> Int -> Int -> Bool +g x y z | even y = get (fst t) + | y > 13 = not (get (fst t)) + | otherwise = False + where + t | x = j (unD (f True z)) + | otherwise = j (unD (f False z)) + where + j a = (T a x, True) + {-# NOINLINE j #-} +{-# NOINLINE g #-} ===================================== testsuite/tests/stranal/sigs/T22241.stderr ===================================== @@ -0,0 +1,24 @@ + +==================== Strictness signatures ==================== +T22241.f: <1L> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + + +==================== Cpr signatures ==================== +T22241.f: 1 +T22241.g: +T22241.get: +T22241.unD: 1 + + + +==================== Strictness signatures ==================== +T22241.f: <1L><1!P(SL)> +T22241.g: <1!P(L)> +T22241.get: <1!P(A,1L)> +T22241.unD: <1!P(L)> + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -37,3 +37,4 @@ test('T21717', normal, compile, ['']) test('T21754', normal, compile, ['']) test('T21888', normal, compile, ['']) test('T21888a', normal, compile, ['']) +test('T22241', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1e5719aa500cb9e0f2549eb9b9e2255038ac35d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1e5719aa500cb9e0f2549eb9b9e2255038ac35d You're receiving 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 Oct 17 16:30:10 2022 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Oct 2022 12:30:10 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Message-ID: <634d83124592f_8b90f514144958d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 1ea328b9 by Gergo ERDI at 2022-10-17T12:29:44-04:00 Add `Enum (Down a)` instance that swaps `succ` and `pred` See https://github.com/haskell/core-libraries-committee/issues/51 for discussion. The key points driving the implementation are the following two ideas: * For the `Int` type, `comparing (complement @Int)` behaves exactly as an order-swapping `compare @Int`. * `enumFrom @(Down a)` can be implemented in terms of `enumFromThen @a`, if only the corner case of starting at the very end is handled specially - - - - - 640051f0 by Alan Zimmerman at 2022-10-17T12:29:44-04:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - f275e39c by Andreas Klebinger at 2022-10-17T12:29:45-04:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - 368c2359 by Andreas Klebinger at 2022-10-17T12:29:45-04:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - d05b4f93 by Eric Lindblad at 2022-10-17T12:29:50-04:00 example rewrite - - - - - b8bf5873 by Eric Lindblad at 2022-10-17T12:29:50-04:00 remove redirect - - - - - 870be1ed by Eric Lindblad at 2022-10-17T12:29:50-04:00 use heredoc - - - - - 7958393a by Matthew Pickering at 2022-10-17T12:29:51-04:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - 3b5cd3ca by Krzysztof Gogolewski at 2022-10-17T12:29:51-04:00 Fix T15155l not getting -fllvm - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Var/Env.hs - libraries/base/Data/Ord.hs - libraries/base/changelog.md - testsuite/config/ghc - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/ghc-config/ghc-config.hs - testsuite/mk/test.mk - testsuite/tests/codeGen/should_compile/Makefile - testsuite/tests/codeGen/should_compile/all.T - testsuite/tests/ghc-api/exactprint/AddDecl2.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.expected.hs - testsuite/tests/ghc-api/exactprint/RmDecl7.hs - testsuite/tests/printer/Makefile - + testsuite/tests/printer/Test21355.hs - testsuite/tests/printer/all.T - + testsuite/tests/stranal/sigs/T22241.hs - + testsuite/tests/stranal/sigs/T22241.stderr - testsuite/tests/stranal/sigs/all.T - utils/check-exact/.ghci The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e09bd1d388e06a978410886d3d998ba5ce64e1cf...3b5cd3ca3e679db9f1d9e0d47ed166b5d534897f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e09bd1d388e06a978410886d3d998ba5ce64e1cf...3b5cd3ca3e679db9f1d9e0d47ed166b5d534897f You're receiving 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 Oct 17 16:48:18 2022 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 17 Oct 2022 12:48:18 -0400 Subject: [Git][ghc/ghc][wip/T22227] 40 commits: Tidy implicit binds Message-ID: <634d8752b8aa2_8b90f5143c52729e@gitlab.mail> Sebastian Graf pushed to branch wip/T22227 at Glasgow Haskell Compiler / GHC Commits: fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 39a35f91 by Sebastian Graf at 2022-10-17T18:48:02+02:00 Loopification in OccurAnal (#13966, #14068, #14287, #22227) The join point work postulated the feasability of a Skip-less definition of an unfoldr/destroy stream fusion framework at no performance cost, but we so far lacked the necessary loopification transformation to make the prophecy come true. This patch changes that. Now, whenever occurrence analysis spots a tail-recursive letrec that is not already a join point, e.g., ``` letrec next x = if .. then 0 else next (x+1) in \y -> if odd (next y) then "odd" else "even" ``` it will transform to ``` let next x = joinrec next x = if .. then 0 else next (x+1) in next x in \y -> if odd (next y) then "odd" else "even" ``` And now `next` is likely to inline, enabling further simplification. More details in Note [Join point loopification]. Fixes #13966, #14068, #14287, #22227 and adds according reproduction test cases. - - - - - 0d3ed47f by Sebastian Graf at 2022-10-17T18:48:02+02:00 Denest NonRecs in SpecConstr for more specialisation (#22277) See Note [Denesting non-recursive let bindings]. Fixes #22277. It is also related to #14951 and #14844 in that it fixes a very specific case of looking through a non-recursive let binding in SpecConstr. If applied to master pre-loopification changes (see !9141), there is virtually no impact on NoFib or ghc/alloc perf, but it fixes a bad interaction between Loopification and SpecConstr. - - - - - 129906ad by Sebastian Graf at 2022-10-17T18:48:02+02:00 Remove Note [Self-recursive tail calls] We now do loopification in Core, so there should be no letrec left where all recursive calls are in tail position and the code is effectively dead. Hence we remove it. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Lint.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Exitify.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Opt/Simplify/Env.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Pipeline/Phases.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/31c14aedc1c58e6be0f6ff29f51ca782f5930f8a...129906ad4d5bcbe40d00a82bc2ff721b7f55e558 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/31c14aedc1c58e6be0f6ff29f51ca782f5930f8a...129906ad4d5bcbe40d00a82bc2ff721b7f55e558 You're receiving 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 Oct 17 17:58:24 2022 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 17 Oct 2022 13:58:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/drop-long-reg Message-ID: <634d97c0c3d93_8b90f5143c544273@gitlab.mail> Ben Gamari pushed new branch wip/drop-long-reg at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/drop-long-reg You're receiving 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 Oct 17 20:16:20 2022 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 17 Oct 2022 16:16:20 -0400 Subject: [Git][ghc/ghc][wip/foundation-tests] 20 commits: Mark T7919 as fragile Message-ID: <634db8146e24f_8b90f517485754fb@gitlab.mail> Matthew Pickering pushed to branch wip/foundation-tests at Glasgow Haskell Compiler / GHC Commits: 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - f30e3ebd by Matthew Pickering at 2022-10-17T21:16:03+01:00 Port foundation numeric tests to GHC testsuite - - - - - 30 changed files: - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/phases.rst - ghc/GHCi/UI/Monad.hs - libraries/base/Data/Char.hs - libraries/base/Data/OldList.hs - libraries/base/GHC/IO/Windows/Handle.hsc - libraries/base/GHC/Unicode.hs - + libraries/base/GHC/Unicode/Internal/Char/DerivedCoreProperties.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/tests/unicode001.hs - libraries/base/tests/unicode001.stdout - libraries/base/tools/ucd2haskell/exe/Parser/Text.hs - libraries/base/tools/ucd2haskell/tests/check_all_chars.py - libraries/base/tools/ucd2haskell/tests/export_all_chars.hs - libraries/base/tools/ucd2haskell/ucd.sh - rts/Schedule.c - rts/Schedule.h - rts/linker/Elf.c - rts/linker/ElfTypes.h - + rts/linker/InitFini.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b291f60fd9c22e23b560202ab20546b50330d148...f30e3ebd1e759b9a27913bb88b7cb847f9e9e979 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b291f60fd9c22e23b560202ab20546b50330d148...f30e3ebd1e759b9a27913bb88b7cb847f9e9e979 You're receiving 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 Oct 17 22:41:34 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 18:41:34 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/untangle-inline Message-ID: <634dda1e40584_8b90f517485848c9@gitlab.mail> Andreas Klebinger pushed new branch wip/andreask/untangle-inline at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/untangle-inline You're receiving 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 Oct 17 22:47:00 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 18:47:00 -0400 Subject: [Git][ghc/ghc][wip/andreask/untangle-inline] Separate core inlining logic from `Unfolding` type. Message-ID: <634ddb649b6a8_8b90f5175c585025@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/untangle-inline at Glasgow Haskell Compiler / GHC Commits: 940aac94 by Andreas Klebinger at 2022-10-18T00:44:11+02:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 5 changed files: - + compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Unfold.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Inline.hs ===================================== @@ -0,0 +1,632 @@ +{- +(c) The University of Glasgow 2006 +(c) The AQUA Project, Glasgow University, 1994-1998 + +This module contains inlining logic used by the simplifier. +-} + + +{-# LANGUAGE BangPatterns #-} + +module GHC.Core.Opt.Simplify.Inline ( + ArgSummary(..), + + -- * Cheap and cheerful inlining checks. + couldBeSmallEnoughToInline, + smallEnoughToInline, + + -- * The smart inlining decisions are made by callSiteInline + callSiteInline, CallCtxt(..), + ) where + +import GHC.Prelude + +import GHC.Driver.Flags + +import GHC.Core +import GHC.Core.Unfold +import GHC.Types.Id +import GHC.Types.Basic ( Arity, RecFlag(..) ) +import GHC.Utils.Logger +import GHC.Utils.Misc +import GHC.Utils.Outputable +import GHC.Types.Name + +import Data.List (isPrefixOf) + +{- +************************************************************************ +* * +\subsection[considerUnfolding]{Given all the info, do (not) do the unfolding} +* * +************************************************************************ + +We use 'couldBeSmallEnoughToInline' to avoid exporting inlinings that +we ``couldn't possibly use'' on the other side. Can be overridden w/ +flaggery. Just the same as smallEnoughToInline, except that it has no +actual arguments. +-} + +couldBeSmallEnoughToInline :: UnfoldingOpts -> Int -> CoreExpr -> Bool +couldBeSmallEnoughToInline opts threshold rhs + = case sizeExpr opts threshold [] body of + TooBig -> False + _ -> True + where + (_, body) = collectBinders rhs + +---------------- +smallEnoughToInline :: UnfoldingOpts -> Unfolding -> Bool +smallEnoughToInline opts (CoreUnfolding {uf_guidance = guidance}) + = case guidance of + UnfIfGoodArgs {ug_size = size} -> size <= unfoldingUseThreshold opts + UnfWhen {} -> True + UnfNever -> False +smallEnoughToInline _ _ + = False + + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +data ArgSummary = TrivArg -- Nothing interesting + | NonTrivArg -- Arg has structure + | ValueArg -- Arg is a con-app or PAP + -- ..or con-like. Note [Conlike is interesting] + +instance Outputable ArgSummary where + ppr TrivArg = text "TrivArg" + ppr NonTrivArg = text "NonTrivArg" + ppr ValueArg = text "ValueArg" + +nonTriv :: ArgSummary -> Bool +nonTriv TrivArg = False +nonTriv _ = True + +data CallCtxt + = BoringCtxt + | RhsCtxt RecFlag -- Rhs of a let-binding; see Note [RHS of lets] + | DiscArgCtxt -- Argument of a function with non-zero arg discount + | RuleArgCtxt -- We are somewhere in the argument of a function with rules + + | ValAppCtxt -- We're applied to at least one value arg + -- This arises when we have ((f x |> co) y) + -- Then the (f x) has argument 'x' but in a ValAppCtxt + + | CaseCtxt -- We're the scrutinee of a case + -- that decomposes its scrutinee + +instance Outputable CallCtxt where + ppr CaseCtxt = text "CaseCtxt" + ppr ValAppCtxt = text "ValAppCtxt" + ppr BoringCtxt = text "BoringCtxt" + ppr (RhsCtxt ir)= text "RhsCtxt" <> parens (ppr ir) + ppr DiscArgCtxt = text "DiscArgCtxt" + ppr RuleArgCtxt = text "RuleArgCtxt" + +callSiteInline :: Logger + -> UnfoldingOpts + -> Int -- Case depth + -> Id -- The Id + -> Bool -- True <=> unfolding is active + -> Bool -- True if there are no arguments at all (incl type args) + -> [ArgSummary] -- One for each value arg; True if it is interesting + -> CallCtxt -- True <=> continuation is interesting + -> Maybe CoreExpr -- Unfolding, if any +callSiteInline logger opts !case_depth id active_unfolding lone_variable arg_infos cont_info + = case idUnfolding id of + -- idUnfolding checks for loop-breakers, returning NoUnfolding + -- Things with an INLINE pragma may have an unfolding *and* + -- be a loop breaker (maybe the knot is not yet untied) + CoreUnfolding { uf_tmpl = unf_template + , uf_is_work_free = is_wf + , uf_guidance = guidance, uf_expandable = is_exp } + | active_unfolding -> tryUnfolding logger opts case_depth id lone_variable + arg_infos cont_info unf_template + is_wf is_exp guidance + | otherwise -> traceInline logger opts id "Inactive unfolding:" (ppr id) Nothing + NoUnfolding -> Nothing + BootUnfolding -> Nothing + OtherCon {} -> Nothing + DFunUnfolding {} -> Nothing -- Never unfold a DFun + +-- | Report the inlining of an identifier's RHS to the user, if requested. +traceInline :: Logger -> UnfoldingOpts -> Id -> String -> SDoc -> a -> a +traceInline logger opts inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. + | enable = logTraceMsg logger str doc result + | otherwise = result + where + enable + | logHasDumpFlag logger Opt_D_dump_verbose_inlinings + = True + | Just prefix <- unfoldingReportPrefix opts + = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] + +{- Note [Avoid inlining into deeply nested cases] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Consider a function f like this: + + f arg1 arg2 = + case ... + ... -> g arg1 + ... -> g arg2 + +This function is small. So should be safe to inline. +However sometimes this doesn't quite work out like that. +Consider this code: + +f1 arg1 arg2 ... = ... + case _foo of + alt1 -> ... f2 arg1 ... + alt2 -> ... f2 arg2 ... + +f2 arg1 arg2 ... = ... + case _foo of + alt1 -> ... f3 arg1 ... + alt2 -> ... f3 arg2 ... + +f3 arg1 arg2 ... = ... + +... repeats up to n times. And then f1 is +applied to some arguments: + +foo = ... f1 ... + +Initially f2..fn are not interesting to inline so we don't. +However we see that f1 is applied to interesting args. +So it's an obvious choice to inline those: + +foo = + ... + case _foo of + alt1 -> ... f2 ... + alt2 -> ... f2 ... + +As a result we go and inline f2 both mentions of f2 in turn are now applied to interesting +arguments and f2 is small: + +foo = + ... + case _foo of + alt1 -> ... case _foo of + alt1 -> ... f3 ... + alt2 -> ... f3 ... + + alt2 -> ... case _foo of + alt1 -> ... f3 ... + alt2 -> ... f3 ... + +The same thing happens for each binding up to f_n, duplicating the amount of inlining +done in each step. Until at some point we are either done or run out of simplifier +ticks/RAM. This pattern happened #18730. + +To combat this we introduce one more heuristic when weighing inlining decision. +We keep track of a "case-depth". Which increases each time we look inside a case +expression with more than one alternative. + +We then apply a penalty to inlinings based on the case-depth at which they would +be inlined. Bounding the number of inlinings in such a scenario. + +The heuristic can be tuned in two ways: + +* We can ignore the first n levels of case nestings for inlining decisions using + -funfolding-case-threshold. +* The penalty grows linear with the depth. It's computed as size*(depth-threshold)/scaling. + Scaling can be set with -funfolding-case-scaling. + +Some guidance on setting these defaults: + +* A low treshold (<= 2) is needed to prevent exponential cases from spiraling out of + control. We picked 2 for no particular reason. +* Scaling the penalty by any more than 30 means the reproducer from + T18730 won't compile even with reasonably small values of n. Instead + it will run out of runs/ticks. This means to positively affect the reproducer + a scaling <= 30 is required. +* A scaling of >= 15 still causes a few very large regressions on some nofib benchmarks. + (+80% for gc/fulsom, +90% for real/ben-raytrace, +20% for spectral/fibheaps) +* A scaling of >= 25 showed no regressions on nofib. However it showed a number of + (small) regression for compiler perf benchmarks. + +The end result is that we are settling for a scaling of 30, with a threshold of 2. +This gives us minimal compiler perf regressions. No nofib runtime regressions and +will still avoid this pattern sometimes. This is a "safe" default, where we err on +the side of compiler blowup instead of risking runtime regressions. + +For cases where the default falls short the flag can be changed to allow more/less inlining as +needed on a per-module basis. + +-} + +tryUnfolding :: Logger -> UnfoldingOpts -> Int -> Id -> Bool -> [ArgSummary] -> CallCtxt + -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance + -> Maybe CoreExpr +tryUnfolding logger opts !case_depth id lone_variable + arg_infos cont_info unf_template + is_wf is_exp guidance + = case guidance of + UnfNever -> traceInline logger opts id str (text "UnfNever") Nothing + + UnfWhen { ug_arity = uf_arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } + | enough_args && (boring_ok || some_benefit || unfoldingVeryAggressive opts) + -- See Note [INLINE for small functions] (3) + -> traceInline logger opts id str (mk_doc some_benefit empty True) (Just unf_template) + | otherwise + -> traceInline logger opts id str (mk_doc some_benefit empty False) Nothing + where + some_benefit = calc_some_benefit uf_arity + enough_args = (n_val_args >= uf_arity) || (unsat_ok && n_val_args > 0) + + UnfIfGoodArgs { ug_args = arg_discounts, ug_res = res_discount, ug_size = size } + | unfoldingVeryAggressive opts + -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) + | is_wf && some_benefit && small_enough + -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) + | otherwise + -> traceInline logger opts id str (mk_doc some_benefit extra_doc False) Nothing + where + some_benefit = calc_some_benefit (length arg_discounts) + extra_doc = vcat [ text "case depth =" <+> int case_depth + , text "depth based penalty =" <+> int depth_penalty + , text "discounted size =" <+> int adjusted_size ] + -- See Note [Avoid inlining into deeply nested cases] + depth_treshold = unfoldingCaseThreshold opts + depth_scaling = unfoldingCaseScaling opts + depth_penalty | case_depth <= depth_treshold = 0 + | otherwise = (size * (case_depth - depth_treshold)) `div` depth_scaling + adjusted_size = size + depth_penalty - discount + small_enough = adjusted_size <= unfoldingUseThreshold opts + discount = computeDiscount arg_discounts res_discount arg_infos cont_info + + where + mk_doc some_benefit extra_doc yes_or_no + = vcat [ text "arg infos" <+> ppr arg_infos + , text "interesting continuation" <+> ppr cont_info + , text "some_benefit" <+> ppr some_benefit + , text "is exp:" <+> ppr is_exp + , text "is work-free:" <+> ppr is_wf + , text "guidance" <+> ppr guidance + , extra_doc + , text "ANSWER =" <+> if yes_or_no then text "YES" else text "NO"] + + ctx = log_default_dump_context (logFlags logger) + str = "Considering inlining: " ++ showSDocOneLine ctx (ppr id) + n_val_args = length arg_infos + + -- some_benefit is used when the RHS is small enough + -- and the call has enough (or too many) value + -- arguments (ie n_val_args >= arity). But there must + -- be *something* interesting about some argument, or the + -- result context, to make it worth inlining + calc_some_benefit :: Arity -> Bool -- The Arity is the number of args + -- expected by the unfolding + calc_some_benefit uf_arity + | not saturated = interesting_args -- Under-saturated + -- Note [Unsaturated applications] + | otherwise = interesting_args -- Saturated or over-saturated + || interesting_call + where + saturated = n_val_args >= uf_arity + over_saturated = n_val_args > uf_arity + interesting_args = any nonTriv arg_infos + -- NB: (any nonTriv arg_infos) looks at the + -- over-saturated args too which is "wrong"; + -- but if over-saturated we inline anyway. + + interesting_call + | over_saturated + = True + | otherwise + = case cont_info of + CaseCtxt -> not (lone_variable && is_exp) -- Note [Lone variables] + ValAppCtxt -> True -- Note [Cast then apply] + RuleArgCtxt -> uf_arity > 0 -- See Note [RHS of lets] + DiscArgCtxt -> uf_arity > 0 -- Note [Inlining in ArgCtxt] + RhsCtxt NonRecursive + -> uf_arity > 0 -- See Note [RHS of lets] + _other -> False -- See Note [Nested functions] + + +{- Note [RHS of lets] +~~~~~~~~~~~~~~~~~~~~~ +When the call is the argument of a function with a RULE, or the RHS of a let, +we are a little bit keener to inline (in tryUnfolding). For example + f y = (y,y,y) + g y = let x = f y in ...(case x of (a,b,c) -> ...) ... +We'd inline 'f' if the call was in a case context, and it kind-of-is, +only we can't see it. Also + x = f v +could be expensive whereas + x = case v of (a,b) -> a +is patently cheap and may allow more eta expansion. + +So, in `interesting_call` in `tryUnfolding`, we treat the RHS of a +/non-recursive/ let as not-totally-boring. A /recursive/ let isn't +going be inlined so there is much less point. Hence the (only reason +for the) RecFlag in RhsCtxt + +Note [Unsaturated applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When a call is not saturated, we *still* inline if one of the +arguments has interesting structure. That's sometimes very important. +A good example is the Ord instance for Bool in Base: + + Rec { + $fOrdBool =GHC.Classes.D:Ord + @ Bool + ... + $cmin_ajX + + $cmin_ajX [Occ=LoopBreaker] :: Bool -> Bool -> Bool + $cmin_ajX = GHC.Classes.$dmmin @ Bool $fOrdBool + } + +But the defn of GHC.Classes.$dmmin is: + + $dmmin :: forall a. GHC.Classes.Ord a => a -> a -> a + {- Arity: 3, HasNoCafRefs, Strictness: SLL, + Unfolding: (\ @ a $dOrd :: GHC.Classes.Ord a x :: a y :: a -> + case @ a GHC.Classes.<= @ a $dOrd x y of wild { + GHC.Types.False -> y GHC.Types.True -> x }) -} + +We *really* want to inline $dmmin, even though it has arity 3, in +order to unravel the recursion. + + +Note [Things to watch] +~~~~~~~~~~~~~~~~~~~~~~ +* { y = I# 3; x = y `cast` co; ...case (x `cast` co) of ... } + Assume x is exported, so not inlined unconditionally. + Then we want x to inline unconditionally; no reason for it + not to, and doing so avoids an indirection. + +* { x = I# 3; ....f x.... } + Make sure that x does not inline unconditionally! + Lest we get extra allocation. + +Note [Nested functions] +~~~~~~~~~~~~~~~~~~~~~~~ +At one time we treated a call of a non-top-level function as +"interesting" (regardless of how boring the context) in the hope +that inlining it would eliminate the binding, and its allocation. +Specifically, in the default case of interesting_call we had + _other -> not is_top && uf_arity > 0 + +But actually postInlineUnconditionally does some of this and overall +it makes virtually no difference to nofib. So I simplified away this +special case + +Note [Cast then apply] +~~~~~~~~~~~~~~~~~~~~~~ +Consider + myIndex = __inline_me ( (/\a. ) |> co ) + co :: (forall a. a -> a) ~ (forall a. T a) + ... /\a.\x. case ((myIndex a) |> sym co) x of { ... } ... + +We need to inline myIndex to unravel this; but the actual call (myIndex a) has +no value arguments. The ValAppCtxt gives it enough incentive to inline. + +Note [Inlining in ArgCtxt] +~~~~~~~~~~~~~~~~~~~~~~~~~~ +The condition (arity > 0) here is very important, because otherwise +we end up inlining top-level stuff into useless places; eg + x = I# 3# + f = \y. g x +This can make a very big difference: it adds 16% to nofib 'integer' allocs, +and 20% to 'power'. + +At one stage I replaced this condition by 'True' (leading to the above +slow-down). The motivation was test eyeball/inline1.hs; but that seems +to work ok now. + +NOTE: arguably, we should inline in ArgCtxt only if the result of the +call is at least CONLIKE. At least for the cases where we use ArgCtxt +for the RHS of a 'let', we only profit from the inlining if we get a +CONLIKE thing (modulo lets). + +Note [Lone variables] See also Note [Interaction of exprIsWorkFree and lone variables] +~~~~~~~~~~~~~~~~~~~~~ which appears below +The "lone-variable" case is important. I spent ages messing about +with unsatisfactory variants, but this is nice. The idea is that if a +variable appears all alone + + as an arg of lazy fn, or rhs BoringCtxt + as scrutinee of a case CaseCtxt + as arg of a fn ArgCtxt +AND + it is bound to a cheap expression + +then we should not inline it (unless there is some other reason, +e.g. it is the sole occurrence). That is what is happening at +the use of 'lone_variable' in 'interesting_call'. + +Why? At least in the case-scrutinee situation, turning + let x = (a,b) in case x of y -> ... +into + let x = (a,b) in case (a,b) of y -> ... +and thence to + let x = (a,b) in let y = (a,b) in ... +is bad if the binding for x will remain. + +Another example: I discovered that strings +were getting inlined straight back into applications of 'error' +because the latter is strict. + s = "foo" + f = \x -> ...(error s)... + +Fundamentally such contexts should not encourage inlining because, provided +the RHS is "expandable" (see Note [exprIsExpandable] in GHC.Core.Utils) the +context can ``see'' the unfolding of the variable (e.g. case or a +RULE) so there's no gain. + +However, watch out: + + * Consider this: + foo = \n. [n]) {-# INLINE foo #-} + bar = foo 20 {-# INLINE bar #-} + baz = \n. case bar of { (m:_) -> m + n } + Here we really want to inline 'bar' so that we can inline 'foo' + and the whole thing unravels as it should obviously do. This is + important: in the NDP project, 'bar' generates a closure data + structure rather than a list. + + So the non-inlining of lone_variables should only apply if the + unfolding is regarded as expandable; because that is when + exprIsConApp_maybe looks through the unfolding. Hence the "&& + is_exp" in the CaseCtxt branch of interesting_call + + * Even a type application or coercion isn't a lone variable. + Consider + case $fMonadST @ RealWorld of { :DMonad a b c -> c } + We had better inline that sucker! The case won't see through it. + + For now, I'm treating treating a variable applied to types + in a *lazy* context "lone". The motivating example was + f = /\a. \x. BIG + g = /\a. \y. h (f a) + There's no advantage in inlining f here, and perhaps + a significant disadvantage. Hence some_val_args in the Stop case + +Note [Interaction of exprIsWorkFree and lone variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The lone-variable test says "don't inline if a case expression +scrutinises a lone variable whose unfolding is cheap". It's very +important that, under these circumstances, exprIsConApp_maybe +can spot a constructor application. So, for example, we don't +consider + let x = e in (x,x) +to be cheap, and that's good because exprIsConApp_maybe doesn't +think that expression is a constructor application. + +In the 'not (lone_variable && is_wf)' test, I used to test is_value +rather than is_wf, which was utterly wrong, because the above +expression responds True to exprIsHNF, which is what sets is_value. + +This kind of thing can occur if you have + + {-# INLINE foo #-} + foo = let x = e in (x,x) + +which Roman did. + + +-} + +computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt + -> Int +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 + + + 10 * length actual_arg_discounts + -- Discount of 10 for each arg supplied, + -- because the result replaces the call + + + total_arg_discount + res_discount' + where + actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos + total_arg_discount = sum actual_arg_discounts + + mk_arg_discount _ TrivArg = 0 + mk_arg_discount _ NonTrivArg = 10 + mk_arg_discount discount ValueArg = discount + + res_discount' + | LT <- arg_discounts `compareLength` arg_infos + = res_discount -- Over-saturated + | otherwise + = case cont_info of + BoringCtxt -> 0 + CaseCtxt -> res_discount -- Presumably a constructor + ValAppCtxt -> res_discount -- Presumably a function + _ -> 40 `min` res_discount + -- ToDo: this 40 `min` res_discount doesn't seem right + -- for DiscArgCtxt it shouldn't matter because the function will + -- get the arg discount for any non-triv arg + -- for RuleArgCtxt we do want to be keener to inline; but not only + -- constructor results + -- for RhsCtxt I suppose that exposing a data con is good in general + -- And 40 seems very arbitrary + -- + -- res_discount can be very large when a function returns + -- constructors; but we only want to invoke that large discount + -- when there's a case continuation. + -- Otherwise we, rather arbitrarily, threshold it. Yuk. + -- But we want to avoid inlining large functions that return + -- constructors into contexts that are simply "interesting" \ No newline at end of file ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -21,6 +21,7 @@ import GHC.Core import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.Opt.Simplify.Env +import GHC.Core.Opt.Simplify.Inline import GHC.Core.Opt.Simplify.Utils import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs ) import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr ) ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -47,6 +47,7 @@ import GHC.Prelude import GHC.Core import GHC.Types.Literal ( isLitRubbish ) import GHC.Core.Opt.Simplify.Env +import GHC.Core.Opt.Simplify.Inline import GHC.Core.Opt.Stats ( Tick(..) ) import qualified GHC.Core.Subst import GHC.Core.Ppr ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -27,19 +27,11 @@ module GHC.Core.Unfold ( updateVeryAggressive, updateCaseScaling, updateCaseThreshold, updateReportPrefix, - ArgSummary(..), - - couldBeSmallEnoughToInline, inlineBoringOk, - smallEnoughToInline, - - callSiteInline, CallCtxt(..), - calcUnfoldingGuidance + inlineBoringOk, calcUnfoldingGuidance ) where import GHC.Prelude -import GHC.Driver.Flags - import GHC.Core import GHC.Core.Utils import GHC.Types.Id @@ -48,20 +40,16 @@ import GHC.Types.Literal import GHC.Builtin.PrimOps import GHC.Types.Id.Info import GHC.Types.RepType ( isZeroBitTy ) -import GHC.Types.Basic ( Arity, RecFlag(..) ) +import GHC.Types.Basic ( Arity ) import GHC.Core.Type import GHC.Builtin.Names import GHC.Data.Bag -import GHC.Utils.Logger import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Types.ForeignCall -import GHC.Types.Name import GHC.Types.Tickish import qualified Data.ByteString as BS -import Data.List (isPrefixOf) - -- | Unfolding options data UnfoldingOpts = UnfoldingOpts @@ -931,550 +919,3 @@ sizeN :: Int -> ExprSize sizeZero = SizeIs 0 emptyBag 0 sizeN n = SizeIs n emptyBag 0 -{- -************************************************************************ -* * -\subsection[considerUnfolding]{Given all the info, do (not) do the unfolding} -* * -************************************************************************ - -We use 'couldBeSmallEnoughToInline' to avoid exporting inlinings that -we ``couldn't possibly use'' on the other side. Can be overridden w/ -flaggery. Just the same as smallEnoughToInline, except that it has no -actual arguments. --} - -couldBeSmallEnoughToInline :: UnfoldingOpts -> Int -> CoreExpr -> Bool -couldBeSmallEnoughToInline opts threshold rhs - = case sizeExpr opts threshold [] body of - TooBig -> False - _ -> True - where - (_, body) = collectBinders rhs - ----------------- -smallEnoughToInline :: UnfoldingOpts -> Unfolding -> Bool -smallEnoughToInline opts (CoreUnfolding {uf_guidance = guidance}) - = case guidance of - UnfIfGoodArgs {ug_size = size} -> size <= unfoldingUseThreshold opts - UnfWhen {} -> True - UnfNever -> False -smallEnoughToInline _ _ - = False - -{- -************************************************************************ -* * -\subsection{callSiteInline} -* * -************************************************************************ - -This is the key function. It decides whether to inline a variable at a call site - -callSiteInline is used at call sites, so it is a bit more generous. -It's a very important function that embodies lots of heuristics. -A non-WHNF can be inlined if it doesn't occur inside a lambda, -and occurs exactly once or - occurs once in each branch of a case and is small - -If the thing is in WHNF, there's no danger of duplicating work, -so we can inline if it occurs once, or is small - -NOTE: we don't want to inline top-level functions that always diverge. -It just makes the code bigger. Tt turns out that the convenient way to prevent -them inlining is to give them a NOINLINE pragma, which we do in -StrictAnal.addStrictnessInfoToTopId --} - -data ArgSummary = TrivArg -- Nothing interesting - | NonTrivArg -- Arg has structure - | ValueArg -- Arg is a con-app or PAP - -- ..or con-like. Note [Conlike is interesting] - -instance Outputable ArgSummary where - ppr TrivArg = text "TrivArg" - ppr NonTrivArg = text "NonTrivArg" - ppr ValueArg = text "ValueArg" - -nonTriv :: ArgSummary -> Bool -nonTriv TrivArg = False -nonTriv _ = True - -data CallCtxt - = BoringCtxt - | RhsCtxt RecFlag -- Rhs of a let-binding; see Note [RHS of lets] - | DiscArgCtxt -- Argument of a function with non-zero arg discount - | RuleArgCtxt -- We are somewhere in the argument of a function with rules - - | ValAppCtxt -- We're applied to at least one value arg - -- This arises when we have ((f x |> co) y) - -- Then the (f x) has argument 'x' but in a ValAppCtxt - - | CaseCtxt -- We're the scrutinee of a case - -- that decomposes its scrutinee - -instance Outputable CallCtxt where - ppr CaseCtxt = text "CaseCtxt" - ppr ValAppCtxt = text "ValAppCtxt" - ppr BoringCtxt = text "BoringCtxt" - ppr (RhsCtxt ir)= text "RhsCtxt" <> parens (ppr ir) - ppr DiscArgCtxt = text "DiscArgCtxt" - ppr RuleArgCtxt = text "RuleArgCtxt" - -callSiteInline :: Logger - -> UnfoldingOpts - -> Int -- Case depth - -> Id -- The Id - -> Bool -- True <=> unfolding is active - -> Bool -- True if there are no arguments at all (incl type args) - -> [ArgSummary] -- One for each value arg; True if it is interesting - -> CallCtxt -- True <=> continuation is interesting - -> Maybe CoreExpr -- Unfolding, if any -callSiteInline logger opts !case_depth id active_unfolding lone_variable arg_infos cont_info - = case idUnfolding id of - -- idUnfolding checks for loop-breakers, returning NoUnfolding - -- Things with an INLINE pragma may have an unfolding *and* - -- be a loop breaker (maybe the knot is not yet untied) - CoreUnfolding { uf_tmpl = unf_template - , uf_is_work_free = is_wf - , uf_guidance = guidance, uf_expandable = is_exp } - | active_unfolding -> tryUnfolding logger opts case_depth id lone_variable - arg_infos cont_info unf_template - is_wf is_exp guidance - | otherwise -> traceInline logger opts id "Inactive unfolding:" (ppr id) Nothing - NoUnfolding -> Nothing - BootUnfolding -> Nothing - OtherCon {} -> Nothing - DFunUnfolding {} -> Nothing -- Never unfold a DFun - --- | Report the inlining of an identifier's RHS to the user, if requested. -traceInline :: Logger -> UnfoldingOpts -> Id -> String -> SDoc -> a -> a -traceInline logger opts inline_id str doc result - -- We take care to ensure that doc is used in only one branch, ensuring that - -- the simplifier can push its allocation into the branch. See Note [INLINE - -- conditional tracing utilities]. - | enable = logTraceMsg logger str doc result - | otherwise = result - where - enable - | logHasDumpFlag logger Opt_D_dump_verbose_inlinings - = True - | Just prefix <- unfoldingReportPrefix opts - = prefix `isPrefixOf` occNameString (getOccName inline_id) - | otherwise - = False -{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] - -{- Note [Avoid inlining into deeply nested cases] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Consider a function f like this: - - f arg1 arg2 = - case ... - ... -> g arg1 - ... -> g arg2 - -This function is small. So should be safe to inline. -However sometimes this doesn't quite work out like that. -Consider this code: - -f1 arg1 arg2 ... = ... - case _foo of - alt1 -> ... f2 arg1 ... - alt2 -> ... f2 arg2 ... - -f2 arg1 arg2 ... = ... - case _foo of - alt1 -> ... f3 arg1 ... - alt2 -> ... f3 arg2 ... - -f3 arg1 arg2 ... = ... - -... repeats up to n times. And then f1 is -applied to some arguments: - -foo = ... f1 ... - -Initially f2..fn are not interesting to inline so we don't. -However we see that f1 is applied to interesting args. -So it's an obvious choice to inline those: - -foo = - ... - case _foo of - alt1 -> ... f2 ... - alt2 -> ... f2 ... - -As a result we go and inline f2 both mentions of f2 in turn are now applied to interesting -arguments and f2 is small: - -foo = - ... - case _foo of - alt1 -> ... case _foo of - alt1 -> ... f3 ... - alt2 -> ... f3 ... - - alt2 -> ... case _foo of - alt1 -> ... f3 ... - alt2 -> ... f3 ... - -The same thing happens for each binding up to f_n, duplicating the amount of inlining -done in each step. Until at some point we are either done or run out of simplifier -ticks/RAM. This pattern happened #18730. - -To combat this we introduce one more heuristic when weighing inlining decision. -We keep track of a "case-depth". Which increases each time we look inside a case -expression with more than one alternative. - -We then apply a penalty to inlinings based on the case-depth at which they would -be inlined. Bounding the number of inlinings in such a scenario. - -The heuristic can be tuned in two ways: - -* We can ignore the first n levels of case nestings for inlining decisions using - -funfolding-case-threshold. -* The penalty grows linear with the depth. It's computed as size*(depth-threshold)/scaling. - Scaling can be set with -funfolding-case-scaling. - -Some guidance on setting these defaults: - -* A low treshold (<= 2) is needed to prevent exponential cases from spiraling out of - control. We picked 2 for no particular reason. -* Scaling the penalty by any more than 30 means the reproducer from - T18730 won't compile even with reasonably small values of n. Instead - it will run out of runs/ticks. This means to positively affect the reproducer - a scaling <= 30 is required. -* A scaling of >= 15 still causes a few very large regressions on some nofib benchmarks. - (+80% for gc/fulsom, +90% for real/ben-raytrace, +20% for spectral/fibheaps) -* A scaling of >= 25 showed no regressions on nofib. However it showed a number of - (small) regression for compiler perf benchmarks. - -The end result is that we are settling for a scaling of 30, with a threshold of 2. -This gives us minimal compiler perf regressions. No nofib runtime regressions and -will still avoid this pattern sometimes. This is a "safe" default, where we err on -the side of compiler blowup instead of risking runtime regressions. - -For cases where the default falls short the flag can be changed to allow more/less inlining as -needed on a per-module basis. - --} - -tryUnfolding :: Logger -> UnfoldingOpts -> Int -> Id -> Bool -> [ArgSummary] -> CallCtxt - -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance - -> Maybe CoreExpr -tryUnfolding logger opts !case_depth id lone_variable - arg_infos cont_info unf_template - is_wf is_exp guidance - = case guidance of - UnfNever -> traceInline logger opts id str (text "UnfNever") Nothing - - UnfWhen { ug_arity = uf_arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } - | enough_args && (boring_ok || some_benefit || unfoldingVeryAggressive opts) - -- See Note [INLINE for small functions] (3) - -> traceInline logger opts id str (mk_doc some_benefit empty True) (Just unf_template) - | otherwise - -> traceInline logger opts id str (mk_doc some_benefit empty False) Nothing - where - some_benefit = calc_some_benefit uf_arity - enough_args = (n_val_args >= uf_arity) || (unsat_ok && n_val_args > 0) - - UnfIfGoodArgs { ug_args = arg_discounts, ug_res = res_discount, ug_size = size } - | unfoldingVeryAggressive opts - -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) - | is_wf && some_benefit && small_enough - -> traceInline logger opts id str (mk_doc some_benefit extra_doc True) (Just unf_template) - | otherwise - -> traceInline logger opts id str (mk_doc some_benefit extra_doc False) Nothing - where - some_benefit = calc_some_benefit (length arg_discounts) - extra_doc = vcat [ text "case depth =" <+> int case_depth - , text "depth based penalty =" <+> int depth_penalty - , text "discounted size =" <+> int adjusted_size ] - -- See Note [Avoid inlining into deeply nested cases] - depth_treshold = unfoldingCaseThreshold opts - depth_scaling = unfoldingCaseScaling opts - depth_penalty | case_depth <= depth_treshold = 0 - | otherwise = (size * (case_depth - depth_treshold)) `div` depth_scaling - adjusted_size = size + depth_penalty - discount - small_enough = adjusted_size <= unfoldingUseThreshold opts - discount = computeDiscount arg_discounts res_discount arg_infos cont_info - - where - mk_doc some_benefit extra_doc yes_or_no - = vcat [ text "arg infos" <+> ppr arg_infos - , text "interesting continuation" <+> ppr cont_info - , text "some_benefit" <+> ppr some_benefit - , text "is exp:" <+> ppr is_exp - , text "is work-free:" <+> ppr is_wf - , text "guidance" <+> ppr guidance - , extra_doc - , text "ANSWER =" <+> if yes_or_no then text "YES" else text "NO"] - - ctx = log_default_dump_context (logFlags logger) - str = "Considering inlining: " ++ showSDocOneLine ctx (ppr id) - n_val_args = length arg_infos - - -- some_benefit is used when the RHS is small enough - -- and the call has enough (or too many) value - -- arguments (ie n_val_args >= arity). But there must - -- be *something* interesting about some argument, or the - -- result context, to make it worth inlining - calc_some_benefit :: Arity -> Bool -- The Arity is the number of args - -- expected by the unfolding - calc_some_benefit uf_arity - | not saturated = interesting_args -- Under-saturated - -- Note [Unsaturated applications] - | otherwise = interesting_args -- Saturated or over-saturated - || interesting_call - where - saturated = n_val_args >= uf_arity - over_saturated = n_val_args > uf_arity - interesting_args = any nonTriv arg_infos - -- NB: (any nonTriv arg_infos) looks at the - -- over-saturated args too which is "wrong"; - -- but if over-saturated we inline anyway. - - interesting_call - | over_saturated - = True - | otherwise - = case cont_info of - CaseCtxt -> not (lone_variable && is_exp) -- Note [Lone variables] - ValAppCtxt -> True -- Note [Cast then apply] - RuleArgCtxt -> uf_arity > 0 -- See Note [RHS of lets] - DiscArgCtxt -> uf_arity > 0 -- Note [Inlining in ArgCtxt] - RhsCtxt NonRecursive - -> uf_arity > 0 -- See Note [RHS of lets] - _other -> False -- See Note [Nested functions] - - -{- Note [RHS of lets] -~~~~~~~~~~~~~~~~~~~~~ -When the call is the argument of a function with a RULE, or the RHS of a let, -we are a little bit keener to inline (in tryUnfolding). For example - f y = (y,y,y) - g y = let x = f y in ...(case x of (a,b,c) -> ...) ... -We'd inline 'f' if the call was in a case context, and it kind-of-is, -only we can't see it. Also - x = f v -could be expensive whereas - x = case v of (a,b) -> a -is patently cheap and may allow more eta expansion. - -So, in `interesting_call` in `tryUnfolding`, we treat the RHS of a -/non-recursive/ let as not-totally-boring. A /recursive/ let isn't -going be inlined so there is much less point. Hence the (only reason -for the) RecFlag in RhsCtxt - -Note [Unsaturated applications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a call is not saturated, we *still* inline if one of the -arguments has interesting structure. That's sometimes very important. -A good example is the Ord instance for Bool in Base: - - Rec { - $fOrdBool =GHC.Classes.D:Ord - @ Bool - ... - $cmin_ajX - - $cmin_ajX [Occ=LoopBreaker] :: Bool -> Bool -> Bool - $cmin_ajX = GHC.Classes.$dmmin @ Bool $fOrdBool - } - -But the defn of GHC.Classes.$dmmin is: - - $dmmin :: forall a. GHC.Classes.Ord a => a -> a -> a - {- Arity: 3, HasNoCafRefs, Strictness: SLL, - Unfolding: (\ @ a $dOrd :: GHC.Classes.Ord a x :: a y :: a -> - case @ a GHC.Classes.<= @ a $dOrd x y of wild { - GHC.Types.False -> y GHC.Types.True -> x }) -} - -We *really* want to inline $dmmin, even though it has arity 3, in -order to unravel the recursion. - - -Note [Things to watch] -~~~~~~~~~~~~~~~~~~~~~~ -* { y = I# 3; x = y `cast` co; ...case (x `cast` co) of ... } - Assume x is exported, so not inlined unconditionally. - Then we want x to inline unconditionally; no reason for it - not to, and doing so avoids an indirection. - -* { x = I# 3; ....f x.... } - Make sure that x does not inline unconditionally! - Lest we get extra allocation. - -Note [Nested functions] -~~~~~~~~~~~~~~~~~~~~~~~ -At one time we treated a call of a non-top-level function as -"interesting" (regardless of how boring the context) in the hope -that inlining it would eliminate the binding, and its allocation. -Specifically, in the default case of interesting_call we had - _other -> not is_top && uf_arity > 0 - -But actually postInlineUnconditionally does some of this and overall -it makes virtually no difference to nofib. So I simplified away this -special case - -Note [Cast then apply] -~~~~~~~~~~~~~~~~~~~~~~ -Consider - myIndex = __inline_me ( (/\a. ) |> co ) - co :: (forall a. a -> a) ~ (forall a. T a) - ... /\a.\x. case ((myIndex a) |> sym co) x of { ... } ... - -We need to inline myIndex to unravel this; but the actual call (myIndex a) has -no value arguments. The ValAppCtxt gives it enough incentive to inline. - -Note [Inlining in ArgCtxt] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -The condition (arity > 0) here is very important, because otherwise -we end up inlining top-level stuff into useless places; eg - x = I# 3# - f = \y. g x -This can make a very big difference: it adds 16% to nofib 'integer' allocs, -and 20% to 'power'. - -At one stage I replaced this condition by 'True' (leading to the above -slow-down). The motivation was test eyeball/inline1.hs; but that seems -to work ok now. - -NOTE: arguably, we should inline in ArgCtxt only if the result of the -call is at least CONLIKE. At least for the cases where we use ArgCtxt -for the RHS of a 'let', we only profit from the inlining if we get a -CONLIKE thing (modulo lets). - -Note [Lone variables] See also Note [Interaction of exprIsWorkFree and lone variables] -~~~~~~~~~~~~~~~~~~~~~ which appears below -The "lone-variable" case is important. I spent ages messing about -with unsatisfactory variants, but this is nice. The idea is that if a -variable appears all alone - - as an arg of lazy fn, or rhs BoringCtxt - as scrutinee of a case CaseCtxt - as arg of a fn ArgCtxt -AND - it is bound to a cheap expression - -then we should not inline it (unless there is some other reason, -e.g. it is the sole occurrence). That is what is happening at -the use of 'lone_variable' in 'interesting_call'. - -Why? At least in the case-scrutinee situation, turning - let x = (a,b) in case x of y -> ... -into - let x = (a,b) in case (a,b) of y -> ... -and thence to - let x = (a,b) in let y = (a,b) in ... -is bad if the binding for x will remain. - -Another example: I discovered that strings -were getting inlined straight back into applications of 'error' -because the latter is strict. - s = "foo" - f = \x -> ...(error s)... - -Fundamentally such contexts should not encourage inlining because, provided -the RHS is "expandable" (see Note [exprIsExpandable] in GHC.Core.Utils) the -context can ``see'' the unfolding of the variable (e.g. case or a -RULE) so there's no gain. - -However, watch out: - - * Consider this: - foo = \n. [n]) {-# INLINE foo #-} - bar = foo 20 {-# INLINE bar #-} - baz = \n. case bar of { (m:_) -> m + n } - Here we really want to inline 'bar' so that we can inline 'foo' - and the whole thing unravels as it should obviously do. This is - important: in the NDP project, 'bar' generates a closure data - structure rather than a list. - - So the non-inlining of lone_variables should only apply if the - unfolding is regarded as expandable; because that is when - exprIsConApp_maybe looks through the unfolding. Hence the "&& - is_exp" in the CaseCtxt branch of interesting_call - - * Even a type application or coercion isn't a lone variable. - Consider - case $fMonadST @ RealWorld of { :DMonad a b c -> c } - We had better inline that sucker! The case won't see through it. - - For now, I'm treating treating a variable applied to types - in a *lazy* context "lone". The motivating example was - f = /\a. \x. BIG - g = /\a. \y. h (f a) - There's no advantage in inlining f here, and perhaps - a significant disadvantage. Hence some_val_args in the Stop case - -Note [Interaction of exprIsWorkFree and lone variables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The lone-variable test says "don't inline if a case expression -scrutinises a lone variable whose unfolding is cheap". It's very -important that, under these circumstances, exprIsConApp_maybe -can spot a constructor application. So, for example, we don't -consider - let x = e in (x,x) -to be cheap, and that's good because exprIsConApp_maybe doesn't -think that expression is a constructor application. - -In the 'not (lone_variable && is_wf)' test, I used to test is_value -rather than is_wf, which was utterly wrong, because the above -expression responds True to exprIsHNF, which is what sets is_value. - -This kind of thing can occur if you have - - {-# INLINE foo #-} - foo = let x = e in (x,x) - -which Roman did. - - --} - -computeDiscount :: [Int] -> Int -> [ArgSummary] -> CallCtxt - -> Int -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 - - + 10 * length actual_arg_discounts - -- Discount of 10 for each arg supplied, - -- because the result replaces the call - - + total_arg_discount + res_discount' - where - actual_arg_discounts = zipWith mk_arg_discount arg_discounts arg_infos - total_arg_discount = sum actual_arg_discounts - - mk_arg_discount _ TrivArg = 0 - mk_arg_discount _ NonTrivArg = 10 - mk_arg_discount discount ValueArg = discount - - res_discount' - | LT <- arg_discounts `compareLength` arg_infos - = res_discount -- Over-saturated - | otherwise - = case cont_info of - BoringCtxt -> 0 - CaseCtxt -> res_discount -- Presumably a constructor - ValAppCtxt -> res_discount -- Presumably a function - _ -> 40 `min` res_discount - -- ToDo: this 40 `min` res_discount doesn't seem right - -- for DiscArgCtxt it shouldn't matter because the function will - -- get the arg discount for any non-triv arg - -- for RuleArgCtxt we do want to be keener to inline; but not only - -- constructor results - -- for RhsCtxt I suppose that exposing a data con is good in general - -- And 40 seems very arbitrary - -- - -- res_discount can be very large when a function returns - -- constructors; but we only want to invoke that large discount - -- when there's a case continuation. - -- Otherwise we, rather arbitrarily, threshold it. Yuk. - -- But we want to avoid inlining large functions that return - -- constructors into contexts that are simply "interesting" ===================================== compiler/ghc.cabal.in ===================================== @@ -322,6 +322,7 @@ Library GHC.Core.Opt.SetLevels GHC.Core.Opt.Simplify GHC.Core.Opt.Simplify.Env + GHC.Core.Opt.Simplify.Inline GHC.Core.Opt.Simplify.Iteration GHC.Core.Opt.Simplify.Monad GHC.Core.Opt.Simplify.Utils View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/940aac94cfd2e4531b54a0017fe9eb4385ffafb4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/940aac94cfd2e4531b54a0017fe9eb4385ffafb4 You're receiving 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 Oct 17 22:52:28 2022 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 17 Oct 2022 18:52:28 -0400 Subject: [Git][ghc/ghc][wip/andreask/untangle-inline] Separate core inlining logic from `Unfolding` type. Message-ID: <634ddcacc3d90_8b90f5175c5873da@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/untangle-inline at Glasgow Haskell Compiler / GHC Commits: f3d3b6a9 by Andreas Klebinger at 2022-10-18T00:49:43+02:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 7 changed files: - compiler/GHC/Core/Opt/LiberateCase.hs - + compiler/GHC/Core/Opt/Simplify/Inline.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Unfold.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Core/Opt/LiberateCase.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Prelude import GHC.Core import GHC.Core.Unfold +import GHC.Core.Opt.Simplify.Inline import GHC.Builtin.Types ( unitDataConId ) import GHC.Types.Id import GHC.Types.Var.Env ===================================== compiler/GHC/Core/Opt/Simplify/Inline.hs ===================================== @@ -0,0 +1,632 @@ +{- +(c) The University of Glasgow 2006 +(c) The AQUA Project, Glasgow University, 1994-1998 + +This module contains inlining logic used by the simplifier. +-} + + +{-# LANGUAGE BangPatterns #-} + +module GHC.Core.Opt.Simplify.Inline ( + ArgSummary(..), + + -- * Cheap and cheerful inlining checks. + couldBeSmallEnoughToInline, + smallEnoughToInline, + + -- * The smart inlining decisions are made by callSiteInline + callSiteInline, CallCtxt(..), + ) where + +import GHC.Prelude + +import GHC.Driver.Flags + +import GHC.Core +import GHC.Core.Unfold +import GHC.Types.Id +import GHC.Types.Basic ( Arity, RecFlag(..) ) +import GHC.Utils.Logger +import GHC.Utils.Misc +import GHC.Utils.Outputable +import GHC.Types.Name + +import Data.List (isPrefixOf) + +{- +************************************************************************ +* * +\subsection[considerUnfolding]{Given all the info, do (not) do the unfolding} +* * +************************************************************************ + +We use 'couldBeSmallEnoughToInline' to avoid exporting inlinings that +we ``couldn't possibly use'' on the other side. Can be overridden w/ +flaggery. Just the same as smallEnoughToInline, except that it has no +actual arguments. +-} + +couldBeSmallEnoughToInline :: UnfoldingOpts -> Int -> CoreExpr -> Bool +couldBeSmallEnoughToInline opts threshold rhs + = case sizeExpr opts threshold [] body of + TooBig -> False + _ -> True + where + (_, body) = collectBinders rhs + +---------------- +smallEnoughToInline :: UnfoldingOpts -> Unfolding -> Bool +smallEnoughToInline opts (CoreUnfolding {uf_guidance = guidance}) + = case guidance of + UnfIfGoodArgs {ug_size = size} -> size <= unfoldingUseThreshold opts + UnfWhen {} -> True + UnfNever -> False +smallEnoughToInline _ _ + = False + + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +{- +************************************************************************ +* * +\subsection{callSiteInline} +* * +************************************************************************ + +This is the key function. It decides whether to inline a variable at a call site + +callSiteInline is used at call sites, so it is a bit more generous. +It's a very important function that embodies lots of heuristics. +A non-WHNF can be inlined if it doesn't occur inside a lambda, +and occurs exactly once or + occurs once in each branch of a case and is small + +If the thing is in WHNF, there's no danger of duplicating work, +so we can inline if it occurs once, or is small + +NOTE: we don't want to inline top-level functions that always diverge. +It just makes the code bigger. Tt turns out that the convenient way to prevent +them inlining is to give them a NOINLINE pragma, which we do in +StrictAnal.addStrictnessInfoToTopId +-} + +data ArgSummary = TrivArg -- Nothing interesting + | NonTrivArg -- Arg has structure + | ValueArg -- Arg is a con-app or PAP + -- ..or con-like. Note [Conlike is interesting] + +instance Outputable ArgSummary where + ppr TrivArg = text "TrivArg" + ppr NonTrivArg = text "NonTrivArg" + ppr ValueArg = text "ValueArg" + +nonTriv :: ArgSummary -> Bool +nonTriv TrivArg = False +nonTriv _ = True + +data CallCtxt + = BoringCtxt + | RhsCtxt RecFlag -- Rhs of a let-binding; see Note [RHS of lets] + | DiscArgCtxt -- Argument of a function with non-zero arg discount + | RuleArgCtxt -- We are somewhere in the argument of a function with rules + + | ValAppCtxt -- We're applied to at least one value arg + -- This arises when we have ((f x |> co) y) + -- Then the (f x) has argument 'x' but in a ValAppCtxt + + | CaseCtxt -- We're the scrutinee of a case + -- that decomposes its scrutinee + +instance Outputable CallCtxt where + ppr CaseCtxt = text "CaseCtxt" + ppr ValAppCtxt = text "ValAppCtxt" + ppr BoringCtxt = text "BoringCtxt" + ppr (RhsCtxt ir)= text "RhsCtxt" <> parens (ppr ir) + ppr DiscArgCtxt = text "DiscArgCtxt" + ppr RuleArgCtxt = text "RuleArgCtxt" + +callSiteInline :: Logger + -> UnfoldingOpts + -> Int -- Case depth + -> Id -- The Id + -> Boo