Andreas Klebinger pushed to branch wip/andreask/9.10.4-batch1 at Glasgow Haskell Compiler / GHC
Commits:
-
b4dc7b1c
by Cheng Shao at 2026-10-28T11:42:58+01:00
-
0eb7b151
by Ben Gamari at 2026-10-28T11:43:25+01:00
-
a026b215
by Ben Gamari at 2026-10-28T11:43:38+01:00
-
b30ecb58
by Ben Gamari at 2026-10-28T11:43:38+01:00
-
ce2add9b
by Ben Gamari at 2026-10-28T11:43:38+01:00
-
374ca5c4
by Ben Gamari at 2026-10-28T11:43:38+01:00
-
97a0f7a4
by Cheng Shao at 2026-10-28T11:45:58+01:00
-
ba4aac3d
by Andreas Klebinger at 2026-10-28T11:53:47+01:00
-
5a256308
by Andreas Klebinger at 2026-10-28T14:08:55+01:00
16 changed files:
- .gitlab-ci.yml
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- hadrian/src/Rules/Generate.hs
- rts/include/rts/storage/Block.h
- rts/sm/NonMoving.c
- rts/sm/NonMovingMark.c
- rts/sm/Scav.c
- testsuite/driver/cpu_features.py
- + testsuite/tests/cross/should_run/T26449.hs
- + testsuite/tests/cross/should_run/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/should_run/T3586.hs
- testsuite/tests/perf/should_run/all.T
Changes:
| 1 | +spec:
|
|
| 2 | + inputs:
|
|
| 3 | + release:
|
|
| 4 | + default: "no"
|
|
| 5 | + description: Release pipeline
|
|
| 6 | + options: [ "yes", "no" ]
|
|
| 7 | + |
|
| 8 | +---
|
|
| 9 | + |
|
| 1 | 10 | variables:
|
| 2 | 11 | GIT_SSL_NO_VERIFY: "1"
|
| 3 | 12 | |
| ... | ... | @@ -25,6 +34,8 @@ variables: |
| 25 | 34 | # Makes ci.sh isolate CABAL_DIR
|
| 26 | 35 | HERMETIC: "YES"
|
| 27 | 36 | |
| 37 | + RELEASE_JOB: $[[ inputs.release ]]
|
|
| 38 | + |
|
| 28 | 39 | # Reduce XZ compression level for regular jobs (it is bumped to 9 for releases
|
| 29 | 40 | # and nightly jobs). In my experiments I've got the following bindist size in
|
| 30 | 41 | # the given time for each compression level (with the quick flavour):
|
| ... | ... | @@ -9,6 +9,8 @@ |
| 9 | 9 | -- many /other/ arguments the function has. Inconsistent unboxing is very
|
| 10 | 10 | -- bad for performance, so I increased the limit to allow it to unbox
|
| 11 | 11 | -- consistently.
|
| 12 | +-- AK: Seems we no longer unbox OccEnv now anyway so it might be redundant.
|
|
| 13 | + |
|
| 12 | 14 | |
| 13 | 15 | {-
|
| 14 | 16 | (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
|
| ... | ... | @@ -967,6 +969,12 @@ occAnalBind |
| 967 | 969 | -> ([CoreBind] -> r -> r) -- How to combine the scope with new binds
|
| 968 | 970 | -> WithUsageDetails r -- Of the whole let(rec)
|
| 969 | 971 | |
| 972 | +-- AK: While not allocating any less inlining occAnalBind turns calls to the
|
|
| 973 | +-- passed functions into known calls with all the benefits that brings.
|
|
| 974 | +-- On a version of T26425 with 6k alternatives this improved compile
|
|
| 975 | +-- by 10-20% with -O.
|
|
| 976 | +{-# INLINE occAnalBind #-}
|
|
| 977 | + |
|
| 970 | 978 | occAnalBind env lvl ire (Rec pairs) thing_inside combine
|
| 971 | 979 | = addInScopeList env (map fst pairs) $ \env ->
|
| 972 | 980 | let WUD body_uds body' = thing_inside env
|
| ... | ... | @@ -984,7 +992,7 @@ occAnalBind !env lvl ire (NonRec bndr rhs) thing_inside combine |
| 984 | 992 | = -- Analyse the RHS and /then/ the body
|
| 985 | 993 | let -- Analyse the rhs first, generating rhs_uds
|
| 986 | 994 | !(rhs_uds_s, bndr', rhs') = occAnalNonRecRhs env ire mb_join bndr rhs
|
| 987 | - rhs_uds = foldr1 orUDs rhs_uds_s -- NB: orUDs. See (W4) of
|
|
| 995 | + rhs_uds = foldl1' orUDs rhs_uds_s -- NB: orUDs. See (W4) of
|
|
| 988 | 996 | -- Note [Occurrence analysis for join points]
|
| 989 | 997 | |
| 990 | 998 | -- Now analyse the body, adding the join point
|
| ... | ... | @@ -1049,6 +1057,7 @@ occAnalNonRecRhs !env imp_rule_edges mb_join bndr rhs |
| 1049 | 1057 | -- Match join arity O from mb_join_arity with manifest join arity M as
|
| 1050 | 1058 | -- returned by of occAnalLamTail. It's totally OK for them to mismatch;
|
| 1051 | 1059 | -- hence adjust the UDs from the RHS
|
| 1060 | + |
|
| 1052 | 1061 | WUD adj_rhs_uds final_rhs = adjustNonRecRhs mb_join $
|
| 1053 | 1062 | occAnalLamTail rhs_env rhs
|
| 1054 | 1063 | final_bndr_with_rules
|
| ... | ... | @@ -2053,6 +2062,18 @@ So The Plan is this: |
| 2053 | 2062 | was a loop breaker last time round
|
| 2054 | 2063 | |
| 2055 | 2064 | Hence the is_lb field of NodeScore
|
| 2065 | + |
|
| 2066 | +Note [Strictness in the occurrence analyser]
|
|
| 2067 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 2068 | +By carefully making the occurrence analyser strict in some places, we can
|
|
| 2069 | +dramatically reduce its memory residency. Among other things we:
|
|
| 2070 | +* Evaluate the result of `tagLamBinder` and friends, so that the binder (or its
|
|
| 2071 | + OccInfo) does not retain the entire `UsageDetails`. Also use `strictMap` in `tagLamBinders`.
|
|
| 2072 | +* In `combineUsageDetailsWith`, the fields of the data constructor are strict, and we use
|
|
| 2073 | + `strictPlusVarEnv` on the maps that are bound to be needed later on to avoid thunks being
|
|
| 2074 | + stored in the values.
|
|
| 2075 | + |
|
| 2076 | +These measures reduced residency for test T26425 by a factor of at least 5x.
|
|
| 2056 | 2077 | -}
|
| 2057 | 2078 | |
| 2058 | 2079 | {- *********************************************************************
|
| ... | ... | @@ -2187,7 +2208,9 @@ occ_anal_lam_tail env expr@(Lam {}) |
| 2187 | 2208 | go env rev_bndrs body
|
| 2188 | 2209 | = addInScope env rev_bndrs $ \env ->
|
| 2189 | 2210 | let !(WUD usage body') = occ_anal_lam_tail env body
|
| 2190 | - wrap_lam body bndr = Lam (tagLamBinder usage bndr) body
|
|
| 2211 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 2212 | + wrap_lam !body !bndr = let !bndr' = tagLamBinder usage bndr
|
|
| 2213 | + in Lam bndr' body
|
|
| 2191 | 2214 | in WUD (usage `addLamCoVarOccs` rev_bndrs)
|
| 2192 | 2215 | (foldl' wrap_lam body' rev_bndrs)
|
| 2193 | 2216 | |
| ... | ... | @@ -2540,7 +2563,8 @@ occAnal env (Case scrut bndr ty alts) |
| 2540 | 2563 | let alt_env = addBndrSwap scrut' bndr $
|
| 2541 | 2564 | setTailCtxt env -- Kill off OccRhs
|
| 2542 | 2565 | WUD alts_usage alts' = do_alts alt_env alts
|
| 2543 | - tagged_bndr = tagLamBinder alts_usage bndr
|
|
| 2566 | + !tagged_bndr = tagLamBinder alts_usage bndr
|
|
| 2567 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 2544 | 2568 | in WUD alts_usage (tagged_bndr, alts')
|
| 2545 | 2569 | |
| 2546 | 2570 | total_usage = markAllNonTail scrut_usage `andUDs` alts_usage
|
| ... | ... | @@ -2558,11 +2582,13 @@ occAnal env (Case scrut bndr ty alts) |
| 2558 | 2582 | do_alt !env (Alt con bndrs rhs)
|
| 2559 | 2583 | = addInScopeList env bndrs $ \ env ->
|
| 2560 | 2584 | let WUD rhs_usage rhs' = occAnal env rhs
|
| 2561 | - tagged_bndrs = tagLamBinders rhs_usage bndrs
|
|
| 2585 | + !tagged_bndrs = tagLamBinders rhs_usage bndrs
|
|
| 2586 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 2562 | 2587 | in -- See Note [Binders in case alternatives]
|
| 2563 | 2588 | WUD rhs_usage (Alt con tagged_bndrs rhs')
|
| 2564 | 2589 | |
| 2565 | 2590 | occAnal env (Let bind body)
|
| 2591 | + -- TODO: Would be nice to use a strict version of mkLets here
|
|
| 2566 | 2592 | = occAnalBind env NotTopLevel noImpRuleEdges bind
|
| 2567 | 2593 | (\env -> occAnal env body) mkLets
|
| 2568 | 2594 | |
| ... | ... | @@ -2622,10 +2648,12 @@ occAnalApp !env (Var fun, args, ticks) |
| 2622 | 2648 | | fun `hasKey` runRWKey
|
| 2623 | 2649 | , [t1, t2, arg] <- args
|
| 2624 | 2650 | , WUD usage arg' <- adjustNonRecRhs (JoinPoint 1) $ occAnalLamTail env arg
|
| 2625 | - = WUD usage (mkTicks ticks $ mkApps (Var fun) [t1, t2, arg'])
|
|
| 2651 | + = let app_out = mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']
|
|
| 2652 | + in WUD usage app_out
|
|
| 2626 | 2653 | |
| 2627 | 2654 | occAnalApp env (Var fun_id, args, ticks)
|
| 2628 | - = WUD all_uds (mkTicks ticks app')
|
|
| 2655 | + = let app_out = mkTicks ticks app'
|
|
| 2656 | + in WUD all_uds app_out
|
|
| 2629 | 2657 | where
|
| 2630 | 2658 | -- Lots of banged bindings: this is a very heavily bit of code,
|
| 2631 | 2659 | -- so it pays not to make lots of thunks here, all of which
|
| ... | ... | @@ -2670,8 +2698,9 @@ occAnalApp env (Var fun_id, args, ticks) |
| 2670 | 2698 | -- See Note [Sources of one-shot information], bullet point A']
|
| 2671 | 2699 | |
| 2672 | 2700 | occAnalApp env (fun, args, ticks)
|
| 2673 | - = WUD (markAllNonTail (fun_uds `andUDs` args_uds))
|
|
| 2674 | - (mkTicks ticks app')
|
|
| 2701 | + = let app_out = mkTicks ticks app'
|
|
| 2702 | + in WUD (markAllNonTail (fun_uds `andUDs` args_uds)) app_out
|
|
| 2703 | + |
|
| 2675 | 2704 | where
|
| 2676 | 2705 | !(WUD args_uds app') = occAnalArgs env fun' args []
|
| 2677 | 2706 | !(WUD fun_uds fun') = occAnal (addAppCtxt env args) fun
|
| ... | ... | @@ -3613,8 +3642,8 @@ data WithTailUsageDetails a = WTUD !TailUsageDetails !a |
| 3613 | 3642 | -------------------
|
| 3614 | 3643 | -- UsageDetails API
|
| 3615 | 3644 | |
| 3616 | -andUDs, orUDs
|
|
| 3617 | - :: UsageDetails -> UsageDetails -> UsageDetails
|
|
| 3645 | +andUDs:: UsageDetails -> UsageDetails -> UsageDetails
|
|
| 3646 | +orUDs :: UsageDetails -> UsageDetails -> UsageDetails
|
|
| 3618 | 3647 | andUDs = combineUsageDetailsWith andLocalOcc
|
| 3619 | 3648 | orUDs = combineUsageDetailsWith orLocalOcc
|
| 3620 | 3649 | |
| ... | ... | @@ -3729,10 +3758,13 @@ combineUsageDetailsWith plus_occ_info |
| 3729 | 3758 | | isEmptyVarEnv env1 = uds2
|
| 3730 | 3759 | | isEmptyVarEnv env2 = uds1
|
| 3731 | 3760 | | otherwise
|
| 3732 | - = UD { ud_env = plusVarEnv_C plus_occ_info env1 env2
|
|
| 3733 | - , ud_z_many = plusVarEnv z_many1 z_many2
|
|
| 3761 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 3762 | + -- Using strictPlusVarEnv here speeds up the test T26425 by about 10% by avoiding
|
|
| 3763 | + -- intermediate thunks.
|
|
| 3764 | + = UD { ud_env = strictPlusVarEnv_C plus_occ_info env1 env2
|
|
| 3765 | + , ud_z_many = strictPlusVarEnv z_many1 z_many2
|
|
| 3734 | 3766 | , ud_z_in_lam = plusVarEnv z_in_lam1 z_in_lam2
|
| 3735 | - , ud_z_tail = plusVarEnv z_tail1 z_tail2 }
|
|
| 3767 | + , ud_z_tail = strictPlusVarEnv z_tail1 z_tail2 }
|
|
| 3736 | 3768 | |
| 3737 | 3769 | lookupLetOccInfo :: UsageDetails -> Id -> OccInfo
|
| 3738 | 3770 | -- Don't use locally-generated occ_info for exported (visible-elsewhere)
|
| ... | ... | @@ -3810,7 +3842,8 @@ tagLamBinders :: UsageDetails -- Of scope |
| 3810 | 3842 | -> [Id] -- Binders
|
| 3811 | 3843 | -> [IdWithOccInfo] -- Tagged binders
|
| 3812 | 3844 | tagLamBinders usage binders
|
| 3813 | - = map (tagLamBinder usage) binders
|
|
| 3845 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 3846 | + = strictMap (tagLamBinder usage) binders
|
|
| 3814 | 3847 | |
| 3815 | 3848 | tagLamBinder :: UsageDetails -- Of scope
|
| 3816 | 3849 | -> Id -- Binder
|
| ... | ... | @@ -3819,6 +3852,7 @@ tagLamBinder :: UsageDetails -- Of scope |
| 3819 | 3852 | -- No-op on TyVars
|
| 3820 | 3853 | -- A lambda binder never has an unfolding, so no need to look for that
|
| 3821 | 3854 | tagLamBinder usage bndr
|
| 3855 | + -- See Note [Strictness in the occurrence analyser]
|
|
| 3822 | 3856 | = setBinderOcc (markNonTail occ) bndr
|
| 3823 | 3857 | -- markNonTail: don't try to make an argument into a join point
|
| 3824 | 3858 | where
|
| ... | ... | @@ -51,7 +51,9 @@ module GHC.Types.Unique.FM ( |
| 51 | 51 | delListFromUFM,
|
| 52 | 52 | delListFromUFM_Directly,
|
| 53 | 53 | plusUFM,
|
| 54 | + strictPlusUFM,
|
|
| 54 | 55 | plusUFM_C,
|
| 56 | + strictPlusUFM_C,
|
|
| 55 | 57 | plusUFM_CD,
|
| 56 | 58 | plusUFM_CD2,
|
| 57 | 59 | mergeUFM,
|
| ... | ... | @@ -249,16 +251,24 @@ delListFromUFM_Directly = foldl' delFromUFM_Directly |
| 249 | 251 | delFromUFM_Directly :: UniqFM key elt -> Unique -> UniqFM key elt
|
| 250 | 252 | delFromUFM_Directly (UFM m) u = UFM (M.delete (getKey u) m)
|
| 251 | 253 | |
| 252 | --- Bindings in right argument shadow those in the left
|
|
| 254 | +-- | Bindings in right argument shadow those in the left.
|
|
| 255 | +--
|
|
| 256 | +-- Unlike containers this union is right-biased for historic reasons.
|
|
| 253 | 257 | plusUFM :: UniqFM key elt -> UniqFM key elt -> UniqFM key elt
|
| 254 | --- M.union is left-biased, plusUFM should be right-biased.
|
|
| 255 | 258 | plusUFM (UFM x) (UFM y) = UFM (M.union y x)
|
| 256 | 259 | -- Note (M.union y x), with arguments flipped
|
| 257 | 260 | -- M.union is left-biased, plusUFM should be right-biased.
|
| 258 | 261 | |
| 262 | +-- | Right biased
|
|
| 263 | +strictPlusUFM :: UniqFM key elt -> UniqFM key elt -> UniqFM key elt
|
|
| 264 | +strictPlusUFM (UFM x) (UFM y) = UFM (MS.union y x)
|
|
| 265 | + |
|
| 259 | 266 | plusUFM_C :: (elt -> elt -> elt) -> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
|
| 260 | 267 | plusUFM_C f (UFM x) (UFM y) = UFM (M.unionWith f x y)
|
| 261 | 268 | |
| 269 | +strictPlusUFM_C :: (elt -> elt -> elt) -> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
|
|
| 270 | +strictPlusUFM_C f (UFM x) (UFM y) = UFM (MS.unionWith f x y)
|
|
| 271 | + |
|
| 262 | 272 | -- | `plusUFM_CD f m1 d1 m2 d2` merges the maps using `f` as the
|
| 263 | 273 | -- combinding function and `d1` resp. `d2` as the default value if
|
| 264 | 274 | -- there is no entry in `m1` reps. `m2`. The domain is the union of
|
| ... | ... | @@ -12,7 +12,8 @@ module GHC.Types.Var.Env ( |
| 12 | 12 | elemVarEnv, disjointVarEnv, anyVarEnv,
|
| 13 | 13 | extendVarEnv, extendVarEnv_C, extendVarEnv_Acc,
|
| 14 | 14 | extendVarEnvList,
|
| 15 | - plusVarEnv, plusVarEnv_C, plusVarEnv_CD, plusMaybeVarEnv_C,
|
|
| 15 | + strictPlusVarEnv, plusVarEnv, plusVarEnv_C, strictPlusVarEnv_C,
|
|
| 16 | + plusVarEnv_CD, plusMaybeVarEnv_C,
|
|
| 16 | 17 | plusVarEnvList, alterVarEnv,
|
| 17 | 18 | delVarEnvList, delVarEnv,
|
| 18 | 19 | minusVarEnv,
|
| ... | ... | @@ -510,6 +511,7 @@ extendVarEnv :: VarEnv a -> Var -> a -> VarEnv a |
| 510 | 511 | extendVarEnv_C :: (a->a->a) -> VarEnv a -> Var -> a -> VarEnv a
|
| 511 | 512 | extendVarEnv_Acc :: (a->b->b) -> (a->b) -> VarEnv b -> Var -> a -> VarEnv b
|
| 512 | 513 | plusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
|
| 514 | +strictPlusVarEnv :: VarEnv a -> VarEnv a -> VarEnv a
|
|
| 513 | 515 | plusVarEnvList :: [VarEnv a] -> VarEnv a
|
| 514 | 516 | extendVarEnvList :: VarEnv a -> [(Var, a)] -> VarEnv a
|
| 515 | 517 | varEnvDomain :: VarEnv elt -> UnVarSet
|
| ... | ... | @@ -521,6 +523,7 @@ delVarEnvList :: VarEnv a -> [Var] -> VarEnv a |
| 521 | 523 | delVarEnv :: VarEnv a -> Var -> VarEnv a
|
| 522 | 524 | minusVarEnv :: VarEnv a -> VarEnv b -> VarEnv a
|
| 523 | 525 | plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a
|
| 526 | +strictPlusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a
|
|
| 524 | 527 | plusVarEnv_CD :: (a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a
|
| 525 | 528 | plusMaybeVarEnv_C :: (a -> a -> Maybe a) -> VarEnv a -> VarEnv a -> VarEnv a
|
| 526 | 529 | mapVarEnv :: (a -> b) -> VarEnv a -> VarEnv b
|
| ... | ... | @@ -547,12 +550,14 @@ extendVarEnv_C = addToUFM_C |
| 547 | 550 | extendVarEnv_Acc = addToUFM_Acc
|
| 548 | 551 | extendVarEnvList = addListToUFM
|
| 549 | 552 | plusVarEnv_C = plusUFM_C
|
| 553 | +strictPlusVarEnv_C = strictPlusUFM_C
|
|
| 550 | 554 | plusVarEnv_CD = plusUFM_CD
|
| 551 | 555 | plusMaybeVarEnv_C = plusMaybeUFM_C
|
| 552 | 556 | delVarEnvList = delListFromUFM
|
| 553 | 557 | delVarEnv = delFromUFM
|
| 554 | 558 | minusVarEnv = minusUFM
|
| 555 | 559 | plusVarEnv = plusUFM
|
| 560 | +strictPlusVarEnv = strictPlusUFM
|
|
| 556 | 561 | plusVarEnvList = plusUFMList
|
| 557 | 562 | -- lookupVarEnv is very hot (in part due to being called by substTyVar),
|
| 558 | 563 | -- if it's not inlined than the mere allocation of the Just constructor causes
|
| ... | ... | @@ -570,8 +570,12 @@ generateVersionHs = do |
| 570 | 570 | generatePlatformHostHs :: Expr String
|
| 571 | 571 | generatePlatformHostHs = do
|
| 572 | 572 | trackGenerateHs
|
| 573 | - cHostPlatformArch <- queryHost (archOS_arch . tgtArchOs)
|
|
| 574 | - cHostPlatformOS <- queryHost (archOS_OS . tgtArchOs)
|
|
| 573 | + stage <- getStage
|
|
| 574 | + let chooseHostQuery = case stage of
|
|
| 575 | + Stage0 {} -> queryHost
|
|
| 576 | + _ -> queryTarget
|
|
| 577 | + cHostPlatformArch <- chooseHostQuery (archOS_arch . tgtArchOs)
|
|
| 578 | + cHostPlatformOS <- chooseHostQuery (archOS_OS . tgtArchOs)
|
|
| 575 | 579 | return $ unlines
|
| 576 | 580 | [ "module GHC.Platform.Host where"
|
| 577 | 581 | , ""
|
| ... | ... | @@ -300,6 +300,28 @@ dbl_link_replace(bdescr *new_, bdescr *old, bdescr **list) |
| 300 | 300 | }
|
| 301 | 301 | }
|
| 302 | 302 | |
| 303 | +INLINE_HEADER void
|
|
| 304 | +block_set_flag(bdescr *bd, uint16_t flag)
|
|
| 305 | +{
|
|
| 306 | + // TODO: This ordering is stronger than necessary for many users (e.g.
|
|
| 307 | + // setting flags).
|
|
| 308 | + __atomic_or_fetch(&bd->flags, flag, __ATOMIC_SEQ_CST);
|
|
| 309 | +}
|
|
| 310 | + |
|
| 311 | +INLINE_HEADER void
|
|
| 312 | +block_clear_flag(bdescr *bd, uint16_t flag)
|
|
| 313 | +{
|
|
| 314 | + // TODO: This ordering is stronger than necessary for many users (e.g.
|
|
| 315 | + // setting flags).
|
|
| 316 | + __atomic_and_fetch(&bd->flags, ~flag, __ATOMIC_SEQ_CST);
|
|
| 317 | +}
|
|
| 318 | + |
|
| 319 | +INLINE_HEADER uint16_t
|
|
| 320 | +block_get_flags(bdescr *bd)
|
|
| 321 | +{
|
|
| 322 | + return RELAXED_LOAD(&bd->flags);
|
|
| 323 | +}
|
|
| 324 | + |
|
| 303 | 325 | /* Initialisation ---------------------------------------------------------- */
|
| 304 | 326 | |
| 305 | 327 | extern void initBlockAllocator(void);
|
| ... | ... | @@ -550,7 +550,7 @@ static void nonmovingBumpEpoch(void) { |
| 550 | 550 | * arbitrary allocator sizes, we need to do some precomputation and make
|
| 551 | 551 | * use of the integer division by constants optimisation.
|
| 552 | 552 | *
|
| 553 | - * We currenlty try to balance these considerations by adopting the following scheme.
|
|
| 553 | + * We currently try to balance these considerations by adopting the following scheme.
|
|
| 554 | 554 | * We have nonmoving_alloca_dense_cnt "dense" allocators starting with size
|
| 555 | 555 | * NONMOVING_ALLOCA0, and incrementing by NONMOVING_ALLOCA_DENSE_INCREMENT.
|
| 556 | 556 | * These service the vast majority of allocations.
|
| ... | ... | @@ -606,7 +606,7 @@ static |
| 606 | 606 | bool check_in_nonmoving_heap(StgClosure *p) {
|
| 607 | 607 | if (HEAP_ALLOCED_GC(p)) {
|
| 608 | 608 | // This works for both large and small objects:
|
| 609 | - return Bdescr((P_)p)->flags & BF_NONMOVING;
|
|
| 609 | + return block_get_flags(Bdescr((P_)p)) & BF_NONMOVING;
|
|
| 610 | 610 | } else {
|
| 611 | 611 | return true; // a static object
|
| 612 | 612 | }
|
| ... | ... | @@ -619,7 +619,7 @@ inline void updateRemembSetPushThunk(Capability *cap, StgThunk *thunk) |
| 619 | 619 | {
|
| 620 | 620 | const StgInfoTable *info;
|
| 621 | 621 | do {
|
| 622 | - info = *(StgInfoTable* volatile*) &thunk->header.info;
|
|
| 622 | + info = (StgInfoTable*) RELAXED_LOAD(&thunk->header.info);
|
|
| 623 | 623 | } while (info == &stg_WHITEHOLE_info);
|
| 624 | 624 | |
| 625 | 625 | const StgThunkInfoTable *thunk_info = THUNK_INFO_PTR_TO_STRUCT(info);
|
| ... | ... | @@ -722,13 +722,14 @@ STATIC_INLINE bool needs_upd_rem_set_mark(StgClosure *p) |
| 722 | 722 | {
|
| 723 | 723 | // TODO: Deduplicate with mark_closure
|
| 724 | 724 | bdescr *bd = Bdescr((StgPtr) p);
|
| 725 | + uint16_t flags = block_get_flags(bd);
|
|
| 725 | 726 | if (bd->gen != oldest_gen) {
|
| 726 | 727 | return false;
|
| 727 | - } else if (bd->flags & BF_LARGE) {
|
|
| 728 | - if (! (bd->flags & BF_NONMOVING_SWEEPING)) {
|
|
| 728 | + } else if (flags & BF_LARGE) {
|
|
| 729 | + if (! (flags & BF_NONMOVING_SWEEPING)) {
|
|
| 729 | 730 | return false;
|
| 730 | 731 | } else {
|
| 731 | - return ! (bd->flags & BF_MARKED);
|
|
| 732 | + return ! (flags & BF_MARKED);
|
|
| 732 | 733 | }
|
| 733 | 734 | } else {
|
| 734 | 735 | struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
|
| ... | ... | @@ -740,8 +741,8 @@ STATIC_INLINE bool needs_upd_rem_set_mark(StgClosure *p) |
| 740 | 741 | static void finish_upd_rem_set_mark_large(bdescr* bd) {
|
| 741 | 742 | // Someone else may have already marked it.
|
| 742 | 743 | ACQUIRE_LOCK(&nonmoving_large_objects_mutex);
|
| 743 | - if (! (bd->flags & BF_MARKED)) {
|
|
| 744 | - bd->flags |= BF_MARKED;
|
|
| 744 | + if (! (block_get_flags(bd) & BF_MARKED)) {
|
|
| 745 | + block_set_flag(bd, BF_MARKED);
|
|
| 745 | 746 | dbl_link_remove(bd, &nonmoving_large_objects);
|
| 746 | 747 | dbl_link_onto(bd, &nonmoving_marked_large_objects);
|
| 747 | 748 | n_nonmoving_large_blocks -= bd->blocks;
|
| ... | ... | @@ -754,7 +755,7 @@ static void finish_upd_rem_set_mark_large(bdescr* bd) { |
| 754 | 755 | STATIC_INLINE void finish_upd_rem_set_mark(StgClosure *p)
|
| 755 | 756 | {
|
| 756 | 757 | bdescr *bd = Bdescr((StgPtr) p);
|
| 757 | - if (bd->flags & BF_LARGE) {
|
|
| 758 | + if (block_get_flags(bd) & BF_LARGE) {
|
|
| 758 | 759 | // This function is extracted so that this function can be inline
|
| 759 | 760 | finish_upd_rem_set_mark_large(bd);
|
| 760 | 761 | } else {
|
| ... | ... | @@ -1342,7 +1343,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) |
| 1342 | 1343 | goto done;
|
| 1343 | 1344 | |
| 1344 | 1345 | case WHITEHOLE:
|
| 1345 | - while (*(StgInfoTable* volatile*) &p->header.info == &stg_WHITEHOLE_info)
|
|
| 1346 | + while (RELAXED_LOAD(&p->header.info) == &stg_WHITEHOLE_info)
|
|
| 1346 | 1347 | #if defined(PARALLEL_GC)
|
| 1347 | 1348 | busy_wait_nop()
|
| 1348 | 1349 | #endif
|
| ... | ... | @@ -1376,35 +1377,36 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) |
| 1376 | 1377 | |
| 1377 | 1378 | // N.B. only the first block of a compact region is guaranteed to carry
|
| 1378 | 1379 | // BF_NONMOVING; consequently we must separately check for BF_COMPACT.
|
| 1379 | - if (bd->flags & (BF_COMPACT | BF_NONMOVING)) {
|
|
| 1380 | + const uint16_t flags = block_get_flags(bd);
|
|
| 1381 | + if (flags & (BF_COMPACT | BF_NONMOVING)) {
|
|
| 1380 | 1382 | |
| 1381 | - if (bd->flags & BF_COMPACT) {
|
|
| 1383 | + if (flags & BF_COMPACT) {
|
|
| 1382 | 1384 | StgCompactNFData *str = objectGetCompact((StgClosure*)p);
|
| 1383 | 1385 | bd = Bdescr((P_)str);
|
| 1384 | 1386 | |
| 1385 | - if (! (bd->flags & BF_NONMOVING_SWEEPING)) {
|
|
| 1387 | + if (! (flags & BF_NONMOVING_SWEEPING)) {
|
|
| 1386 | 1388 | // Not in the snapshot
|
| 1387 | 1389 | return;
|
| 1388 | 1390 | }
|
| 1389 | 1391 | |
| 1390 | - if (! (bd->flags & BF_MARKED)) {
|
|
| 1392 | + if (! (flags & BF_MARKED)) {
|
|
| 1391 | 1393 | dbl_link_remove(bd, &nonmoving_compact_objects);
|
| 1392 | 1394 | dbl_link_onto(bd, &nonmoving_marked_compact_objects);
|
| 1393 | 1395 | StgWord blocks = str->totalW / BLOCK_SIZE_W;
|
| 1394 | 1396 | n_nonmoving_compact_blocks -= blocks;
|
| 1395 | 1397 | n_nonmoving_marked_compact_blocks += blocks;
|
| 1396 | - bd->flags |= BF_MARKED;
|
|
| 1398 | + block_set_flag(bd, BF_MARKED);
|
|
| 1397 | 1399 | }
|
| 1398 | 1400 | |
| 1399 | 1401 | // N.B. the object being marked is in a compact region so by
|
| 1400 | 1402 | // definition there is no need to do any tracing here.
|
| 1401 | 1403 | goto done;
|
| 1402 | - } else if (bd->flags & BF_LARGE) {
|
|
| 1403 | - if (! (bd->flags & BF_NONMOVING_SWEEPING)) {
|
|
| 1404 | + } else if (flags & BF_LARGE) {
|
|
| 1405 | + if (! (flags & BF_NONMOVING_SWEEPING)) {
|
|
| 1404 | 1406 | // Not in the snapshot
|
| 1405 | 1407 | goto done;
|
| 1406 | 1408 | }
|
| 1407 | - if (bd->flags & BF_MARKED) {
|
|
| 1409 | + if (flags & BF_MARKED) {
|
|
| 1408 | 1410 | goto done;
|
| 1409 | 1411 | }
|
| 1410 | 1412 | } else {
|
| ... | ... | @@ -1712,7 +1714,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) |
| 1712 | 1714 | break;
|
| 1713 | 1715 | |
| 1714 | 1716 | case WHITEHOLE:
|
| 1715 | - while (*(StgInfoTable* volatile*) &p->header.info == &stg_WHITEHOLE_info);
|
|
| 1717 | + while ((StgInfoTable *) RELAXED_LOAD(&p->header.info) == &stg_WHITEHOLE_info);
|
|
| 1716 | 1718 | goto try_again;
|
| 1717 | 1719 | |
| 1718 | 1720 | case COMPACT_NFDATA:
|
| ... | ... | @@ -1736,24 +1738,25 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) |
| 1736 | 1738 | * the object's pointers since in the case of marking stacks there may be a
|
| 1737 | 1739 | * mutator waiting for us to finish so it can start execution.
|
| 1738 | 1740 | */
|
| 1739 | - if (bd->flags & BF_LARGE) {
|
|
| 1741 | + uint16_t bd_flags = block_get_flags(bd);
|
|
| 1742 | + if (bd_flags & BF_LARGE) {
|
|
| 1740 | 1743 | /* Marking a large object isn't idempotent since we move it to
|
| 1741 | 1744 | * nonmoving_marked_large_objects; to ensure that we don't repeatedly
|
| 1742 | 1745 | * mark a large object, we only set BF_MARKED on large objects in the
|
| 1743 | 1746 | * nonmoving heap while holding nonmoving_large_objects_mutex
|
| 1744 | 1747 | */
|
| 1745 | 1748 | ACQUIRE_LOCK(&nonmoving_large_objects_mutex);
|
| 1746 | - if (! (bd->flags & BF_MARKED)) {
|
|
| 1749 | + if (! (bd_flags & BF_MARKED)) {
|
|
| 1747 | 1750 | // Remove the object from nonmoving_large_objects and link it to
|
| 1748 | 1751 | // nonmoving_marked_large_objects
|
| 1749 | 1752 | dbl_link_remove(bd, &nonmoving_large_objects);
|
| 1750 | 1753 | dbl_link_onto(bd, &nonmoving_marked_large_objects);
|
| 1751 | 1754 | n_nonmoving_large_blocks -= bd->blocks;
|
| 1752 | 1755 | n_nonmoving_marked_large_blocks += bd->blocks;
|
| 1753 | - bd->flags |= BF_MARKED;
|
|
| 1756 | + block_set_flag(bd, BF_MARKED);
|
|
| 1754 | 1757 | }
|
| 1755 | 1758 | RELEASE_LOCK(&nonmoving_large_objects_mutex);
|
| 1756 | - } else if (bd->flags & BF_NONMOVING) {
|
|
| 1759 | + } else if (bd_flags & BF_NONMOVING) {
|
|
| 1757 | 1760 | // TODO: Kill repetition
|
| 1758 | 1761 | struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
|
| 1759 | 1762 | nonmoving_block_idx block_idx = nonmovingGetBlockIdx((StgPtr) p);
|
| ... | ... | @@ -1768,7 +1771,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) |
| 1768 | 1771 | }
|
| 1769 | 1772 | |
| 1770 | 1773 | done:
|
| 1771 | - if (origin != NULL && (!HEAP_ALLOCED(p) || bd->flags & BF_NONMOVING)) {
|
|
| 1774 | + if (origin != NULL && (!HEAP_ALLOCED(p) || block_get_flags(bd) & BF_NONMOVING)) {
|
|
| 1772 | 1775 | if (UNTAG_CLOSURE((StgClosure*)p0) != p && *origin == p0) {
|
| 1773 | 1776 | if (cas((StgVolatilePtr)origin, (StgWord)p0, (StgWord)TAG_CLOSURE(tag, p)) == (StgWord)p0) {
|
| 1774 | 1777 | // debugBelch("Thunk optimization successful\n");
|
| ... | ... | @@ -1865,19 +1868,20 @@ bool nonmovingIsAlive (StgClosure *p) |
| 1865 | 1868 | }
|
| 1866 | 1869 | |
| 1867 | 1870 | bdescr *bd = Bdescr((P_)p);
|
| 1871 | + uint16_t bd_flags = block_get_flags(bd);
|
|
| 1868 | 1872 | |
| 1869 | 1873 | // All non-static objects in the non-moving heap should be marked as
|
| 1870 | 1874 | // BF_NONMOVING
|
| 1871 | - ASSERT(bd->flags & BF_NONMOVING);
|
|
| 1875 | + ASSERT(bd_flags & BF_NONMOVING);
|
|
| 1872 | 1876 | |
| 1873 | - if (bd->flags & (BF_COMPACT | BF_LARGE)) {
|
|
| 1874 | - if (bd->flags & BF_COMPACT) {
|
|
| 1877 | + if (bd_flags & (BF_COMPACT | BF_LARGE)) {
|
|
| 1878 | + if (bd_flags & BF_COMPACT) {
|
|
| 1875 | 1879 | StgCompactNFData *str = objectGetCompact((StgClosure*)p);
|
| 1876 | 1880 | bd = Bdescr((P_)str);
|
| 1877 | 1881 | }
|
| 1878 | - return (bd->flags & BF_NONMOVING_SWEEPING) == 0
|
|
| 1882 | + return (bd_flags & BF_NONMOVING_SWEEPING) == 0
|
|
| 1879 | 1883 | // the large object wasn't in the snapshot and therefore wasn't marked
|
| 1880 | - || (bd->flags & BF_MARKED) != 0;
|
|
| 1884 | + || (bd_flags & BF_MARKED) != 0;
|
|
| 1881 | 1885 | // The object was marked
|
| 1882 | 1886 | } else {
|
| 1883 | 1887 | struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
|
| ... | ... | @@ -1931,8 +1935,8 @@ static bool nonmovingIsNowAlive (StgClosure *p) |
| 1931 | 1935 | }
|
| 1932 | 1936 | |
| 1933 | 1937 | bdescr *bd = Bdescr((P_)p);
|
| 1938 | + const uint16_t flags = block_get_flags(bd);
|
|
| 1934 | 1939 | |
| 1935 | - const uint16_t flags = bd->flags;
|
|
| 1936 | 1940 | if (flags & BF_LARGE) {
|
| 1937 | 1941 | if (flags & BF_PINNED && !(flags & BF_NONMOVING)) {
|
| 1938 | 1942 | // In this case we have a pinned object living in a non-full
|
| ... | ... | @@ -1942,15 +1946,15 @@ static bool nonmovingIsNowAlive (StgClosure *p) |
| 1942 | 1946 | return true;
|
| 1943 | 1947 | }
|
| 1944 | 1948 | |
| 1945 | - ASSERT(bd->flags & BF_NONMOVING);
|
|
| 1946 | - return (bd->flags & BF_NONMOVING_SWEEPING) == 0
|
|
| 1949 | + ASSERT(flags & BF_NONMOVING);
|
|
| 1950 | + return (flags & BF_NONMOVING_SWEEPING) == 0
|
|
| 1947 | 1951 | // the large object wasn't in the snapshot and therefore wasn't marked
|
| 1948 | - || (bd->flags & BF_MARKED) != 0;
|
|
| 1952 | + || (flags & BF_MARKED) != 0;
|
|
| 1949 | 1953 | // The object was marked
|
| 1950 | 1954 | } else {
|
| 1951 | 1955 | // All non-static objects in the non-moving heap should be marked as
|
| 1952 | 1956 | // BF_NONMOVING.
|
| 1953 | - ASSERT(bd->flags & BF_NONMOVING);
|
|
| 1957 | + ASSERT(flags & BF_NONMOVING);
|
|
| 1954 | 1958 | |
| 1955 | 1959 | struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p);
|
| 1956 | 1960 | StgClosure *snapshot_loc =
|
| ... | ... | @@ -2013,7 +2017,8 @@ bool nonmovingTidyWeaks (struct MarkQueue_ *queue) |
| 2013 | 2017 | |
| 2014 | 2018 | // See Note [Weak pointer processing and the non-moving GC] in
|
| 2015 | 2019 | // MarkWeak.c
|
| 2016 | - bool key_in_nonmoving = HEAP_ALLOCED_GC(w->key) && Bdescr((StgPtr) w->key)->flags & BF_NONMOVING;
|
|
| 2020 | + bdescr *key_bd = Bdescr((StgPtr) w->key);
|
|
| 2021 | + bool key_in_nonmoving = HEAP_ALLOCED_GC(w->key) && block_get_flags(key_bd) & BF_NONMOVING;
|
|
| 2017 | 2022 | if (!key_in_nonmoving || nonmovingIsNowAlive(w->key)) {
|
| 2018 | 2023 | nonmovingMarkLiveWeak(queue, w);
|
| 2019 | 2024 | did_work = true;
|
| ... | ... | @@ -1269,6 +1269,7 @@ scavenge_one(StgPtr p) |
| 1269 | 1269 | bool no_luck;
|
| 1270 | 1270 | bool saved_eager_promotion;
|
| 1271 | 1271 | |
| 1272 | +try_again:
|
|
| 1272 | 1273 | saved_eager_promotion = gct->eager_promotion;
|
| 1273 | 1274 | |
| 1274 | 1275 | ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
|
| ... | ... | @@ -1610,6 +1611,13 @@ scavenge_one(StgPtr p) |
| 1610 | 1611 | scavenge_continuation((StgContinuation *)p);
|
| 1611 | 1612 | break;
|
| 1612 | 1613 | |
| 1614 | + case WHITEHOLE:
|
|
| 1615 | + // This may happen when the nonmoving GC is in use via two paths:
|
|
| 1616 | + // 1. when an MVAR is being marked concurrently
|
|
| 1617 | + // 2. when the object belongs to a chain of selectors being short-cutted.
|
|
| 1618 | + while (get_itbl((StgClosure*) p) == &stg_WHITEHOLE_info);
|
|
| 1619 | + goto try_again;
|
|
| 1620 | + |
|
| 1613 | 1621 | default:
|
| 1614 | 1622 | barf("scavenge_one: strange object %d", (int)(info->type));
|
| 1615 | 1623 | }
|
| ... | ... | @@ -8,8 +8,8 @@ SUPPORTED_CPU_FEATURES = { |
| 8 | 8 | # These aren't comprehensive; they are only CPU features that we care about
|
| 9 | 9 | |
| 10 | 10 | # x86:
|
| 11 | - 'sse', 'sse2', 'sse3', 'ssse3', 'sse4_1', 'sse4_2',
|
|
| 12 | - 'avx1', 'avx2',
|
|
| 11 | + 'sse', 'sse2', 'sse3', 'pni', 'ssse3', 'sse4_1', 'sse4_2',
|
|
| 12 | + 'avx', 'avx2', 'avx512f',
|
|
| 13 | 13 | 'fma',
|
| 14 | 14 | 'popcnt', 'bmi1', 'bmi2'
|
| 15 | 15 | }
|
| 1 | +import Control.Monad
|
|
| 2 | +import GHC.Platform.ArchOS
|
|
| 3 | +import GHC.Platform.Host
|
|
| 4 | +import System.Info
|
|
| 5 | + |
|
| 6 | +main :: IO ()
|
|
| 7 | +main =
|
|
| 8 | + when ((arch, os) /= (arch', os')) $
|
|
| 9 | + fail $
|
|
| 10 | + "System.Info says host platform is "
|
|
| 11 | + <> show (arch, os)
|
|
| 12 | + <> " but GHC.Platform.Host says "
|
|
| 13 | + <> show (arch', os')
|
|
| 14 | + where
|
|
| 15 | + (arch', os') =
|
|
| 16 | + (stringEncodeArch hostPlatformArch, stringEncodeOS hostPlatformOS) |
| 1 | +test('T26449', [], compile_and_run, ['']) |
| 1 | +{-# LANGUAGE OverloadedStrings #-}
|
|
| 2 | + |
|
| 3 | +module Reproducer (strToInt) where
|
|
| 4 | + |
|
| 5 | +import qualified Data.Text as T
|
|
| 6 | + |
|
| 7 | +{- This program results in a nested chain of join points and cases which tests
|
|
| 8 | + primarily OccAnal and Unfolding performance.
|
|
| 9 | +-}
|
|
| 10 | + |
|
| 11 | +strToInt :: T.Text -> Maybe Int
|
|
| 12 | +strToInt txt = case txt of
|
|
| 13 | + "0" -> Just 0
|
|
| 14 | + "1" -> Just 1
|
|
| 15 | + "2" -> Just 2
|
|
| 16 | + "3" -> Just 3
|
|
| 17 | + "4" -> Just 4
|
|
| 18 | + "5" -> Just 5
|
|
| 19 | + "6" -> Just 6
|
|
| 20 | + "7" -> Just 7
|
|
| 21 | + "8" -> Just 8
|
|
| 22 | + "9" -> Just 9
|
|
| 23 | + "10" -> Just 10
|
|
| 24 | + "11" -> Just 11
|
|
| 25 | + "12" -> Just 12
|
|
| 26 | + "13" -> Just 13
|
|
| 27 | + "14" -> Just 14
|
|
| 28 | + "15" -> Just 15
|
|
| 29 | + "16" -> Just 16
|
|
| 30 | + "17" -> Just 17
|
|
| 31 | + "18" -> Just 18
|
|
| 32 | + "19" -> Just 19
|
|
| 33 | + "20" -> Just 20
|
|
| 34 | + "21" -> Just 21
|
|
| 35 | + "22" -> Just 22
|
|
| 36 | + "23" -> Just 23
|
|
| 37 | + "24" -> Just 24
|
|
| 38 | + "25" -> Just 25
|
|
| 39 | + "26" -> Just 26
|
|
| 40 | + "27" -> Just 27
|
|
| 41 | + "28" -> Just 28
|
|
| 42 | + "29" -> Just 29
|
|
| 43 | + "30" -> Just 30
|
|
| 44 | + "31" -> Just 31
|
|
| 45 | + "32" -> Just 32
|
|
| 46 | + "33" -> Just 33
|
|
| 47 | + "34" -> Just 34
|
|
| 48 | + "35" -> Just 35
|
|
| 49 | + "36" -> Just 36
|
|
| 50 | + "37" -> Just 37
|
|
| 51 | + "38" -> Just 38
|
|
| 52 | + "39" -> Just 39
|
|
| 53 | + "40" -> Just 40
|
|
| 54 | + "41" -> Just 41
|
|
| 55 | + "42" -> Just 42
|
|
| 56 | + "43" -> Just 43
|
|
| 57 | + "44" -> Just 44
|
|
| 58 | + "45" -> Just 45
|
|
| 59 | + "46" -> Just 46
|
|
| 60 | + "47" -> Just 47
|
|
| 61 | + "48" -> Just 48
|
|
| 62 | + "49" -> Just 49
|
|
| 63 | + "50" -> Just 50
|
|
| 64 | + "51" -> Just 51
|
|
| 65 | + "52" -> Just 52
|
|
| 66 | + "53" -> Just 53
|
|
| 67 | + "54" -> Just 54
|
|
| 68 | + "55" -> Just 55
|
|
| 69 | + "56" -> Just 56
|
|
| 70 | + "57" -> Just 57
|
|
| 71 | + "58" -> Just 58
|
|
| 72 | + "59" -> Just 59
|
|
| 73 | + "60" -> Just 60
|
|
| 74 | + "61" -> Just 61
|
|
| 75 | + "62" -> Just 62
|
|
| 76 | + "63" -> Just 63
|
|
| 77 | + "64" -> Just 64
|
|
| 78 | + "65" -> Just 65
|
|
| 79 | + "66" -> Just 66
|
|
| 80 | + "67" -> Just 67
|
|
| 81 | + "68" -> Just 68
|
|
| 82 | + "69" -> Just 69
|
|
| 83 | + "70" -> Just 70
|
|
| 84 | + "71" -> Just 71
|
|
| 85 | + "72" -> Just 72
|
|
| 86 | + "73" -> Just 73
|
|
| 87 | + "74" -> Just 74
|
|
| 88 | + "75" -> Just 75
|
|
| 89 | + "76" -> Just 76
|
|
| 90 | + "77" -> Just 77
|
|
| 91 | + "78" -> Just 78
|
|
| 92 | + "79" -> Just 79
|
|
| 93 | + "80" -> Just 80
|
|
| 94 | + "81" -> Just 81
|
|
| 95 | + "82" -> Just 82
|
|
| 96 | + "83" -> Just 83
|
|
| 97 | + "84" -> Just 84
|
|
| 98 | + "85" -> Just 85
|
|
| 99 | + "86" -> Just 86
|
|
| 100 | + "87" -> Just 87
|
|
| 101 | + "88" -> Just 88
|
|
| 102 | + "89" -> Just 89
|
|
| 103 | + "90" -> Just 90
|
|
| 104 | + "91" -> Just 91
|
|
| 105 | + "92" -> Just 92
|
|
| 106 | + "93" -> Just 93
|
|
| 107 | + "94" -> Just 94
|
|
| 108 | + "95" -> Just 95
|
|
| 109 | + "96" -> Just 96
|
|
| 110 | + "97" -> Just 97
|
|
| 111 | + "98" -> Just 98
|
|
| 112 | + "99" -> Just 99
|
|
| 113 | + "100" -> Just 100
|
|
| 114 | + "101" -> Just 101
|
|
| 115 | + "102" -> Just 102
|
|
| 116 | + "103" -> Just 103
|
|
| 117 | + "104" -> Just 104
|
|
| 118 | + "105" -> Just 105
|
|
| 119 | + "106" -> Just 106
|
|
| 120 | + "107" -> Just 107
|
|
| 121 | + "108" -> Just 108
|
|
| 122 | + "109" -> Just 109
|
|
| 123 | + "110" -> Just 110
|
|
| 124 | + "111" -> Just 111
|
|
| 125 | + "112" -> Just 112
|
|
| 126 | + "113" -> Just 113
|
|
| 127 | + "114" -> Just 114
|
|
| 128 | + "115" -> Just 115
|
|
| 129 | + "116" -> Just 116
|
|
| 130 | + "117" -> Just 117
|
|
| 131 | + "118" -> Just 118
|
|
| 132 | + "119" -> Just 119
|
|
| 133 | + "120" -> Just 120
|
|
| 134 | + "121" -> Just 121
|
|
| 135 | + "122" -> Just 122
|
|
| 136 | + "123" -> Just 123
|
|
| 137 | + "124" -> Just 124
|
|
| 138 | + "125" -> Just 125
|
|
| 139 | + "126" -> Just 126
|
|
| 140 | + "127" -> Just 127
|
|
| 141 | + "128" -> Just 128
|
|
| 142 | + "129" -> Just 129
|
|
| 143 | + "130" -> Just 130
|
|
| 144 | + "131" -> Just 131
|
|
| 145 | + "132" -> Just 132
|
|
| 146 | + "133" -> Just 133
|
|
| 147 | + "134" -> Just 134
|
|
| 148 | + "135" -> Just 135
|
|
| 149 | + "136" -> Just 136
|
|
| 150 | + "137" -> Just 137
|
|
| 151 | + "138" -> Just 138
|
|
| 152 | + "139" -> Just 139
|
|
| 153 | + "140" -> Just 140
|
|
| 154 | + "141" -> Just 141
|
|
| 155 | + "142" -> Just 142
|
|
| 156 | + "143" -> Just 143
|
|
| 157 | + "144" -> Just 144
|
|
| 158 | + "145" -> Just 145
|
|
| 159 | + "146" -> Just 146
|
|
| 160 | + "147" -> Just 147
|
|
| 161 | + "148" -> Just 148
|
|
| 162 | + "149" -> Just 149
|
|
| 163 | + "150" -> Just 150
|
|
| 164 | + "151" -> Just 151
|
|
| 165 | + "152" -> Just 152
|
|
| 166 | + "153" -> Just 153
|
|
| 167 | + "154" -> Just 154
|
|
| 168 | + "155" -> Just 155
|
|
| 169 | + "156" -> Just 156
|
|
| 170 | + "157" -> Just 157
|
|
| 171 | + "158" -> Just 158
|
|
| 172 | + "159" -> Just 159
|
|
| 173 | + "160" -> Just 160
|
|
| 174 | + "161" -> Just 161
|
|
| 175 | + "162" -> Just 162
|
|
| 176 | + "163" -> Just 163
|
|
| 177 | + "164" -> Just 164
|
|
| 178 | + "165" -> Just 165
|
|
| 179 | + "166" -> Just 166
|
|
| 180 | + "167" -> Just 167
|
|
| 181 | + "168" -> Just 168
|
|
| 182 | + "169" -> Just 169
|
|
| 183 | + "170" -> Just 170
|
|
| 184 | + "171" -> Just 171
|
|
| 185 | + "172" -> Just 172
|
|
| 186 | + "173" -> Just 173
|
|
| 187 | + "174" -> Just 174
|
|
| 188 | + "175" -> Just 175
|
|
| 189 | + "176" -> Just 176
|
|
| 190 | + "177" -> Just 177
|
|
| 191 | + "178" -> Just 178
|
|
| 192 | + "179" -> Just 179
|
|
| 193 | + "180" -> Just 180
|
|
| 194 | + "181" -> Just 181
|
|
| 195 | + "182" -> Just 182
|
|
| 196 | + "183" -> Just 183
|
|
| 197 | + "184" -> Just 184
|
|
| 198 | + "185" -> Just 185
|
|
| 199 | + "186" -> Just 186
|
|
| 200 | + "187" -> Just 187
|
|
| 201 | + "188" -> Just 188
|
|
| 202 | + "189" -> Just 189
|
|
| 203 | + "190" -> Just 190
|
|
| 204 | + "191" -> Just 191
|
|
| 205 | + "192" -> Just 192
|
|
| 206 | + "193" -> Just 193
|
|
| 207 | + "194" -> Just 194
|
|
| 208 | + "195" -> Just 195
|
|
| 209 | + "196" -> Just 196
|
|
| 210 | + "197" -> Just 197
|
|
| 211 | + "198" -> Just 198
|
|
| 212 | + "199" -> Just 199
|
|
| 213 | + "200" -> Just 200
|
|
| 214 | + "201" -> Just 201
|
|
| 215 | + "202" -> Just 202
|
|
| 216 | + "203" -> Just 203
|
|
| 217 | + "204" -> Just 204
|
|
| 218 | + "205" -> Just 205
|
|
| 219 | + "206" -> Just 206
|
|
| 220 | + "207" -> Just 207
|
|
| 221 | + "208" -> Just 208
|
|
| 222 | + "209" -> Just 209
|
|
| 223 | + "210" -> Just 210
|
|
| 224 | + "211" -> Just 211
|
|
| 225 | + "212" -> Just 212
|
|
| 226 | + "213" -> Just 213
|
|
| 227 | + "214" -> Just 214
|
|
| 228 | + "215" -> Just 215
|
|
| 229 | + "216" -> Just 216
|
|
| 230 | + "217" -> Just 217
|
|
| 231 | + "218" -> Just 218
|
|
| 232 | + "219" -> Just 219
|
|
| 233 | + "220" -> Just 220
|
|
| 234 | + "221" -> Just 221
|
|
| 235 | + "222" -> Just 222
|
|
| 236 | + "223" -> Just 223
|
|
| 237 | + "224" -> Just 224
|
|
| 238 | + "225" -> Just 225
|
|
| 239 | + "226" -> Just 226
|
|
| 240 | + "227" -> Just 227
|
|
| 241 | + "228" -> Just 228
|
|
| 242 | + "229" -> Just 229
|
|
| 243 | + "230" -> Just 230
|
|
| 244 | + "231" -> Just 231
|
|
| 245 | + "232" -> Just 232
|
|
| 246 | + "233" -> Just 233
|
|
| 247 | + "234" -> Just 234
|
|
| 248 | + "235" -> Just 235
|
|
| 249 | + "236" -> Just 236
|
|
| 250 | + "237" -> Just 237
|
|
| 251 | + "238" -> Just 238
|
|
| 252 | + "239" -> Just 239
|
|
| 253 | + "240" -> Just 240
|
|
| 254 | + "241" -> Just 241
|
|
| 255 | + "242" -> Just 242
|
|
| 256 | + "243" -> Just 243
|
|
| 257 | + "244" -> Just 244
|
|
| 258 | + "245" -> Just 245
|
|
| 259 | + "246" -> Just 246
|
|
| 260 | + "247" -> Just 247
|
|
| 261 | + "248" -> Just 248
|
|
| 262 | + "249" -> Just 249
|
|
| 263 | + "250" -> Just 250
|
|
| 264 | + "251" -> Just 251
|
|
| 265 | + "252" -> Just 252
|
|
| 266 | + "253" -> Just 253
|
|
| 267 | + "254" -> Just 254
|
|
| 268 | + "255" -> Just 255
|
|
| 269 | + "256" -> Just 256
|
|
| 270 | + "257" -> Just 257
|
|
| 271 | + "258" -> Just 258
|
|
| 272 | + "259" -> Just 259
|
|
| 273 | + "260" -> Just 260
|
|
| 274 | + "261" -> Just 261
|
|
| 275 | + "262" -> Just 262
|
|
| 276 | + "263" -> Just 263
|
|
| 277 | + "264" -> Just 264
|
|
| 278 | + "265" -> Just 265
|
|
| 279 | + "266" -> Just 266
|
|
| 280 | + "267" -> Just 267
|
|
| 281 | + "268" -> Just 268
|
|
| 282 | + "269" -> Just 269
|
|
| 283 | + "270" -> Just 270
|
|
| 284 | + "271" -> Just 271
|
|
| 285 | + "272" -> Just 272
|
|
| 286 | + "273" -> Just 273
|
|
| 287 | + "274" -> Just 274
|
|
| 288 | + "275" -> Just 275
|
|
| 289 | + "276" -> Just 276
|
|
| 290 | + "277" -> Just 277
|
|
| 291 | + "278" -> Just 278
|
|
| 292 | + "279" -> Just 279
|
|
| 293 | + "280" -> Just 280
|
|
| 294 | + "281" -> Just 281
|
|
| 295 | + "282" -> Just 282
|
|
| 296 | + "283" -> Just 283
|
|
| 297 | + "284" -> Just 284
|
|
| 298 | + "285" -> Just 285
|
|
| 299 | + "286" -> Just 286
|
|
| 300 | + "287" -> Just 287
|
|
| 301 | + "288" -> Just 288
|
|
| 302 | + "289" -> Just 289
|
|
| 303 | + "290" -> Just 290
|
|
| 304 | + "291" -> Just 291
|
|
| 305 | + "292" -> Just 292
|
|
| 306 | + "293" -> Just 293
|
|
| 307 | + "294" -> Just 294
|
|
| 308 | + "295" -> Just 295
|
|
| 309 | + "296" -> Just 296
|
|
| 310 | + "297" -> Just 297
|
|
| 311 | + "298" -> Just 298
|
|
| 312 | + "299" -> Just 299
|
|
| 313 | + "300" -> Just 300
|
|
| 314 | + "301" -> Just 301
|
|
| 315 | + "302" -> Just 302
|
|
| 316 | + "303" -> Just 303
|
|
| 317 | + "304" -> Just 304
|
|
| 318 | + "305" -> Just 305
|
|
| 319 | + "306" -> Just 306
|
|
| 320 | + "307" -> Just 307
|
|
| 321 | + "308" -> Just 308
|
|
| 322 | + "309" -> Just 309
|
|
| 323 | + "310" -> Just 310
|
|
| 324 | + "311" -> Just 311
|
|
| 325 | + "312" -> Just 312
|
|
| 326 | + "313" -> Just 313
|
|
| 327 | + "314" -> Just 314
|
|
| 328 | + "315" -> Just 315
|
|
| 329 | + "316" -> Just 316
|
|
| 330 | + "317" -> Just 317
|
|
| 331 | + "318" -> Just 318
|
|
| 332 | + "319" -> Just 319
|
|
| 333 | + "320" -> Just 320
|
|
| 334 | + "321" -> Just 321
|
|
| 335 | + "322" -> Just 322
|
|
| 336 | + "323" -> Just 323
|
|
| 337 | + "324" -> Just 324
|
|
| 338 | + "325" -> Just 325
|
|
| 339 | + "326" -> Just 326
|
|
| 340 | + "327" -> Just 327
|
|
| 341 | + "328" -> Just 328
|
|
| 342 | + "329" -> Just 329
|
|
| 343 | + "330" -> Just 330
|
|
| 344 | + "331" -> Just 331
|
|
| 345 | + "332" -> Just 332
|
|
| 346 | + "333" -> Just 333
|
|
| 347 | + "334" -> Just 334
|
|
| 348 | + "335" -> Just 335
|
|
| 349 | + "336" -> Just 336
|
|
| 350 | + "337" -> Just 337
|
|
| 351 | + "338" -> Just 338
|
|
| 352 | + "339" -> Just 339
|
|
| 353 | + "340" -> Just 340
|
|
| 354 | + "341" -> Just 341
|
|
| 355 | + "342" -> Just 342
|
|
| 356 | + "343" -> Just 343
|
|
| 357 | + "344" -> Just 344
|
|
| 358 | + "345" -> Just 345
|
|
| 359 | + "346" -> Just 346
|
|
| 360 | + "347" -> Just 347
|
|
| 361 | + "348" -> Just 348
|
|
| 362 | + "349" -> Just 349
|
|
| 363 | + "350" -> Just 350
|
|
| 364 | + "351" -> Just 351
|
|
| 365 | + "352" -> Just 352
|
|
| 366 | + "353" -> Just 353
|
|
| 367 | + "354" -> Just 354
|
|
| 368 | + "355" -> Just 355
|
|
| 369 | + "356" -> Just 356
|
|
| 370 | + "357" -> Just 357
|
|
| 371 | + "358" -> Just 358
|
|
| 372 | + "359" -> Just 359
|
|
| 373 | + "360" -> Just 360
|
|
| 374 | + "361" -> Just 361
|
|
| 375 | + "362" -> Just 362
|
|
| 376 | + "363" -> Just 363
|
|
| 377 | + "364" -> Just 364
|
|
| 378 | + "365" -> Just 365
|
|
| 379 | + "366" -> Just 366
|
|
| 380 | + "367" -> Just 367
|
|
| 381 | + "368" -> Just 368
|
|
| 382 | + "369" -> Just 369
|
|
| 383 | + "370" -> Just 370
|
|
| 384 | + "371" -> Just 371
|
|
| 385 | + "372" -> Just 372
|
|
| 386 | + "373" -> Just 373
|
|
| 387 | + "374" -> Just 374
|
|
| 388 | + "375" -> Just 375
|
|
| 389 | + "376" -> Just 376
|
|
| 390 | + "377" -> Just 377
|
|
| 391 | + "378" -> Just 378
|
|
| 392 | + "379" -> Just 379
|
|
| 393 | + "380" -> Just 380
|
|
| 394 | + "381" -> Just 381
|
|
| 395 | + "382" -> Just 382
|
|
| 396 | + "383" -> Just 383
|
|
| 397 | + "384" -> Just 384
|
|
| 398 | + "385" -> Just 385
|
|
| 399 | + "386" -> Just 386
|
|
| 400 | + "387" -> Just 387
|
|
| 401 | + "388" -> Just 388
|
|
| 402 | + "389" -> Just 389
|
|
| 403 | + "390" -> Just 390
|
|
| 404 | + "391" -> Just 391
|
|
| 405 | + "392" -> Just 392
|
|
| 406 | + "393" -> Just 393
|
|
| 407 | + "394" -> Just 394
|
|
| 408 | + "395" -> Just 395
|
|
| 409 | + "396" -> Just 396
|
|
| 410 | + "397" -> Just 397
|
|
| 411 | + "398" -> Just 398
|
|
| 412 | + "399" -> Just 399
|
|
| 413 | + "400" -> Just 400
|
|
| 414 | + "401" -> Just 401
|
|
| 415 | + "402" -> Just 402
|
|
| 416 | + "403" -> Just 403
|
|
| 417 | + "404" -> Just 404
|
|
| 418 | + "405" -> Just 405
|
|
| 419 | + "406" -> Just 406
|
|
| 420 | + "407" -> Just 407
|
|
| 421 | + "408" -> Just 408
|
|
| 422 | + "409" -> Just 409
|
|
| 423 | + "410" -> Just 410
|
|
| 424 | + "411" -> Just 411
|
|
| 425 | + "412" -> Just 412
|
|
| 426 | + "413" -> Just 413
|
|
| 427 | + "414" -> Just 414
|
|
| 428 | + "415" -> Just 415
|
|
| 429 | + "416" -> Just 416
|
|
| 430 | + "417" -> Just 417
|
|
| 431 | + "418" -> Just 418
|
|
| 432 | + "419" -> Just 419
|
|
| 433 | + "420" -> Just 420
|
|
| 434 | + "421" -> Just 421
|
|
| 435 | + "422" -> Just 422
|
|
| 436 | + "423" -> Just 423
|
|
| 437 | + "424" -> Just 424
|
|
| 438 | + "425" -> Just 425
|
|
| 439 | + "426" -> Just 426
|
|
| 440 | + "427" -> Just 427
|
|
| 441 | + "428" -> Just 428
|
|
| 442 | + "429" -> Just 429
|
|
| 443 | + "430" -> Just 430
|
|
| 444 | + "431" -> Just 431
|
|
| 445 | + "432" -> Just 432
|
|
| 446 | + "433" -> Just 433
|
|
| 447 | + "434" -> Just 434
|
|
| 448 | + "435" -> Just 435
|
|
| 449 | + "436" -> Just 436
|
|
| 450 | + "437" -> Just 437
|
|
| 451 | + "438" -> Just 438
|
|
| 452 | + "439" -> Just 439
|
|
| 453 | + "440" -> Just 440
|
|
| 454 | + "441" -> Just 441
|
|
| 455 | + "442" -> Just 442
|
|
| 456 | + "443" -> Just 443
|
|
| 457 | + "444" -> Just 444
|
|
| 458 | + "445" -> Just 445
|
|
| 459 | + "446" -> Just 446
|
|
| 460 | + "447" -> Just 447
|
|
| 461 | + "448" -> Just 448
|
|
| 462 | + "449" -> Just 449
|
|
| 463 | + "450" -> Just 450
|
|
| 464 | + "451" -> Just 451
|
|
| 465 | + "452" -> Just 452
|
|
| 466 | + "453" -> Just 453
|
|
| 467 | + "454" -> Just 454
|
|
| 468 | + "455" -> Just 455
|
|
| 469 | + "456" -> Just 456
|
|
| 470 | + "457" -> Just 457
|
|
| 471 | + "458" -> Just 458
|
|
| 472 | + "459" -> Just 459
|
|
| 473 | + "460" -> Just 460
|
|
| 474 | + "461" -> Just 461
|
|
| 475 | + "462" -> Just 462
|
|
| 476 | + "463" -> Just 463
|
|
| 477 | + "464" -> Just 464
|
|
| 478 | + "465" -> Just 465
|
|
| 479 | + "466" -> Just 466
|
|
| 480 | + "467" -> Just 467
|
|
| 481 | + "468" -> Just 468
|
|
| 482 | + "469" -> Just 469
|
|
| 483 | + "470" -> Just 470
|
|
| 484 | + "471" -> Just 471
|
|
| 485 | + "472" -> Just 472
|
|
| 486 | + "473" -> Just 473
|
|
| 487 | + "474" -> Just 474
|
|
| 488 | + "475" -> Just 475
|
|
| 489 | + "476" -> Just 476
|
|
| 490 | + "477" -> Just 477
|
|
| 491 | + "478" -> Just 478
|
|
| 492 | + "479" -> Just 479
|
|
| 493 | + "480" -> Just 480
|
|
| 494 | + "481" -> Just 481
|
|
| 495 | + "482" -> Just 482
|
|
| 496 | + "483" -> Just 483
|
|
| 497 | + "484" -> Just 484
|
|
| 498 | + "485" -> Just 485
|
|
| 499 | + "486" -> Just 486
|
|
| 500 | + "487" -> Just 487
|
|
| 501 | + "488" -> Just 488
|
|
| 502 | + "489" -> Just 489
|
|
| 503 | + "490" -> Just 490
|
|
| 504 | + "491" -> Just 491
|
|
| 505 | + "492" -> Just 492
|
|
| 506 | + "493" -> Just 493
|
|
| 507 | + "494" -> Just 494
|
|
| 508 | + "495" -> Just 495
|
|
| 509 | + "496" -> Just 496
|
|
| 510 | + "497" -> Just 497
|
|
| 511 | + "498" -> Just 498
|
|
| 512 | + "499" -> Just 499
|
|
| 513 | + "500" -> Just 500
|
|
| 514 | + _ -> Nothing |
| ... | ... | @@ -716,3 +716,8 @@ test ('LookupFusion', |
| 716 | 716 | test('T24471',
|
| 717 | 717 | [req_th, collect_compiler_stats('all', 5)],
|
| 718 | 718 | multimod_compile, ['T24471', '-v0 -O'])
|
| 719 | + |
|
| 720 | +test ('T26425',
|
|
| 721 | + [ collect_compiler_stats('all',5) ],
|
|
| 722 | + compile,
|
|
| 723 | + ['-O']) |
|
| \ No newline at end of file |
| 1 | 1 | {-# LANGUAGE BangPatterns #-}
|
| 2 | -{-# OPTIONS -fvia-C -optc-O3 -fexcess-precision -optc-msse3 #-}
|
|
| 2 | +{-# OPTIONS -optc-O3 -fexcess-precision #-}
|
|
| 3 | 3 | |
| 4 | 4 | import Control.Monad.ST
|
| 5 | 5 | import Data.Array.ST
|
| ... | ... | @@ -43,6 +43,7 @@ test('T3586', |
| 43 | 43 | [collect_runtime_residency(2),
|
| 44 | 44 | collect_stats('bytes allocated', 5),
|
| 45 | 45 | only_ways(['normal']),
|
| 46 | + when(have_cpu_feature('pni') or have_cpu_feature('sse3'), extra_hc_opts('-optc-msse3')),
|
|
| 46 | 47 | ],
|
| 47 | 48 | compile_and_run,
|
| 48 | 49 | ['-O'])
|