[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Reg.Liveness: Strictness
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Tue Jul 18 21:14:07 UTC 2023
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
8ad58ef1 by Ben Gamari at 2023-07-18T17:13:00-04:00
Reg.Liveness: Strictness
- - - - -
490342ef by Ben Gamari at 2023-07-18T17:13:01-04:00
Reg.Liveness: Don't repeatedly construct UniqSets
- - - - -
e822b807 by Ben Gamari at 2023-07-18T17:13:01-04:00
compiler/Types: Ensure that fromList-type operations can fuse
In #20740 I noticed that mkUniqSet does not fuse. In practice, allowing
it to do so makes a considerable difference in allocations due to the
backend.
Metric Decrease:
T12707
T13379
T3294
T4801
T5321FD
T5321Fun
T783
- - - - -
0da0bea2 by Sven Tennie at 2023-07-18T17:13:01-04:00
x86 Codegen: Implement MO_S_MulMayOflo for W16
- - - - -
30b24868 by Sven Tennie at 2023-07-18T17:13:01-04:00
x86 CodeGen: MO_S_MulMayOflo better error message for rep > W64
It's useful to see which value made the pattern match fail. (If it ever
occurs.)
- - - - -
56d53198 by Sven Tennie at 2023-07-18T17:13:01-04:00
x86 CodeGen: Implement MO_S_MulMayOflo for W8
This case wasn't handled before. But, the test-primops test suite showed
that it actually might appear.
- - - - -
8a6f413f by Sven Tennie at 2023-07-18T17:13:01-04:00
Add test for %mulmayoflo primop
The test expects a perfect implementation with no false positives.
- - - - -
73d540fc by Matthew Pickering at 2023-07-18T17:13:02-04:00
lint-ci-config: Generate jobs-metadata.json
We also now save the jobs-metadata.json and jobs.yaml file as artifacts
as:
* It might be useful for someone who is modifying CI to copy jobs.yaml
if they are having trouble regenerating locally.
* jobs-metadata.json is very useful for downstream pipelines to work out
the right job to download.
Fixes #23654
- - - - -
12d79a59 by Vladislav Zavialov at 2023-07-18T17:13:03-04:00
Initialize 9.10.1-notes.rst
Create new release notes for the next GHC release (GHC 9.10)
- - - - -
8a4d3b7c by sheaf at 2023-07-18T17:13:05-04:00
Prioritise Parent when looking up class sub-binder
When we look up children GlobalRdrElts of a given Parent, we sometimes
would rather prioritise those GlobalRdrElts which have the right Parent,
and sometimes prioritise those that have the right NameSpace:
- in export lists, we should prioritise NameSpace
- for class/instance binders, we should prioritise Parent
See Note [childGREPriority] in GHC.Types.Name.Reader.
fixes #23664
- - - - -
3ecd4722 by Alan Zimmerman at 2023-07-18T17:13:06-04:00
EPA: Improve annotation management in getMonoBind
Ensure the LHsDecl for a FunBind has the correct leading comments and
trailing annotations.
See the added note for details.
- - - - -
21 changed files:
- .gitlab-ci.yml
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Unique/Set.hs
- + docs/users_guide/9.10.1-notes.rst
- docs/users_guide/release-notes.rst
- + testsuite/tests/codeGen/should_run/MulMayOflo.hs
- + testsuite/tests/codeGen/should_run/MulMayOflo_full.cmm
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/printer/Test19784.hs
- + testsuite/tests/rename/should_compile/T23664.hs
- testsuite/tests/rename/should_compile/all.T
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -278,6 +278,13 @@ lint-ci-config:
- nix run .gitlab/generate-ci#generate-jobs
# 1 if .gitlab/generate_jobs changed the output of the generated config
- nix shell nixpkgs#git -c git diff --exit-code
+ # And run this to generate the .gitlab/jobs-metadata.json
+ - nix run .gitlab/generate-ci#generate-job-metadata
+ artifacts:
+ when: always
+ paths:
+ - .gitlab/jobs-metadata.json
+ - .gitlab/jobs.yaml
dependencies: []
lint-submods:
=====================================
compiler/GHC/Cmm/MachOp.hs
=====================================
@@ -56,6 +56,25 @@ Note that there are variety of places in the native code generator where we
assume that the code produced for a MachOp does not introduce new blocks.
-}
+-- Note [MO_S_MulMayOflo significant width]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- There are two interpretations in the code about what a multiplication
+-- overflow exactly means:
+--
+-- 1. The result does not fit into the specified width (of type Width.)
+-- 2. The result does not fit into a register.
+--
+-- (2) has some flaws: A following MO_Mul has a width, too. So MO_S_MulMayOflo
+-- may signal no overflow, while MO_Mul truncates the result. There are
+-- architectures with several register widths and it might be hard to decide
+-- what's an overflow and what not. Both attributes can easily lead to subtle
+-- bugs.
+--
+-- (1) has the benefit that its interpretation is completely independent of the
+-- architecture. So, the mid-term plan is to migrate to this
+-- interpretation/sematics.
+
data MachOp
-- Integer operations (insensitive to signed/unsigned)
= MO_Add Width
@@ -65,7 +84,8 @@ data MachOp
| MO_Mul Width -- low word of multiply
-- Signed multiply/divide
- | MO_S_MulMayOflo Width -- nonzero if signed multiply overflows
+ | MO_S_MulMayOflo Width -- nonzero if signed multiply overflows. See
+ -- Note [MO_S_MulMayOflo significant width]
| MO_S_Quot Width -- signed / (same semantics as IntQuotOp)
| MO_S_Rem Width -- signed % (same semantics as IntRemOp)
| MO_S_Neg Width -- unary -
=====================================
compiler/GHC/CmmToAsm/Reg/Liveness.hs
=====================================
@@ -1001,7 +1001,7 @@ livenessBack
livenessBack _ liveregs _ done [] = (liveregs, done)
livenessBack platform liveregs blockmap acc (instr : instrs)
- = let (liveregs', instr') = liveness1 platform liveregs blockmap instr
+ = let !(!liveregs', instr') = liveness1 platform liveregs blockmap instr
in livenessBack platform liveregs' blockmap (instr' : acc) instrs
@@ -1024,15 +1024,15 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
= (liveregs1, LiveInstr instr
(Just $ Liveness
{ liveBorn = emptyUniqSet
- , liveDieRead = mkUniqSet r_dying
- , liveDieWrite = mkUniqSet w_dying }))
+ , liveDieRead = r_dying
+ , liveDieWrite = w_dying }))
| otherwise
= (liveregs_br, LiveInstr instr
(Just $ Liveness
{ liveBorn = emptyUniqSet
, liveDieRead = mkUniqSet r_dying_br
- , liveDieWrite = mkUniqSet w_dying }))
+ , liveDieWrite = w_dying }))
where
!(RU read written) = regUsageOfInstr platform instr
@@ -1044,10 +1044,12 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
-- registers that are not live beyond this point, are recorded
-- as dying here.
- r_dying = [ reg | reg <- read, reg `notElem` written,
+ r_dying = mkUniqSet
+ [ reg | reg <- read, reg `notElem` written,
not (elementOfUniqSet reg liveregs) ]
- w_dying = [ reg | reg <- written,
+ w_dying = mkUniqSet
+ [ reg | reg <- written,
not (elementOfUniqSet reg liveregs) ]
-- union in the live regs from all the jump destinations of this
@@ -1067,6 +1069,6 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
-- registers that are live only in the branch targets should
-- be listed as dying here.
live_branch_only = live_from_branch `minusUniqSet` liveregs
- r_dying_br = nonDetEltsUniqSet (mkUniqSet r_dying `unionUniqSets`
+ r_dying_br = nonDetEltsUniqSet (r_dying `unionUniqSets`
live_branch_only)
-- See Note [Unique Determinism and code generation]
=====================================
compiler/GHC/CmmToAsm/X86/CodeGen.hs
=====================================
@@ -966,16 +966,38 @@ getRegister' _ is32Bit (CmmMachOp mop [x, y]) = -- dyadic MachOps
return (Fixed format eax code)
-
imulMayOflo :: Width -> CmmExpr -> CmmExpr -> NatM Register
+ imulMayOflo W8 a b = do
+ -- The general case (W16, W32, W64) doesn't work for W8 as its
+ -- multiplication doesn't use two registers.
+ --
+ -- The plan is:
+ -- 1. truncate and sign-extend a and b to 8bit width
+ -- 2. multiply a' = a * b in 32bit width
+ -- 3. copy and sign-extend 8bit from a' to c
+ -- 4. compare a' and c: they are equal if there was no overflow
+ (a_reg, a_code) <- getNonClobberedReg a
+ (b_reg, b_code) <- getNonClobberedReg b
+ let
+ code = a_code `appOL` b_code `appOL`
+ toOL [
+ MOVSxL II8 (OpReg a_reg) (OpReg a_reg),
+ MOVSxL II8 (OpReg b_reg) (OpReg b_reg),
+ IMUL II32 (OpReg b_reg) (OpReg a_reg),
+ MOVSxL II8 (OpReg a_reg) (OpReg eax),
+ CMP II16 (OpReg a_reg) (OpReg eax),
+ SETCC NE (OpReg eax)
+ ]
+ return (Fixed II8 eax code)
imulMayOflo rep a b = do
(a_reg, a_code) <- getNonClobberedReg a
b_code <- getAnyReg b
let
shift_amt = case rep of
+ W16 -> 15
W32 -> 31
W64 -> 63
- _ -> panic "shift_amt"
+ w -> panic ("shift_amt: " ++ show w)
format = intFormat rep
code = a_code `appOL` b_code eax `appOL`
=====================================
compiler/GHC/Parser/Annotation.hs
=====================================
@@ -82,7 +82,8 @@ module GHC.Parser.Annotation (
-- ** Working with comments in annotations
noComments, comment, addCommentsToSrcAnn, setCommentsSrcAnn,
addCommentsToEpAnn, setCommentsEpAnn,
- transferAnnsA, commentsOnlyA, removeCommentsA,
+ transferAnnsA, transferAnnsOnlyA, transferCommentsOnlyA, commentsOnlyA,
+ removeCommentsA,
placeholderRealSpan,
) where
@@ -1154,6 +1155,26 @@ transferAnnsA (SrcSpanAnn (EpAnn a an cs) l) to
(SrcSpanAnn (EpAnn a an' cs') loc)
-> SrcSpanAnn (EpAnn a (an' <> an) (cs' <> cs)) loc
+-- | Transfer trailing items from the annotations in the
+-- first 'SrcSpanAnnA' argument to those in the second.
+transferAnnsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA)
+transferAnnsOnlyA (SrcSpanAnn EpAnnNotUsed l) ss2
+ = (SrcSpanAnn EpAnnNotUsed l, ss2)
+transferAnnsOnlyA (SrcSpanAnn (EpAnn a an cs) l) (SrcSpanAnn EpAnnNotUsed l')
+ = (SrcSpanAnn (EpAnn a mempty cs) l, SrcSpanAnn (EpAnn (spanAsAnchor l') an emptyComments) l')
+transferAnnsOnlyA (SrcSpanAnn (EpAnn a an cs) l) (SrcSpanAnn (EpAnn a' an' cs') l')
+ = (SrcSpanAnn (EpAnn a mempty cs) l, SrcSpanAnn (EpAnn a' (an' <> an) cs') l')
+
+-- | Transfer comments from the annotations in the
+-- first 'SrcSpanAnnA' argument to those in the second.
+transferCommentsOnlyA :: SrcSpanAnnA -> SrcSpanAnnA -> (SrcSpanAnnA, SrcSpanAnnA)
+transferCommentsOnlyA (SrcSpanAnn EpAnnNotUsed l) ss2
+ = (SrcSpanAnn EpAnnNotUsed l, ss2)
+transferCommentsOnlyA (SrcSpanAnn (EpAnn a an cs) l) (SrcSpanAnn EpAnnNotUsed l')
+ = (SrcSpanAnn (EpAnn a an emptyComments ) l, SrcSpanAnn (EpAnn (spanAsAnchor l') mempty cs) l')
+transferCommentsOnlyA (SrcSpanAnn (EpAnn a an cs) l) (SrcSpanAnn (EpAnn a' an' cs') l')
+ = (SrcSpanAnn (EpAnn a an emptyComments) l, SrcSpanAnn (EpAnn a' an' (cs <> cs')) l')
+
-- | Remove the exact print annotations payload, leaving only the
-- anchor and comments.
commentsOnlyA :: Monoid ann => SrcAnn ann -> SrcAnn ann
=====================================
compiler/GHC/Parser/PostProcess.hs
=====================================
@@ -587,11 +587,14 @@ getMonoBind (L loc1 (FunBind { fun_id = fun_id1@(L _ f1)
MG { mg_alts = (L _ m1@[L _ mtchs1]) } }))
binds
| has_args m1
- = go [L (removeCommentsA loc1) mtchs1] (commentsOnlyA loc1) binds []
+ = go [L loc1 mtchs1] (noAnnSrcSpan $ locA loc1) binds []
where
- go :: [LMatch GhcPs (LHsExpr GhcPs)] -> SrcSpanAnnA
- -> [LHsDecl GhcPs] -> [LHsDecl GhcPs]
- -> (LHsBind GhcPs,[LHsDecl GhcPs]) -- AZ
+ -- See Note [Exact Print Annotations for FunBind]
+ go :: [LMatch GhcPs (LHsExpr GhcPs)] -- accumulates matches for current fun
+ -> SrcSpanAnnA -- current top level loc
+ -> [LHsDecl GhcPs] -- Any docbinds seen
+ -> [LHsDecl GhcPs] -- rest of decls to be processed
+ -> (LHsBind GhcPs, [LHsDecl GhcPs]) -- FunBind, rest of decls
go mtchs loc
((L loc2 (ValD _ (FunBind { fun_id = (L _ f2)
, fun_matches =
@@ -605,13 +608,61 @@ getMonoBind (L loc1 (FunBind { fun_id = fun_id1@(L _ f1)
= let doc_decls' = doc_decl : doc_decls
in go mtchs (combineSrcSpansA loc loc2) binds doc_decls'
go mtchs loc binds doc_decls
- = ( L loc (makeFunBind fun_id1 (mkLocatedList $ reverse mtchs))
- , (reverse doc_decls) ++ binds)
+ = let
+ L llm last_m = head mtchs -- Guaranteed at least one
+ (llm',loc') = transferAnnsOnlyA llm loc -- Keep comments, transfer trailing
+
+ matches' = reverse (L llm' last_m:tail mtchs)
+ L lfm first_m = head matches'
+ (lfm', loc'') = transferCommentsOnlyA lfm loc'
+ in
+ ( L loc'' (makeFunBind fun_id1 (mkLocatedList $ (L lfm' first_m:tail matches')))
+ , (reverse doc_decls) ++ binds)
-- Reverse the final matches, to get it back in the right order
-- Do the same thing with the trailing doc comments
getMonoBind bind binds = (bind, binds)
+{- Note [Exact Print Annotations for FunBind]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An individual Match that ends up in a FunBind MatchGroup is initially
+parsed as a LHsDecl. This takes the form
+
+ L loc (ValD NoExtField (FunBind ... [L lm (Match ..)]))
+
+The loc contains the annotations, in particular comments, which are to
+precede the declaration when printed, and [TrailingAnn] which are to
+follow it. The [TrailingAnn] captures semicolons that may appear after
+it when using the braces and semis style of coding.
+
+The match location (lm) has only a location in it at this point, no
+annotations. Its location is the same as the top level location in
+loc.
+
+What getMonoBind does it to take a sequence of FunBind LHsDecls that
+belong to the same function and group them into a single function with
+the component declarations all combined into the single MatchGroup as
+[LMatch GhcPs].
+
+Given that when exact printing a FunBind the exact printer simply
+iterates over all the matches and prints each in turn, the simplest
+behaviour would be to simply take the top level annotations (loc) for
+each declaration, and use them for the individual component matches
+(lm).
+
+The problem is the exact printer first has to deal with the top level
+LHsDecl, which means annotations for the loc. This needs to be able to
+be exact printed in the context of surrounding declarations, and if
+some refactor decides to move the declaration elsewhere, the leading
+comments and trailing semicolons need to be handled at that level.
+
+So the solution is to combine all the matches into one, pushing the
+annotations into the LMatch's, and then at the end extract the
+comments from the first match and [TrailingAnn] from the last to go in
+the top level LHsDecl.
+-}
+
-- Group together adjacent FunBinds for every function.
getMonoBindAll :: [LHsDecl GhcPs] -> [LHsDecl GhcPs]
getMonoBindAll [] = []
=====================================
compiler/GHC/Rename/Env.hs
=====================================
@@ -845,8 +845,10 @@ lookupSubBndrOcc warn_if_deprec the_parent doc rdr_name =
-- See [Mismatched class methods and associated type families]
-- in TcInstDecls.
where
- what_lkup = LookupChild { wantedParent = the_parent
- , lookupDataConFirst = False }
+ what_lkup = LookupChild { wantedParent = the_parent
+ , lookupDataConFirst = False
+ , prioritiseParent = True -- See T23664.
+ }
{-
Note [Family instance binders]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Tc/Gen/Export.hs
=====================================
@@ -690,8 +690,12 @@ lookupChildrenExport spec_parent rdr_items = mapAndReportM doOne rdr_items
let bareName = (ieWrappedName . unLoc) n
what_lkup :: LookupChild
- what_lkup = LookupChild { wantedParent = spec_parent
- , lookupDataConFirst = True }
+ what_lkup =
+ LookupChild
+ { wantedParent = spec_parent
+ , lookupDataConFirst = True
+ , prioritiseParent = False -- See T11970.
+ }
-- Do not report export list declaration deprecations
name <- lookupSubBndrOcc_helper False ExportDeprecationWarnings
=====================================
compiler/GHC/Types/Name/Reader.hs
=====================================
@@ -1190,6 +1190,13 @@ data LookupChild
, lookupDataConFirst :: Bool
-- ^ for type constructors, should we look in the data constructor
-- namespace first?
+ , prioritiseParent :: Bool
+ -- ^ should we prioritise getting the right 'Parent'?
+ --
+ -- - @True@: prioritise getting the right 'Parent'
+ -- - @False@: prioritise getting the right 'NameSpace'
+ --
+ -- See Note [childGREPriority].
}
-- | After looking up something with the given 'NameSpace', is the resulting
@@ -1225,14 +1232,52 @@ greIsRelevant which_gres ns gre
where
other_ns = greNameSpace gre
+{- Note [childGREPriority]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+There are currently two places in the compiler where we look up GlobalRdrElts
+which have a given Parent. These are the two calls to lookupSubBndrOcc_helper:
+
+ A. Looking up children in an export item, e.g.
+
+ module M ( T(MkT, D) ) where { data T = MkT; data D = D }
+
+ B. Looking up binders in a class or instance declaration, e.g.
+ the operator +++ in the fixity declaration:
+
+ class C a where { type (+++) :: a -> a ->; infixl 6 +++ }
+ (+++) :: Int -> Int -> Int; (+++) = (+)
+
+In these two situations, there are two competing metrics for finding the "best"
+'GlobalRdrElt' that a particular 'OccName' resolves to:
+
+ - does the resolved 'GlobalRdrElt' have the correct parent?
+ - does the resolved 'GlobalRdrElt' have the same 'NameSpace' as the 'OccName'?
+
+(A) and (B) have competing requirements.
+
+For the example of (A) above, we know that the child 'D' of 'T' must live
+in the data namespace, so we look up the OccName 'OccName DataName "D"' and
+prioritise the lookup results based on the 'NameSpace'.
+This means we get an error message of the form:
+
+ The type constructor 'T' is not the parent of the data constructor 'D'.
+
+as opposed to the rather unhelpful and confusing:
+
+ The type constructor 'T' is not the parent of the type constructor 'D'.
+
+See test case T11970.
+
+For the example of (B) above, the fixity declaration for +++ lies inside the
+class, so we should prioritise looking up 'GlobalRdrElt's whose parent is 'C'.
+Not doing so led to #23664.
+-}
+
-- | Scoring priority function for looking up children 'GlobalRdrElt'.
--
--- First we score by 'NameSpace', with higher-priority 'NameSpace's having a
--- lower number. Then we break ties by checking if the 'Parent' is correct.
---
--- This complicated scoring function is determined by the behaviour required by
--- 'lookupChildrenExport', which requires us to look in the data constructor
--- 'NameSpace' first, for things in the type constructor 'NameSpace'.
+-- We score by 'Parent' and 'NameSpace', with higher priorities having lower
+-- numbers. Which lexicographic order we use ('Parent' or 'NameSpace' first)
+-- is determined by the first argument; see Note [childGREPriority].
childGREPriority :: LookupChild -- ^ what kind of child do we want,
-- e.g. what should its parent be?
-> NameSpace -- ^ what 'NameSpace' are we originally looking in?
@@ -1241,13 +1286,18 @@ childGREPriority :: LookupChild -- ^ what kind of child do we want,
-- 'NameSpace', which is used to determine the score
-- (in the first component)
-> Maybe (Int, Int)
-childGREPriority (LookupChild { wantedParent = wanted_parent, lookupDataConFirst = try_dc_first })
+childGREPriority (LookupChild { wantedParent = wanted_parent
+ , lookupDataConFirst = try_dc_first
+ , prioritiseParent = par_first })
ns gre =
- case child_ns_prio $ greNameSpace gre of
- Nothing -> Nothing
- Just np -> Just (np, parent_prio $ greParent gre)
- -- Prioritise GREs first on NameSpace, and then on Parent.
- -- See T11970.
+ case child_ns_prio $ greNameSpace gre of
+ Nothing -> Nothing
+ Just ns_prio ->
+ let par_prio = parent_prio $ greParent gre
+ in Just $ if par_first
+ then (par_prio, ns_prio)
+ else (ns_prio, par_prio)
+ -- See Note [childGREPriority].
where
-- Pick out the possible 'NameSpace's in order of priority.
@@ -1302,11 +1352,9 @@ lookupGRE env = \case
lkup | all_ns = concat $ lookupOccEnv_AllNameSpaces env occ
| otherwise = fromMaybe [] $ lookupOccEnv env occ
LookupChildren occ which_child ->
- highestPriorityGREs (childGREPriority which_child ns) $
- concat $ lookupOccEnv_AllNameSpaces env occ
- where
- ns :: NameSpace
- ns = occNameSpace occ
+ let ns = occNameSpace occ
+ all_gres = concat $ lookupOccEnv_AllNameSpaces env occ
+ in highestPriorityGREs (childGREPriority which_child ns) all_gres
-- | Collect the 'GlobalRdrElt's with the highest priority according
-- to the given function (lower value <=> higher priority).
=====================================
compiler/GHC/Types/Unique/DFM.hs
=====================================
@@ -212,13 +212,16 @@ addToUDFM_C f m k v = addToUDFM_C_Directly f m (getUnique k) v
addListToUDFM :: Uniquable key => UniqDFM key elt -> [(key,elt)] -> UniqDFM key elt
addListToUDFM = foldl' (\m (k, v) -> addToUDFM m k v)
+{-# INLINEABLE addListToUDFM #-}
addListToUDFM_Directly :: UniqDFM key elt -> [(Unique,elt)] -> UniqDFM key elt
addListToUDFM_Directly = foldl' (\m (k, v) -> addToUDFM_Directly m k v)
+{-# INLINEABLE addListToUDFM_Directly #-}
addListToUDFM_Directly_C
:: (elt -> elt -> elt) -> UniqDFM key elt -> [(Unique,elt)] -> UniqDFM key elt
addListToUDFM_Directly_C f = foldl' (\m (k, v) -> addToUDFM_C_Directly f m k v)
+{-# INLINEABLE addListToUDFM_Directly_C #-}
delFromUDFM :: Uniquable key => UniqDFM key elt -> key -> UniqDFM key elt
delFromUDFM (UDFM m i) k = UDFM (M.delete (getKey $ getUnique k) m) i
=====================================
compiler/GHC/Types/Unique/FM.hs
=====================================
@@ -139,9 +139,11 @@ zipToUFM ks vs = assert (length ks == length vs ) innerZip emptyUFM ks vs
listToUFM :: Uniquable key => [(key,elt)] -> UniqFM key elt
listToUFM = foldl' (\m (k, v) -> addToUFM m k v) emptyUFM
+{-# INLINEABLE listToUFM #-}
listToUFM_Directly :: [(Unique, elt)] -> UniqFM key elt
listToUFM_Directly = foldl' (\m (u, v) -> addToUFM_Directly m u v) emptyUFM
+{-# INLINEABLE listToUFM_Directly #-}
listToIdentityUFM :: Uniquable key => [key] -> UniqFM key key
listToIdentityUFM = foldl' (\m x -> addToUFM m x x) emptyUFM
@@ -152,6 +154,7 @@ listToUFM_C
-> [(key, elt)]
-> UniqFM key elt
listToUFM_C f = foldl' (\m (k, v) -> addToUFM_C f m k v) emptyUFM
+{-# INLINEABLE listToUFM_C #-}
addToUFM :: Uniquable key => UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM (UFM m) k v = UFM (M.insert (getKey $ getUnique k) v m)
=====================================
compiler/GHC/Types/Unique/Set.hs
=====================================
@@ -74,12 +74,14 @@ unitUniqSet x = UniqSet $ unitUFM x x
mkUniqSet :: Uniquable a => [a] -> UniqSet a
mkUniqSet = foldl' addOneToUniqSet emptyUniqSet
+{-# INLINEABLE mkUniqSet #-}
addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
addOneToUniqSet (UniqSet set) x = UniqSet (addToUFM set x x)
addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet = foldl' addOneToUniqSet
+{-# INLINEABLE addListToUniqSet #-}
delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
delOneFromUniqSet (UniqSet s) a = UniqSet (delFromUFM s a)
@@ -89,10 +91,12 @@ delOneFromUniqSet_Directly (UniqSet s) u = UniqSet (delFromUFM_Directly s u)
delListFromUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
delListFromUniqSet (UniqSet s) l = UniqSet (delListFromUFM s l)
+{-# INLINEABLE delListFromUniqSet #-}
delListFromUniqSet_Directly :: UniqSet a -> [Unique] -> UniqSet a
delListFromUniqSet_Directly (UniqSet s) l =
UniqSet (delListFromUFM_Directly s l)
+{-# INLINEABLE delListFromUniqSet_Directly #-}
unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
unionUniqSets (UniqSet s) (UniqSet t) = UniqSet (plusUFM s t)
=====================================
docs/users_guide/9.10.1-notes.rst
=====================================
@@ -0,0 +1,75 @@
+.. _release-9-10-1:
+
+Version 9.10.1
+==============
+
+Language
+~~~~~~~~
+
+Compiler
+~~~~~~~~
+
+GHCi
+~~~~
+
+Runtime system
+~~~~~~~~~~~~~~
+
+``base`` library
+~~~~~~~~~~~~~~~~
+
+``ghc-prim`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``ghc`` library
+~~~~~~~~~~~~~~~
+
+``ghc-heap`` library
+~~~~~~~~~~~~~~~~~~~~
+
+``template-haskell`` library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Included libraries
+~~~~~~~~~~~~~~~~~~
+
+The package database provided with this distribution also contains a number of
+packages other than GHC itself. See the changelogs provided with these packages
+for further change information.
+
+.. ghc-package-list::
+
+ libraries/array/array.cabal: Dependency of ``ghc`` library
+ libraries/base/base.cabal: Core library
+ libraries/binary/binary.cabal: Dependency of ``ghc`` library
+ libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library
+ libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility
+ libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility
+ libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library
+ libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library
+ libraries/directory/directory.cabal: Dependency of ``ghc`` library
+ libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library
+ libraries/filepath/filepath.cabal: Dependency of ``ghc`` library
+ compiler/ghc.cabal: The compiler itself
+ libraries/ghci/ghci.cabal: The REPL interface
+ libraries/ghc-boot/ghc-boot.cabal: Internal compiler library
+ libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library
+ libraries/ghc-compact/ghc-compact.cabal: Core library
+ libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library
+ libraries/ghc-prim/ghc-prim.cabal: Core library
+ libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable
+ libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable
+ libraries/integer-gmp/integer-gmp.cabal: Core library
+ libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library
+ libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library
+ libraries/pretty/pretty.cabal: Dependency of ``ghc`` library
+ libraries/process/process.cabal: Dependency of ``ghc`` library
+ libraries/stm/stm.cabal: Dependency of ``haskeline`` library
+ libraries/template-haskell/template-haskell.cabal: Core library
+ libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library
+ libraries/text/text.cabal: Dependency of ``Cabal`` library
+ libraries/time/time.cabal: Dependency of ``ghc`` library
+ libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
+ libraries/unix/unix.cabal: Dependency of ``ghc`` library
+ libraries/Win32/Win32.cabal: Dependency of ``ghc`` library
+ libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable
=====================================
docs/users_guide/release-notes.rst
=====================================
@@ -4,4 +4,4 @@ Release notes
.. toctree::
:maxdepth: 1
- 9.8.1-notes
+ 9.10.1-notes
=====================================
testsuite/tests/codeGen/should_run/MulMayOflo.hs
=====================================
@@ -0,0 +1,26 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+
+{-
+ N.B. the contract of '%mulmayoflo' is a bit weak: "Return non-zero if there is
+ any possibility that the signed multiply of a and b might overflow. Return zero
+ only if you are absolutely sure that it won't overflow. If in doubt, return
+ non-zero." (Stg.h)
+
+This test verifies the a stronger contract: It's expected that there are no
+false positives. This requirement is e.g. met by code generation backends which
+execute the multiplication to check for overflow.
+-}
+
+module Main where
+
+import GHC.Exts
+
+-- The argument and return types are unimportant: They're only used to force
+-- evaluation, but carry no information.
+foreign import prim "runCmmzh" runCmmzh# :: Word# -> Word#
+
+main :: IO ()
+main = print . show $ W# (runCmmzh# 42##)
=====================================
testsuite/tests/codeGen/should_run/MulMayOflo_full.cmm
=====================================
@@ -0,0 +1,98 @@
+// Suppress empty ASSERT() optimization
+#define USE_ASSERTS_ALL_WAYS 1
+
+#include "Cmm.h"
+#include "MachDeps.h"
+
+runCmmzh() {
+// BEWARE: Cmm isn't really type checked. I.e. you may construct
+// 256::I8, which is obviously wrong and let's to strange behaviour.
+
+ // --- I8
+ ASSERT(%mulmayoflo(64::I8, 2::I8) > 0::I8);
+ ASSERT(%mulmayoflo(2::I8, 64::I8) > 0::I8);
+ ASSERT(%mulmayoflo(-65::I8, 2::I8) > 0::I8);
+ ASSERT(%mulmayoflo(2::I8, -65::I8) > 0::I8);
+
+ // --- I16
+ ASSERT(%mulmayoflo(16384::I16, 2::I16) > 0::I16);
+ ASSERT(%mulmayoflo(2::I16, 16384::I16) > 0::I16);
+ ASSERT(%mulmayoflo(-16385::I16, 2::I16) > 0::I16);
+ ASSERT(%mulmayoflo(2::I16, -16385::I16) > 0::I16);
+
+
+ // -- I32
+ ASSERT(%mulmayoflo(2::I32, 1073741824::I32) > 0::I32);
+ ASSERT(%mulmayoflo(1073741824::I32, 2::I32) > 0::I32);
+ ASSERT(%mulmayoflo(2::I32, -1073741825::I32) > 0::I32);
+ ASSERT(%mulmayoflo(-1073741825::I32, 2::I32) > 0::I32);
+
+#if WORD_SIZE_IN_BITS >= 64
+ // -- I64
+ ASSERT(%mulmayoflo(4611686018427387904::I64, 2::I64) > 0::I64);
+ ASSERT(%mulmayoflo(2::I64, 4611686018427387904::I64) > 0::I64);
+ ASSERT(%mulmayoflo(-4611686018427387905::I64, 2::I64) > 0::I64);
+ ASSERT(%mulmayoflo(2::I64, -4611686018427387905::I64) > 0::I64);
+#endif
+
+ // --- I8
+ ASSERT(%mulmayoflo(1::I8, 1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(0::I8, 0::I8) == 0::I8);
+ ASSERT(%mulmayoflo(-1::I8, 1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(1::I8, -1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(127::I8, 1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(1::I8, 127::I8) == 0::I8);
+ ASSERT(%mulmayoflo(63::I8, 2::I8) == 0::I8);
+ ASSERT(%mulmayoflo(2::I8, 63::I8) == 0::I8);
+ ASSERT(%mulmayoflo(127::I8, -1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(-1::I8, 127::I8) == 0::I8);
+ ASSERT(%mulmayoflo(-128::I8, 1::I8) == 0::I8);
+ ASSERT(%mulmayoflo(-64::I8, 2::I8) == 0::I8);
+ ASSERT(%mulmayoflo(2::I8, -64::I8) == 0::I8);
+
+ // --- I16
+ ASSERT(%mulmayoflo(1::I16, 1::I16) == 0::I16);
+ ASSERT(%mulmayoflo(0::I16, 0::I16) == 0::I16);
+ ASSERT(%mulmayoflo(-1::I16, 1::I16) == 0::I16);
+ ASSERT(%mulmayoflo(1::I16, -1::I16) == 0::I16);
+ ASSERT(%mulmayoflo(32767::I16, 1::I16) == 0::I16);
+ ASSERT(%mulmayoflo(1::I16,32767 ::I16) == 0::I16);
+ ASSERT(%mulmayoflo(16383::I16, 2::I16) == 0::I16);
+ ASSERT(%mulmayoflo(2::I16, 16383::I16) == 0::I16);
+ ASSERT(%mulmayoflo(-16384::I16, 2::I16) == 0::I16);
+ ASSERT(%mulmayoflo(2::I16, -16384::I16) == 0::I16);
+ ASSERT(%mulmayoflo(-32768::I16, 1::I16) == 0::I16);
+ ASSERT(%mulmayoflo(1::I16, -32768::I16) == 0::I16);
+
+ // -- I32
+ ASSERT(%mulmayoflo(1::I32, 1::I32) == 0::I32);
+ ASSERT(%mulmayoflo(0::I32, 0::I32) == 0::I32);
+ ASSERT(%mulmayoflo(-1::I32, 1::I32) == 0::I32);
+ ASSERT(%mulmayoflo(1::I32, -1::I32) == 0::I32);
+ ASSERT(%mulmayoflo(2147483647::I32, 1::I32) == 0::I32);
+ ASSERT(%mulmayoflo(1::I32, 2147483647::I32) == 0::I32);
+ ASSERT(%mulmayoflo(-2147483648::I32, 1::I32) == 0::I32);
+ ASSERT(%mulmayoflo(1::I32, -2147483648::I32) == 0::I32);
+ ASSERT(%mulmayoflo(2::I32, 1073741823::I32) == 0::I32);
+ ASSERT(%mulmayoflo(1073741823::I32, 2::I32) == 0::I32);
+ ASSERT(%mulmayoflo(2::I32, -1073741824::I32) == 0::I32);
+ ASSERT(%mulmayoflo(-1073741824::I32, 2::I32) == 0::I32);
+
+#if WORD_SIZE_IN_BITS >= 64
+ // -- I64
+ ASSERT(%mulmayoflo(1::I64, 1::I64) == 0::I64);
+ ASSERT(%mulmayoflo(0::I64, 0::I64) == 0::I64);
+ ASSERT(%mulmayoflo(-1::I64, 1::I64) == 0::I64);
+ ASSERT(%mulmayoflo(1::I64, -1::I64) == 0::I64);
+ ASSERT(%mulmayoflo(9223372036854775807::I64, 1::I64) == 0::I64);
+ ASSERT(%mulmayoflo(1::I64, 9223372036854775807::I64) == 0::I64);
+ ASSERT(%mulmayoflo(-9223372036854775808::I64, 1::I64) == 0::I64);
+ ASSERT(%mulmayoflo(1::I64, -9223372036854775808::I64) == 0::I64);
+ ASSERT(%mulmayoflo(4611686018427387903::I64, 2::I64) == 0::I64);
+ ASSERT(%mulmayoflo(2::I64, 4611686018427387903::I64) == 0::I64);
+ ASSERT(%mulmayoflo(-4611686018427387904::I64, 2::I64) == 0::I64);
+ ASSERT(%mulmayoflo(2::I64, -4611686018427387904::I64) == 0::I64);
+#endif
+
+ return(0);
+}
=====================================
testsuite/tests/codeGen/should_run/all.T
=====================================
@@ -226,3 +226,14 @@ test('T22296',[only_ways(llvm_ways)
test('T22798', normal, compile_and_run, ['-fregs-graph'])
test('CheckBoundsOK', normal, compile_and_run, ['-fcheck-prim-bounds'])
test('OrigThunkInfo', normal, compile_and_run, ['-forig-thunk-info'])
+
+# TODO: Enable more architectures here. N.B. some code generation backends are
+# not implemeted correctly (according to
+# Note [MO_S_MulMayOflo significant width]) and may require fixing/adjustment.
+test('MulMayOflo_full',
+ [ extra_files(['MulMayOflo.hs']),
+ when(unregisterised(), skip),
+ unless(arch('x86_64') or arch('i386'), skip),
+ ignore_stdout],
+ multi_compile_and_run,
+ ['MulMayOflo', [('MulMayOflo_full.cmm', '')], ''])
=====================================
testsuite/tests/parser/should_compile/DumpSemis.stderr
=====================================
@@ -1349,7 +1349,12 @@
{ DumpSemis.hs:32:1-7 }
(UnchangedAnchor))
(AnnListItem
- [])
+ [(AddSemiAnn
+ (EpaSpan { DumpSemis.hs:33:1 }))
+ ,(AddSemiAnn
+ (EpaSpan { DumpSemis.hs:34:6 }))
+ ,(AddSemiAnn
+ (EpaSpan { DumpSemis.hs:34:7 }))])
(EpaComments
[])) { DumpSemis.hs:32:1-7 })
(ValD
@@ -1370,12 +1375,7 @@
{ DumpSemis.hs:32:1-7 }
(UnchangedAnchor))
(AnnListItem
- [(AddSemiAnn
- (EpaSpan { DumpSemis.hs:33:1 }))
- ,(AddSemiAnn
- (EpaSpan { DumpSemis.hs:34:6 }))
- ,(AddSemiAnn
- (EpaSpan { DumpSemis.hs:34:7 }))])
+ [])
(EpaComments
[])) { DumpSemis.hs:32:1-7 })
(Match
@@ -1707,7 +1707,8 @@
{ DumpSemis.hs:(36,1)-(44,4) }
(UnchangedAnchor))
(AnnListItem
- [])
+ [(AddSemiAnn
+ (EpaSpan { DumpSemis.hs:45:1 }))])
(EpaComments
[])) { DumpSemis.hs:(36,1)-(44,4) })
(ValD
@@ -1728,8 +1729,7 @@
{ DumpSemis.hs:(36,1)-(44,4) }
(UnchangedAnchor))
(AnnListItem
- [(AddSemiAnn
- (EpaSpan { DumpSemis.hs:45:1 }))])
+ [])
(EpaComments
[])) { DumpSemis.hs:(36,1)-(44,4) })
(Match
@@ -2100,5 +2100,3 @@
(NoExtField)))))]))))))]
(EmptyLocalBinds
(NoExtField)))))])))))]))
-
-
=====================================
testsuite/tests/printer/Test19784.hs
=====================================
@@ -2,4 +2,9 @@ module Test19784 where
{
a 0 = 1;
a _ = 2;
+
+-- c0
+b 0 = 1; -- c1
+b 1 = 2; -- c2
+b 2 = 3; -- c3
}
=====================================
testsuite/tests/rename/should_compile/T23664.hs
=====================================
@@ -0,0 +1,7 @@
+{-# LANGUAGE TypeFamilies, TypeOperators #-}
+
+module T23664 where
+
+class POrd a where
+ type a >= b
+ infix 4 >=
=====================================
testsuite/tests/rename/should_compile/all.T
=====================================
@@ -214,6 +214,7 @@ test('T23318', normal, compile, ['-Wduplicate-exports'])
test('T23434', normal, compile, [''])
test('T23510b', normal, compile, [''])
test('T23512b', normal, compile, [''])
+test('T23664', normal, compile, [''])
test('ExportWarnings1', extra_files(['ExportWarnings_base.hs', 'ExportWarnings_aux.hs']), multimod_compile, ['ExportWarnings1', '-v0 -Wno-duplicate-exports -Wx-custom'])
test('ExportWarnings2', extra_files(['ExportWarnings_base.hs', 'ExportWarnings_aux.hs', 'ExportWarnings_aux2.hs']), multimod_compile, ['ExportWarnings2', '-v0 -Wno-duplicate-exports -Wx-custom'])
test('ExportWarnings3', extra_files(['ExportWarnings_base.hs', 'ExportWarnings_aux.hs']), multimod_compile, ['ExportWarnings3', '-v0 -Wno-duplicate-exports -Wx-custom'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3195da2d9794489becd627ccc5f4f6160d97cd7b...3ecd4722b61410ef5e02cabedda25bed5e4c9939
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3195da2d9794489becd627ccc5f4f6160d97cd7b...3ecd4722b61410ef5e02cabedda25bed5e4c9939
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/20230718/019ef280/attachment-0001.html>
More information about the ghc-commits
mailing list