[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Revert "ci: enable parallel compression for xz"
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Fri Sep 30 18:55:28 UTC 2022
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
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.
- - - - -
6b366242 by M Farkas-Dyck at 2022-09-30T14:55:00-04:00
Scrub various partiality involving empty lists.
Avoids some uses of `head` and `tail`, and some panics when an argument is null.
- - - - -
25 changed files:
- .gitlab/ci.sh
- 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/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
- 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:
=====================================
.gitlab/ci.sh
=====================================
@@ -499,7 +499,7 @@ function build_hadrian() {
if [[ -n "${REINSTALL_GHC:-}" ]]; then
run_hadrian build-cabal -V
else
- XZ_OPT="${XZ_OPT:-} -T$cores" run_hadrian binary-dist -V
+ run_hadrian binary-dist -V
mv _build/bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz"
fi
=====================================
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/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)
=====================================
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/66e5e7cf9e1501ddde870af4a2403de97e047701...6b36624262c1956f7fd2ba8b50b5fe14cd9e83e9
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/66e5e7cf9e1501ddde870af4a2403de97e047701...6b36624262c1956f7fd2ba8b50b5fe14cd9e83e9
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220930/09d1ffeb/attachment-0001.html>
More information about the ghc-commits
mailing list