15 Jun '26
Rodrigo Mesquita pushed to branch wip/fix-26953 at Glasgow Haskell Compiler / GHC
Commits:
0a0f4ccc by Rodrigo Mesquita at 2026-06-15T15:46:57+01:00
drop rebase artifact
- - - - -
9 changed files:
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Linker/Unit.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Misc.hs
Changes:
=====================================
compiler/GHC/CmmToAsm/BlockLayout.hs
=====================================
@@ -36,6 +36,7 @@ import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Utils.Misc
+import Data.Containers.ListUtils (nubOrd)
import Data.List (sortOn, sortBy, nub)
import Data.List.NonEmpty (nonEmpty)
import qualified Data.List.NonEmpty as NE
@@ -426,7 +427,7 @@ combineNeighbourhood edges chains
applyEdges :: [CfgEdge] -> FrontierMap -> FrontierMap -> Set.Set (BlockId, BlockId)
-> ([BlockChain], Set.Set (BlockId,BlockId))
applyEdges [] chainEnds _chainFronts combined =
- (ordNub $ map snd $ mapElems chainEnds, combined)
+ (nubOrd $ map snd $ mapElems chainEnds, combined)
applyEdges ((CfgEdge from to _w):edges) chainEnds chainFronts combined
| Just (c1_e,c1) <- mapLookup from chainEnds
, Just (c2_f,c2) <- mapLookup to chainFronts
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -76,6 +76,7 @@ import GHC.Data.FastString
import qualified GHC.Data.EnumSet as EnumSet
import qualified GHC.Data.ShortText as ST
+import Data.Containers.ListUtils (nubOrd)
import Data.List ( partition )
import System.Exit
import Control.Monad
@@ -763,14 +764,14 @@ hsunitModuleGraph do_link unit = do
let inodes = instantiationNodes (homeUnitId $ hsc_home_unit hsc_env) (hsc_units hsc_env)
-- TODO: Backpack mode does not properly support ExternalPackage nodes yet
-- Module nodes do not get given package dependencies (see hsModuleToModSummary).
- let pkg_nodes = ordNub $ map (\(_, iud) -> UnitNode [] (instUnitInstanceOf iud)) inodes
+ let pkg_nodes = nubOrd $ map (\(_, iud) -> UnitNode [] (instUnitInstanceOf iud)) inodes
let graph_nodes = nodes ++ req_nodes ++ (map (uncurry InstantiationNode) $ inodes) ++ pkg_nodes
key_nodes = map mkNodeKey graph_nodes
all_nodes = graph_nodes ++ [LinkNode key_nodes (homeUnitId $ hsc_home_unit hsc_env) | do_link]
-- This error message is not very good but .bkp mode is just for testing so
-- better to be direct rather than pretty.
when
- (length key_nodes /= length (ordNub key_nodes))
+ (length key_nodes /= length (nubOrd key_nodes))
(pprPanic "Duplicate nodes keys in backpack file" (ppr key_nodes))
-- 3. Return the kaboodle
=====================================
compiler/GHC/Driver/Session/Units.hs
=====================================
@@ -25,7 +25,6 @@ import qualified GHC.Unit.State as State
import GHC.Types.SrcLoc
import GHC.Types.SourceError
-import GHC.Utils.Misc
import GHC.Utils.Panic
import GHC.Utils.Outputable as Outputable
import GHC.Utils.Monad ( liftIO, mapMaybeM )
@@ -35,6 +34,7 @@ import System.IO
import System.Exit
import System.FilePath
import Control.Monad
+import Data.Containers.ListUtils (nubOrdOn)
import Data.List ( partition, (\\) )
import qualified Data.Set as Set
import GHC.Prelude
@@ -204,7 +204,7 @@ checkDuplicateUnits dflags flags =
where
uids = map (second homeUnitId_) flags
- deduplicated_uids = ordNubOn snd uids
+ deduplicated_uids = nubOrdOn snd uids
duplicate_ids = Set.fromList (map snd uids \\ map snd deduplicated_uids)
duplicate_flags = filter (flip Set.member duplicate_ids . snd) uids
=====================================
compiler/GHC/HsToCore/Usage.hs
=====================================
@@ -32,6 +32,7 @@ import GHC.Unit.Module.Deps
import GHC.Data.Maybe
import GHC.Data.FastString
+import Data.Containers.ListUtils (nubOrdOn)
import Data.List (sortBy)
import Data.Map (Map)
import qualified Data.Map as Map
@@ -180,7 +181,7 @@ the TH splice.
-- modules and direct object files for pkg dependencies
mkObjectUsage :: Plugins -> FinderCache -> [LinkableUsage] -> PkgsLoaded -> IO [Usage]
mkObjectUsage plugins fc th_links_needed th_pkgs_needed = do
- let ls = ordNubOn linkableModule (th_links_needed ++ plugins_links_needed)
+ let ls = nubOrdOn linkableModule (th_links_needed ++ plugins_links_needed)
ds = concatMap loaded_pkg_hs_objs $ eltsUDFM (plusUDFM th_pkgs_needed plugin_pkgs_needed) -- TODO possibly record loaded_pkg_non_hs_objs as well
(plugins_links_needed, plugin_pkgs_needed) = loadedPluginDeps plugins
concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
=====================================
compiler/GHC/Linker/Unit.hs
=====================================
@@ -25,6 +25,7 @@ import qualified GHC.Data.ShortText as ST
import GHC.Settings
import Control.Monad
+import Data.Containers.ListUtils (nubOrd)
import Data.List (nub)
import Data.Semigroup ( Semigroup(..) )
import System.Directory
@@ -95,7 +96,7 @@ collectArchives namever ways pc =
filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a")
| searchPath <- searchPaths
, lib <- libs ]
- where searchPaths = ordNub . filter notNull . libraryDirsForWay ways $ pc
+ where searchPaths = nubOrd . filter notNull . libraryDirsForWay ways $ pc
libs = unitHsLibs namever ways pc ++ (map ST.unpack . unitExtDepLibsStaticSys $ pc)
getLibs :: GhcNameVersion -> Ways -> UnitEnv -> [UnitId] -> IO [(String,String)]
=====================================
compiler/GHC/Rename/Pat.hs
=====================================
@@ -78,6 +78,7 @@ import GHC.Core.TyCon ( isKindName )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad ( when, ap, guard, unless )
+import Data.Containers.ListUtils (nubOrdOn)
import Data.Foldable
import Data.Function ( on )
import Data.Functor.Identity ( Identity (..) )
@@ -666,7 +667,7 @@ rnPatAndThen mk (OrPat _ pats)
; pats' <- rnLPatsAndThen mk pats
; let bndrs = collectPatsBinders CollVarTyVarBinders (NE.toList pats')
; liftCps $ setSrcSpan loc $ checkErr (null bndrs) $
- TcRnOrPatBindsVariables (NE.fromList (ordNubOn getOccName bndrs))
+ TcRnOrPatBindsVariables (NE.fromList (nubOrdOn getOccName bndrs))
; return (OrPat noExtField pats') }
rnPatAndThen mk (SumPat _ pat alt arity)
=====================================
compiler/GHC/Unit/Info.hs
=====================================
@@ -49,6 +49,7 @@ import GHC.Unit.Database
import GHC.Settings
+import Data.Containers.ListUtils (nubOrd)
import Data.Version
import Data.Bifunctor
import Data.List (isPrefixOf, stripPrefix)
@@ -185,7 +186,7 @@ mkUnitPprInfo ufs i = UnitPprInfo
-- | Find all the include directories in the given units
collectIncludeDirs :: [UnitInfo] -> [FilePath]
-collectIncludeDirs ps = map ST.unpack $ ordNub (filter (not . ST.null) (concatMap unitIncludeDirs ps))
+collectIncludeDirs ps = map ST.unpack $ nubOrd (filter (not . ST.null) (concatMap unitIncludeDirs ps))
-- | Find all the C-compiler options in the given units
collectExtraCcOpts :: [UnitInfo] -> [String]
@@ -193,7 +194,7 @@ collectExtraCcOpts ps = map ST.unpack (concatMap unitCcOptions ps)
-- | Find all the library directories in the given units for the given ways
collectLibraryDirs :: Ways -> [UnitInfo] -> [FilePath]
-collectLibraryDirs ws = ordNub . filter notNull . concatMap (libraryDirsForWay ws)
+collectLibraryDirs ws = nubOrd . filter notNull . concatMap (libraryDirsForWay ws)
-- | Find all the frameworks in the given units
collectFrameworks :: [UnitInfo] -> [String]
@@ -201,7 +202,7 @@ collectFrameworks ps = map ST.unpack (concatMap unitExtDepFrameworks ps)
-- | Find all the package framework paths in these and the preload packages
collectFrameworksDirs :: [UnitInfo] -> [String]
-collectFrameworksDirs ps = map ST.unpack (ordNub (filter (not . ST.null) (concatMap unitExtDepFrameworkDirs ps)))
+collectFrameworksDirs ps = map ST.unpack (nubOrd (filter (not . ST.null) (concatMap unitExtDepFrameworkDirs ps)))
-- | Either the 'unitLibraryDirs' or 'unitLibraryDynDirs' as appropriate for the way.
libraryDirsForWay :: Ways -> UnitInfo -> [String]
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -112,6 +112,7 @@ import GHC.Utils.Exception
import System.Directory
import System.FilePath as FilePath
import Control.Monad
+import Data.Containers.ListUtils (nubOrd)
import Data.Graph (stronglyConnComp, SCC(..))
import Data.Char ( toUpper )
import Data.List ( intersperse, partition, sortBy, sortOn, sort )
@@ -1705,7 +1706,7 @@ mkUnitState logger cfg = do
basicLinkedUnits = fmap (RealUnit . Definite)
$ filter (flip elemUniqMap pkg_db)
$ unitConfigAutoLink cfg
- preload3 = ordNub $ (basicLinkedUnits ++ preload1)
+ preload3 = nubOrd $ (basicLinkedUnits ++ preload1)
-- Close the preload packages with their dependencies
dep_preload <- mayThrowUnitErr
=====================================
compiler/GHC/Utils/Misc.hs
=====================================
@@ -59,7 +59,7 @@ module GHC.Utils.Misc (
replaceAt, dropTail, capitalise,
-- * Sorting
- sortWith, minWith, nubSort, ordNub, ordNubOn,
+ sortWith, minWith, nubSort,
-- * Comparisons
isEqual,
@@ -570,23 +570,6 @@ minWith get_key xs = assert (not (null xs) )
nubSort :: Ord a => [a] -> [a]
nubSort = Set.toAscList . Set.fromList
--- | Remove duplicates but keep elements in order.
--- O(n * log n)
-ordNub :: Ord a => [a] -> [a]
-ordNub xs = ordNubOn id xs
-
--- | Remove duplicates but keep elements in order.
--- O(n * log n)
-ordNubOn :: Ord b => (a -> b) -> [a] -> [a]
-ordNubOn f xs
- = go Set.empty xs
- where
- go _ [] = []
- go s (x:xs)
- | Set.member (f x) s = go s xs
- | otherwise = x : go (Set.insert (f x) s) xs
-
-
{-
************************************************************************
* *
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a0f4ccca3e106384c3a78db8204ebd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0a0f4ccca3e106384c3a78db8204ebd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/ani/T27156] 9 commits: Hadrian: avoid response files when command line is short enough
by Apoorv Ingle (@ani) 15 Jun '26
by Apoorv Ingle (@ani) 15 Jun '26
15 Jun '26
Apoorv Ingle pushed to branch wip/ani/T27156 at Glasgow Haskell Compiler / GHC
Commits:
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
333df444 by sheaf at 2026-06-10T05:10:25-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
98c20394 by sheaf at 2026-06-10T05:11:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
089e9187 by Apoorv Ingle at 2026-06-10T21:12:02-05:00
Work on #27156
- Add `RebindableSyntaxTable` to store function/operator names while renaming in the XBlah fields
- Expand the following expressions right before typechecking instead of in the renamer
* OverloadedLabel
* RecordDotSyntax: HsGetField and HsProjection
* ExplicitList
* RecordUpd
* HsIf
* HsDo (Vanilla cases)
- - - - -
8aac933c by Apoorv Ingle at 2026-06-15T00:04:47-05:00
update notes
- - - - -
49 changed files:
- + changelog.d/T27156
- + changelog.d/T27225
- + changelog.d/T27317
- + changelog.d/T27359
- changelog.d/hadrian-response-files.md
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Expand.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Utils/Logger.hs
- docs/users_guide/using.rst
- hadrian/build-cabal
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/ghc-api/T25121_status.stdout
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail9.stderr
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- testsuite/tests/rebindable/T19918.stdout
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/th/T18102b.stdout
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89ab658e1487762c08277a97f0b682…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/89ab658e1487762c08277a97f0b682…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
15 Jun '26
Magnus pushed new branch wip/mangoiv/add-more-hlint-ignore at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mangoiv/add-more-hlint-ignore
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/davide/ghc-internal-def] Hadrian: fix ghc-internal .def file name
by David Eichmann (@DavidEichmann) 15 Jun '26
by David Eichmann (@DavidEichmann) 15 Jun '26
15 Jun '26
David Eichmann pushed to branch wip/davide/ghc-internal-def at Glasgow Haskell Compiler / GHC
Commits:
677c9d7a by David Eichmann at 2026-06-15T14:08:18+01:00
Hadrian: fix ghc-internal .def file name
- - - - -
1 changed file:
- hadrian/src/Rules/Rts.hs
Changes:
=====================================
hadrian/src/Rules/Rts.hs
=====================================
@@ -25,7 +25,7 @@ buildGhcInternalImportDef target = do
buildGhcInternalImportLib :: FilePath -> Action ()
buildGhcInternalImportLib target = do
- let input = dropExtensions target <.> "def" -- the .def file
+ let input = dropExtension (dropExtension target) <.> "def" -- the .def file
output = target -- the .dll.a import lib
need [input]
runBuilder Dlltool ["-d", input, "-l", output] [input] [output]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/677c9d7ab6ca073ef6ef8381478e35d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/677c9d7ab6ca073ef6ef8381478e35d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/davide/ghc-internal-def] 48 commits: Fixes for black holes
by David Eichmann (@DavidEichmann) 15 Jun '26
by David Eichmann (@DavidEichmann) 15 Jun '26
15 Jun '26
David Eichmann pushed to branch wip/davide/ghc-internal-def at Glasgow Haskell Compiler / GHC
Commits:
63ce5770 by Luite Stegeman at 2026-05-28T12:23:35-04:00
Fixes for black holes
- suspend duplicate work for eager black holes
- detect eager black holes in checkBlockingQueues
- don't overwrite existing black holes even if they're not
in an eager blackhole frame
- don't deadlock on self when thunk is already blackholed
Fixes #26936
- - - - -
037a80dc by Tom McLaughlin at 2026-05-28T12:24:36-04:00
Event/Windows.hsc: rethrow exceptions in overlapped IO
This prevents the WinIO manager from swallowing exceptions in overlapped IO. It
was added to make WinIO support possible in the `network` library. See
https://gitlab.haskell.org/ghc/ghc/-/issues/27283.
We also bump __IO_MANAGER_WINIO__ to 2 so libraries can gate on this using CPP.
- - - - -
2d53bcdb by Wolfgang Jeltsch at 2026-05-28T12:25:21-04:00
Allow `downsweep` to use nodes of an existing module graph
To this end, `downsweep` has not been able to use the nodes of a module
graph obtained from a previous downsweeping round. In some GHC API
applications, downsweeping is performed somewhat incrementally and
therefore could profit from reusing such existing results. This
contribution makes this possible.
Resolves #27054.
Co-authored-by: Matthew Pickering <matthewtpickering(a)gmail.com>
- - - - -
f4fbb583 by Simon Jakobi at 2026-05-28T12:26:04-04:00
Add regression test for T11226
Closes #11226.
- - - - -
ed29a5e6 by Sven Tennie at 2026-05-28T17:30:36-04:00
Add optional config setting for LibDir (#19174)
Previously, the `libDir` was derived from `topDir`. This won't work for
inplace stage2 cross-compilers where binaries and libraries are in
different stage dirs (`_build/stage1/` for executables and
`_build/stage2` for libraries).
`LibDir` is set in the inplace `settings` files. For bindists, we
generate a new `settings` file with no `LibDir` entry. GHC then defaults
to use `topDir` as `libDir` again. This keeps the bindist relocatable.
If `LibDir` is a relative path, it is interpreted relatively to
`topDir`.
The global package db is part of the `lib/` folder. If we want to point
for inplace cross-compilers to the succeeding stage's folder, this is
done by setting `LibDir`. Thus, the global package db must be found
relative to `libDir`` (which may default to `topDir` or be set by
`LibDir`).
The complexity of settings becomes scary. So, add a test to ensure
`LibDir` works as expected.
- - - - -
8339cf8f by Sven Tennie at 2026-05-28T17:30:36-04:00
Add Haddock to FileSettings
Helping to understand the fields' meanings without deeper analyses.
- - - - -
4ce251e4 by Sylvain Henry at 2026-05-28T17:31:39-04:00
foundation test: skip signed minBound `quot` (-1) (#27222)
`minBound `quot` (-1)` for fixed-width signed integers is platform
dependent: the mathematical result -minBound is not representable in
the type. On x86, IDIV traps; LLVM's sdiv is undefined behaviour in
this case; on AArch64/RISC-V, SDIV wraps to minBound.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
b8ba7e61 by Simon Jakobi at 2026-05-28T17:32:23-04:00
Prevent dictionary-passing in checkTyEqRhs
...by pre-specializing it to TcM.
Previously, wherever checkTyEqRhs was used in other modules, the
Core showed dictionary passing ($fMonadIOEnv). The added SPECIALIZE
pragma prevents this.
- - - - -
d603477f by David Eichmann at 2026-05-29T13:17:12-04:00
Hadrian: create a ghc-internal .def file per ghc-internal dll
The .def file generated from rts/win32/libHSghc-internal.def.in contains
the name of the ghc-internal dll. The correct dll name differs based
on if the dll is inplace/final and if using the Dynamic way. Previously,
this was not accounted for and inconsistent dlls names where used. That
led to failure when loading dlls at runtime in experiments with windows
dynamic linking.
- - - - -
1fc21753 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: copy backend interface haddocks to Native backend (#27305)
The haddock comments documenting the BigNat backend interface (function
contracts, expected MutableWordArray# sizes, return-value semantics, etc.)
were attached to the FFI backend module. Copy them to the Native backend
so they remain in tree once the FFI backend is removed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
717059df by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove FFI backend (#27305)
The FFI backend of ghc-bignum (now part of ghc-internal) had no known
users and is easy to recreate by relinking ghc-internal with a custom
backend. Remove the backend module, the bignum-ffi cabal flag, and the
ffi option from Hadrian's --bignum selector. The backend interface
documentation now lives in the Native backend module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
4bb3b1d8 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove Check backend (#27305)
The Check backend of ghc-bignum (now part of ghc-internal) compared the
selected backend's output against the Native backend for validation.
It had no known users. Remove the backend module, the bignum-check
cabal flag, the bignumCheck Hadrian flavour field, and the check-
prefix in Hadrian's --bignum selector.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
6b3044a0 by David Eichmann at 2026-05-30T11:58:48-04:00
Add code comments to allocator code
- - - - -
f4e04210 by Matthew Pickering at 2026-05-30T11:59:34-04:00
hadrian: Refactor system-cxx-std-lib rules
I noticed a few things wrong with the hadrian rules for
`system-cxx-std-lib` rules.
* For `text` there is an ad-hoc check to depend on `system-cxx-std-lib`
outside of `configurePackage`.
* The `system-cxx-std-lib` dependency is not read from cabal files.
* Recache is not called on the packge database after the `.conf` file is
generated, a more natural place for this rule is `registerRules`.
Treating this uniformly like other packages is complicated by it not
having any source code or a cabal file. However we can do a bit better
by reporting the dependency firstly in `PackageData` and then needing
the `.conf` file in the same place as every other package in
`configurePackage`.
This commit increases the `shakeVersion`, to provide backwards
compatibility to previous builds with different PackageData.
Fixes #25303
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
576987d0 by Simon Jakobi at 2026-06-02T04:53:36-04:00
compiler: use nubOrd from containers
Address #27103 by replacing GHC.Utils.Misc.ordNub[On] with
Data.Containers.ListUtils.nubOrd[On].
Note that nubOrd suffers from a small inefficiency, a fix for which
will be included in the next containers release:
https://github.com/haskell/containers/issues/1202
- - - - -
deea53c3 by David Eichmann at 2026-06-02T04:54:22-04:00
Hadrian: disable response files for GHC/Haddock builders on non-Windows
This makes debugging build errors easier on non-windows hosts.
See issue #27230
- - - - -
f2f5c6ba by Nikita Efremov at 2026-06-02T16:04:54+00:00
fix typo : compete with performance, not complete
- - - - -
5524ea0e by Wolfgang Jeltsch at 2026-06-03T08:01:26-04:00
Make the current `base` buildable with GHC 9.14
This comprises the following changes:
* Disable some imports into `GHC.Base` for GHC 9.14
* Disable some imports into `Prelude` for GHC 9.14
* Disable separate `ArrowLoop` import for GHC 9.14
* Disable `GHC.Internal.STM` import for GHC 9.14
* Disable `GHC.Internal.Unicode.Version` import for GHC 9.14
* Disable `GHC.Internal.TH.Monad` import for GHC 9.14
* Add alternative `fixIO` import for GHC 9.14
* Add alternative `unsafeCodeCoerce` import for GHC 9.14
* Disable hiding of imported SIMD operations for GHC 9.14
* Disable use of GHC 9.14’s `printToHandleFinalizerExceptionHandler`
* Enable use of `getFileHash` from `ghc-internal` for GHC 9.14
* Make `thenA` available for GHC 9.14
* Make `thenM` available for GHC 9.14
* Disable translation of `IoManagerFlagPoll` for GHC 9.14
* Add `hGetNewlineMode` for GHC 9.14
- - - - -
d3438055 by Enrico Maria De Angelis at 2026-06-03T08:02:17-04:00
Fix #27067 - Clarify haddocks on `minusNaturalMaybe`
- - - - -
f9bcfac2 by sheaf at 2026-06-03T14:47:19-04:00
Avoid mkTick in Core Prep breaking ANF
As discovered in #27182, mkTick can break ANF. This patch introduces a
variant of mkTick that skips the single optimisation that could break
ANF. This is preferrable over switching to the raw Tick constructor,
as the latter may introduce spurious cost centres in profiling reports.
This is a temporary measure until we more thoroughly refactor how
mkTick works (see #27141).
See Note [mkTick breaks ANF] in GHC.CoreToStg.Prep.
Fixes #27182
- - - - -
cf1fd661 by Artem Pelenitsyn at 2026-06-03T14:48:09-04:00
clarify comment for getSizeofMutableByteArray#: we get the size in bytes, not "elements"
- - - - -
a3b431f3 by David Eichmann at 2026-06-04T10:10:19+00:00
Hadrian: convert env variable ACLOCAL_PATH to unix paths.
Convert ACLOCAL_PATH to a unix style path when invoking autoreconf.
Autoreconf doesn't handle windows paths.
See Note [Autoreconf unix paths from ACLOCAL_PATH].
Fixes #27311
- - - - -
18f6138a by Simon Jakobi at 2026-06-04T20:20:31-04:00
testsuite: Deduplicate --only test names
config.only is assumed to be a set, but supplying --only overwrote it
with the (list) argparse result, which can contain duplicates. When a
test ran, config.only.remove(name) dropped only the first occurrence,
so a duplicated name lingered and was later misreported as a
"test not found" framework failure. Store it as a set instead.
Fixes #27322
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
2f3cc9ff by Simon Jakobi at 2026-06-08T07:55:49-04:00
testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
The ghc-bignum package was merged into ghc-internal, so the BIGNUM_GMP
probe in test.mk ran `ghc-pkg field ghc-bignum exposed-modules`, which
fails with "cannot find package ghc-bignum". That error went to stderr
and leaked into the captured stderr of every makefile_test, causing
spurious [bad stderr] failures across the suite. The probe also silently
returned empty, so config.have_fast_bignum was wrongly False even on GMP
builds.
Probe ghc-internal's extra-libraries for the gmp library instead: the
GMP backend module is an other-module (not exposed), but GMP_LIBS adds
gmp to extra-libraries only on a GMP build, so this distinguishes the
backends. Redirect stderr to keep any future missing-package error off
the harness's stderr.
This also removes a stale comment as per suggestion from hsyl20.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
eb3bf6e7 by Alan Zimmerman at 2026-06-08T07:56:32-04:00
EPA: Rename Transform.anchorEof to addModuleCommentOrigDeltas
This now matches what it actually does.
- - - - -
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
333df444 by sheaf at 2026-06-10T05:10:25-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
98c20394 by sheaf at 2026-06-10T05:11:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
5ac9ce7d by Zubin Duggal at 2026-06-10T21:26:32+05:30
hadrian: Remove old package.conf files when generating new ones
Old package.conf files might exists with different hashes, causing issues like #26661
Fixes #26661
- - - - -
c9015f09 by sheaf at 2026-06-11T12:40:28-04:00
Fix AArch64 clobbering bug for MUL2
On AArch64, the code generator could clobber one of the input operands
when computing the lower bits of a MUL2 operation. This rendered invalid
the subsequent computation of the high bits.
This commit fixes that by using a temporary register. The register
allocator can remove the redundant move in the common case when the
registers do not conflict.
Fixes #27046
- - - - -
7ab90288 by Rodrigo Mesquita at 2026-06-11T12:41:11-04:00
fix: make T27131 less flaky
It seems that T27131 fails flakily in a race where we check the flag
before the capability had the chance to process the mailbox which sets
the flag. This seemingly should only happen if the capability ends up
being the same for setting and checking the flag.
- - - - -
8965cb76 by Marc Scholten at 2026-06-12T04:53:22-04:00
haddock: render modules concurrently
- - - - -
8cc0b64a by Duncan Coutts at 2026-06-12T04:54:06-04:00
Promote HAVE_PREEMPTION from Timer.c to OSThreads.h
We will want to know about HAVE_PREEMPTION in more places.
HAVE_PREEMPTION tells us that we do have OS threads available,
irrespective of whether THREADED is defined. In particular,
HAVE_PREEMPTION is defined on all proper OSs, but not on WASM (and
hyopthetically may not be true on some other platforms like
micro-controllers, RTOSs, VM hypervisors etc).
- - - - -
cce574ed by Duncan Coutts at 2026-06-12T04:54:06-04:00
Define ACQUIRE_LOCK_ALWAYS and friends
Fix issue #27335
Like the atomic _ALWAYS variants, these lock actions are always defined,
rather than being dependent on whether we are in the THREADED case. All
the "normal" LOCK macros are defined to be no-ops when !THREADED.
The use case for the _ALWAYS variants is where we are using OS threads
even in the non-threaded RTS. This includes everything to do with the
timer/ticker thread, which is used in the non-threaded RTS too.
In particular, we will want to use this for eventlog things, because the
timer thread performs eventlogging concurrently with the main
capability, even in the non-threaded RTS.
- - - - -
1f28d1f6 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Use ACQUIRE/RELEASE_LOCK_ALWAYS with eventBufMutex
Even in the non-threaded RTS the eventBufMutex is needed by both the
main capability and the timer/ticker thread, so always use the mutex.
This should fix #25165 which is about the main capability and the timer
thread posting events to the eventlog buffer concurrently and thereby
corrupting the buffer data.
- - - - -
0ff29782 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Expose eventBufMutex in the EventLog interface/header
We will need it in forkProcess to ensure we don't write to the global
eventlog buffer concurrently with trying to flush eventlog buffers and
do the fork().
- - - - -
7a688395 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Split flushAllCapsEventsBufs into safe and unlocked version
Following the convention that unlocked versions have a trailing _
underscore in their name. This one requires the caller to hold the
eventlog global buffer mutex. We will need this in forkProcess.
- - - - -
341ed474 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in setNumCapabilities
Historically, the comment here was:
We must stop the interval timer while we are changing the
capabilities array lest handle_tick may try to context switch
an old capability. See #17289.
and
We must disable the timer while we do this since the tick handler may
call contextSwitchAllCapabilities, which may see the capabilities array
as we free it.
What this refers to is that historically, when changing the number of
capabilities, the array of capabilities was reallocated to a new size,
allocating new ones and freeing the old ones, thus invalidating all
existing capbility pointers.
Strangely, for good measure the code used to call stopTimer twice (hence
the two similar comments above).
However, since commit a3eccf06292dd666b24606251a52da2b466a9612, the
capabilities array is no longer reallocated. Instead the array is
allcoated once on RTS startup to the maximum size it could ever be
allowed to be, and then capabilities get enabled/disabled at runtime. So
the capability pointers never become invalid anymore. At worst, they may
point to capabilities that are disabled.
Thus we no longer need to stop the timer (twice) while we change the
number of enabled capabilities. This also partially solves issue #27105,
which notes that stopTimer is being used as if it were synchronous, when
it is not. At least for this case, the solution is that stopTimer is not
needed at all!
- - - - -
674858e3 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in forkProcess
but replace it with taking the eventlog buffer lock during the fork.
Fixes issue #27105
The original reason to block the timer during a fork was that
historically the timer was implemented using a periodic timer signal,
and the signal itself would interrupt the fork system call (returning
EINTR). For large processes (where fork() takes a while) this could
permanently livelock: the timer always would go off before the fork
could complete, which got retried in a loop forever.
The timer is no longer implemented as a unix signal, but uses threads.
Thus the original problem no longer exists. The only remaining reason to
block the timer tick is to prevent actions taken by the tick from
interfering with the delicate process involved in fork (taking a load of
locks and pausing everything).
The only thing we need to do is to prevent the eventlog from being
written to or flushed while the fork is taking place. To achieve this
all we need to do is hold the mutex for the global eventlog buffer.
This removes the last use of stopTimer that expects stopTimer to work
synchronously (which it was not) and thus solves issue #27105. To be
clear, we solve issue #27105 not by making stopTimer synchronous, but by
eliminating the use sites that expected it to be synchronous.
- - - - -
40764930 by sheaf at 2026-06-12T14:54:43-04:00
Add type family performance test for #26426
Some GHC versions produced large numbers of coercions after typechecking
and desugaring when compiling the program in #26426:
Version | Typechecker time | Typechecker allocations | Coercions
-------:|-----------------:|------------------------:|---------:
9.6 | 47 ms | 48 MB | 110k
9.8 | 1000 ms | 486 MB | 10,437k
9.10 | 922 ms | 489 MB | 10,436k
9.12 | 906 ms | 482 MB | 10,437k
9.14 | 63 ms | 55 MB | 333k
10.0 | 47 ms | 64 MB | 35k
The improvement 9.12 -> 9.14 was due to commit 22d11fa818fae2c95c494fc0fac1f8cb4c6e7cb6,
while the improvement 9.14 -> 10.0 was due to commit 0b7df6db9e46df40e86fbff1a66dc10440b99db5.
As the behaviour of GHC seems better than it's ever been on this program,
we declare victory, adding this performance test to ensure we don't
regress on this program.
On the way, we update Note [Combining equalities] in GHC.Tc.SolveR.Equality
with the explanation of the 9.12 -> 9.14 improvement (getting rid of an
exponential blowup in coercion sizes), and we update
Note [Exploiting closed type families] in GHC.Tc.Solver.FunDeps with
the explanation of the 9.14 -> 10.0 improvement (bringing down coercion
size growth from cubic to quadratic).
- - - - -
0f3d0a71 by Zubin Duggal at 2026-06-12T14:55:30-04:00
compiler: mark tool messages as errors/warnings depending on the exit code
Fixes #27370
- - - - -
d9ea2d76 by mangoiv at 2026-06-13T04:41:51-04:00
libraries/process: bump submodule to v1.6.30.0
- bump the submodule to the appropriate tag
- suppress benign warning resulting from the change
- - - - -
6ebaaba3 by David Eichmann at 2026-06-13T04:42:37-04:00
ghc-toolchain: don't throw when candidate executables are not found
Fixes #27369
- - - - -
6c65e1e1 by David Eichmann at 2026-06-13T04:43:23-04:00
CI: lint-changelog checks for no-changelog label in script instead of rules
- - - - -
181 changed files:
- .gitlab-ci.yml
- boot
- + changelog.d/T27046
- + changelog.d/T27182.md
- + changelog.d/T27225
- + changelog.d/T27317
- + changelog.d/T27359
- + changelog.d/fix-blackhole-handling
- changelog.d/hadrian-response-files.md
- + changelog.d/hadrian-stale-package-confs-26661
- + changelog.d/hadrian-system-cxx-std-lib-25303
- + changelog.d/libdir-setting
- + changelog.d/module-graph-reuse-in-downsweep
- + changelog.d/remove-bignum-check-backend
- + changelog.d/remove-bignum-ffi-backend
- + changelog.d/tool-messages-27370
- + changelog.d/windows-rethrow-overlapped-exception
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Linker/Unit.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Misc.hs
- docs/users_guide/javascript.rst
- docs/users_guide/using.rst
- ghc/GHCi/UI.hs
- hadrian/README.md
- hadrian/build-cabal
- hadrian/doc/user-settings.md
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Main.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Arrow.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Fixed.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/src/GHC/Conc/Sync.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/GHC/Weak.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/System/Mem/Weak.hs
- libraries/ghc-bignum/ghc-bignum.cabal
- libraries/ghc-boot/GHC/Settings/Utils.hs
- libraries/ghc-internal/bignum-backend.rst
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- libraries/ghc-internal/src/GHC/Internal/Natural.hs
- libraries/process
- rts/Capability.c
- rts/Messages.c
- rts/Schedule.c
- rts/ThreadPaused.c
- rts/Threads.c
- rts/Timer.c
- rts/Updates.h
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/include/rts/OSThreads.h
- rts/include/rts/storage/ClosureMacros.h
- rts/sm/BlockAlloc.c
- rts/sm/MBlock.c
- rts/win32/libHSghc-internal.def.in
- testsuite/driver/runtests.py
- testsuite/driver/testlib.py
- testsuite/mk/test.mk
- testsuite/tests/MiniQuickCheck.hs
- + testsuite/tests/codeGen/should_run/T27046.hs
- + testsuite/tests/codeGen/should_run/T27046_cmm.cmm
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/T27370/Makefile
- + testsuite/tests/driver/T27370/T27370.hs
- + testsuite/tests/driver/T27370/T27370.pp
- + testsuite/tests/driver/T27370/T27370.stderr
- + testsuite/tests/driver/T27370/all.T
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/A.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/B.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/C.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/D.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/X.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Y.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Z.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.stdout
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/downsweep/all.T
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- + testsuite/tests/ghc-api/settings/LibDir.hs
- + testsuite/tests/ghc-api/settings/LibDir.stdout
- + testsuite/tests/ghc-api/settings/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- + testsuite/tests/perf/compiler/T26426.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/perf/should_run/T11226.hs
- + testsuite/tests/perf/should_run/T11226.stdout
- testsuite/tests/perf/should_run/all.T
- + testsuite/tests/profiling/should_compile/T27182.hs
- testsuite/tests/profiling/should_compile/all.T
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- testsuite/tests/rts/T27131.hs
- testsuite/tests/rts/T27131.stdout
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml.hs
- utils/haddock/haddock-api/src/Haddock/Options.hs
- utils/haddock/haddock-api/src/Haddock/Utils.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f9118647b8704bce384b679e8cbb8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f9118647b8704bce384b679e8cbb8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/ghc-9-14-building-base] Correct `tar` options
by Wolfgang Jeltsch (@jeltsch) 15 Jun '26
by Wolfgang Jeltsch (@jeltsch) 15 Jun '26
15 Jun '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/ghc-9-14-building-base at Glasgow Haskell Compiler / GHC
Commits:
c148bcb9 by Wolfgang Jeltsch at 2026-06-15T14:06:10+02:00
Correct `tar` options
- - - - -
1 changed file:
- .gitlab-ci.yml
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -1162,7 +1162,7 @@ base-build-with-ghc-914:
ghc_version=9.14.1
url=https://downloads.haskell.org/~ghc/$ghc_version/ghc-$ghc_version-x86_64…
curl "$url" >ghc-$ghc_version.tar.xz
- tar -xJF ghc-$ghc_version.tar.xz
+ tar -xJf ghc-$ghc_version.tar.xz
cd ghc-$ghc_version
./configure --prefix "$PWD/../ghc"
make install
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c148bcb90909771e026fe77608ab071…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c148bcb90909771e026fe77608ab071…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/21176-integer-bits] Add explicit setBit/clearBit/complementBit for instance Bits Integer (#21176)
by Simon Jakobi (@sjakobi2) 15 Jun '26
by Simon Jakobi (@sjakobi2) 15 Jun '26
15 Jun '26
Simon Jakobi pushed to branch wip/sjakobi/21176-integer-bits at Glasgow Haskell Compiler / GHC
Commits:
612095c2 by Simon Jakobi at 2026-06-15T13:53:11+02:00
Add explicit setBit/clearBit/complementBit for instance Bits Integer (#21176)
The default setBit, clearBit, and complementBit methods allocate
intermediate Integers per call. Define them explicitly via the new
integerSetBit[#], integerClearBit[#] and integerComplementBit[#], built
on the BigNat# primitives, which avoid those allocations. Allocation is not
eliminated entirely -- the negative (IN) cases would need in-place mutation,
which is left as future work.
The default methods constant-folded on literal arguments via the
integerOr/integerAnd/integerXor rules, which fold literal Integers of any
size. The explicit functions have no such rule, so they (their Word-argument
wrappers, and the Bits Integer methods) are marked INLINE to expose the
underlying primops to the simplifier; see Note [INLINE for constant folding
of bit operations]. This restores folding only on the small-int (IS) path --
large literal Integers (IP/IN) are no longer constant-folded, a minor
regression for that case. T8832 covers the IS-path folding.
The new golden-output test T21176 checks all three operations against the
default implementations across the sign/size boundaries, recording each
result plus its integerCheck validity. The base and ghc-bignum interface-
stability export goldens gain the new functions.
The main changelog entry lives in changelog.d under a new ghc-internal
section (renamed from ghc-prim).
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
11 changed files:
- + changelog.d/T21176
- changelog.d/config
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
- libraries/ghc-internal/src/GHC/Internal/Bits.hs
- testsuite/tests/interface-stability/ghc-bignum-exports.stdout
- + testsuite/tests/numeric/should_run/T21176.hs
- + testsuite/tests/numeric/should_run/T21176.stdout
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/simplCore/should_compile/T8832.hs
- testsuite/tests/simplCore/should_compile/T8832.stdout
Changes:
=====================================
changelog.d/T21176
=====================================
@@ -0,0 +1,4 @@
+section: ghc-internal
+synopsis: Give ``setBit``, ``clearBit`` and ``complementBit`` explicit definitions in ``instance Bits Integer``, backed by new ``integerSetBit[#]``, ``integerClearBit[#]`` and ``integerComplementBit[#]`` functions. These avoid the intermediate ``Integer`` allocations of the previous default methods, although allocation is not eliminated entirely — notably the negative (``IN``) cases would require in-place mutation, which is left as future work. As a trade-off, constant folding of these operations now applies only to small (machine-word-sized) literal arguments; the previous default methods folded literal ``Integer`` arguments of any size via the ``integerOr``/``integerAnd``/``integerXor`` rules.
+issues: #21176
+mrs: !7772
=====================================
changelog.d/config
=====================================
@@ -27,7 +27,7 @@ sections: {
cmm Cmm
build-tools Build tools
base ``base`` library
- ghc-prim ``ghc-prim`` library
+ ghc-internal ``ghc-internal`` library
ghc-lib ``ghc`` library
ghc-heap ``ghc-heap`` library
ghc-experimental ``ghc-experimental`` library
=====================================
libraries/base/changelog.md
=====================================
@@ -1,6 +1,7 @@
# Changelog for [`base` package](http://hackage.haskell.org/package/base)
## 4.24.0.0 *TBA*
+ * Give `setBit`, `clearBit` and `complementBit` explicit definitions in `instance Bits Integer`, reducing intermediate allocations. ([GHC #21176](https://gitlab.haskell.org/ghc/ghc/-/issues/21176))
* Add `Bounded` instances for `Double`, `Float`, `CDouble` and `CFloat`. ([CLC proposal #402](https://github.com/haskell/core-libraries-committee/issues/402))
* Ensure that `Data.List.elem` and `notElem` can be specialized even when no list fusion happens. ([CLC proposal #412)(https://github.com/haskell/core-libraries-committee/issues/412))
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
=====================================
@@ -133,6 +133,12 @@ module GHC.Internal.Bignum.Integer
, integerBit
, integerTestBit#
, integerTestBit
+ , integerSetBit#
+ , integerSetBit
+ , integerClearBit#
+ , integerClearBit
+ , integerComplementBit#
+ , integerComplementBit
, integerShiftR#
, integerShiftR
, integerShiftL#
@@ -707,6 +713,113 @@ integerTestBit# (IN x) i
integerTestBit :: Integer -> Word -> Bool
integerTestBit !i (W# n) = isTrue# (integerTestBit# i n)
+{- Note [INLINE for constant folding of bit operations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+While there are no dedicated constant-folding rules for
+integerSetBit#/integerClearBit#/integerComplementBit#, we do INLINE them (and
+their Word-argument wrappers and the corresponding Bits Integer methods) to make
+the underlying primops accessible for constant folding, e.g. so that
+`clearBit (bit 0) 0 :: Integer` folds to `IS 0#`. Test T8832 checks the folding
+for all three operations.
+-}
+
+-- | Set the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerSetBit# :: Integer -> Word# -> Integer
+{-# INLINE integerSetBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerSetBit# n@(IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `orI#` uncheckedIShiftL# 1# (word2Int# i))
+ | isTrue# (x >=# 0#)
+ = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
+ | True
+ = n
+integerSetBit# (IP x) i = IP (bigNatSetBit# x i)
+integerSetBit# (IN x) i = integerFromBigNatNeg#
+ (bigNatAddWord#
+ (bigNatClearBit# (bigNatSubWordUnsafe# x 1##) i)
+ 1##)
+
+-- | Set the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerSetBit :: Integer -> Word -> Integer
+{-# INLINE integerSetBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerSetBit !i (W# n) = integerSetBit# i n
+
+-- | Clear the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerClearBit# :: Integer -> Word# -> Integer
+{-# INLINE integerClearBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerClearBit# n@(IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `andI#` notI# (uncheckedIShiftL# 1# (word2Int# i)))
+ | isTrue# (x >=# 0#)
+ = n
+ | True
+ = IN (bigNatAddWord#
+ (bigNatSetBit#
+ (bigNatFromWord#
+ (minusWord# (int2Word# (negateInt# x)) 1##))
+ i)
+ 1##)
+integerClearBit# (IP x) i = integerFromBigNat# (bigNatClearBit# x i)
+integerClearBit# (IN x) i = IN (bigNatAddWord#
+ (bigNatSetBit# (bigNatSubWordUnsafe# x 1##) i)
+ 1##)
+
+-- | Clear the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerClearBit :: Integer -> Word -> Integer
+{-# INLINE integerClearBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerClearBit !i (W# n) = integerClearBit# i n
+
+-- | Reverse the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerComplementBit# :: Integer -> Word# -> Integer
+{-# INLINE integerComplementBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerComplementBit# (IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `xorI#` uncheckedIShiftL# 1# (word2Int# i))
+ | isTrue# (x >=# 0#)
+ = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
+ | True
+ = IN (bigNatAddWord#
+ (bigNatSetBit#
+ (bigNatFromWord# (minusWord# (int2Word# (negateInt# x)) 1##))
+ i)
+ 1##)
+integerComplementBit# (IP x) i = integerFromBigNat# (bigNatComplementBit# x i)
+integerComplementBit# (IN x) i = integerFromBigNatNeg#
+ (bigNatAddWord#
+ (bigNatComplementBit#
+ (bigNatSubWordUnsafe# x 1##)
+ i)
+ 1##)
+
+-- | Reverse the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerComplementBit :: Integer -> Word -> Integer
+{-# INLINE integerComplementBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerComplementBit !i (W# n) = integerComplementBit# i n
+
-- | Shift-right operation
--
-- Fake 2's complement for negative values (might be slow)
=====================================
libraries/ghc-internal/src/GHC/Internal/Bits.hs
=====================================
@@ -564,6 +564,15 @@ instance Bits Integer where
| otherwise = integerShiftR x (fromIntegral (negate i))
testBit x i = integerTestBit x (fromIntegral i)
zeroBits = integerZero
+ -- INLINE on setBit/clearBit/complementBit preserves constant folding;
+ -- see Note [INLINE for constant folding of bit operations] in
+ -- GHC.Internal.Bignum.Integer.
+ setBit x i = integerSetBit x (fromIntegral i)
+ {-# INLINE setBit #-}
+ clearBit x i = integerClearBit x (fromIntegral i)
+ {-# INLINE clearBit #-}
+ complementBit x i = integerComplementBit x (fromIntegral i)
+ {-# INLINE complementBit #-}
bit (I# i) = integerBit# (int2Word# i)
popCount x = I# (integerPopCount# x)
=====================================
testsuite/tests/interface-stability/ghc-bignum-exports.stdout
=====================================
@@ -201,8 +201,12 @@ module GHC.Num.Integer where
integerBit# :: GHC.Internal.Prim.Word# -> Integer
integerCheck :: Integer -> GHC.Internal.Types.Bool
integerCheck# :: Integer -> GHC.Internal.Bignum.Primitives.Bool#
+ integerClearBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerClearBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerCompare :: Integer -> Integer -> GHC.Internal.Types.Ordering
integerComplement :: Integer -> Integer
+ integerComplementBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerComplementBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerDecodeDouble# :: GHC.Internal.Prim.Double# -> (# Integer, GHC.Internal.Prim.Int# #)
integerDiv :: Integer -> Integer -> Integer
integerDivMod :: Integer -> Integer -> (Integer, Integer)
@@ -266,6 +270,8 @@ module GHC.Num.Integer where
integerQuotRem# :: Integer -> Integer -> (# Integer, Integer #)
integerRecipMod# :: Integer -> GHC.Internal.Bignum.Natural.Natural -> (# GHC.Internal.Bignum.Natural.Natural | () #)
integerRem :: Integer -> Integer -> Integer
+ integerSetBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerSetBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerShiftL :: Integer -> GHC.Internal.Types.Word -> Integer
integerShiftL# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerShiftR :: Integer -> GHC.Internal.Types.Word -> Integer
=====================================
testsuite/tests/numeric/should_run/T21176.hs
=====================================
@@ -0,0 +1,38 @@
+module Main where
+
+import Data.Bits
+import Data.Int (Int32, Int64)
+import Data.Foldable (for_)
+import GHC.Num.Integer (integerCheck)
+
+integers :: [Integer]
+integers = concatMap neighbours [minInt64, minInt32, 0, maxInt32, maxInt64]
+ where
+ neighbours i = [i - 2, i - 1, i, i + 1, i + 2]
+ minInt64 = toInteger (minBound :: Int64)
+ minInt32 = toInteger (minBound :: Int32)
+ maxInt32 = toInteger (maxBound :: Int32)
+ maxInt64 = toInteger (maxBound :: Int64)
+
+bits :: [Int]
+bits = [0, 1, x - 1, x, x + 1]
+ where x = finiteBitSize (0 :: Int) - 1
+
+testXBit :: String -> (Integer -> Int -> Integer) -> (Integer -> Int -> Integer) -> IO ()
+testXBit name f model = do
+ putStrLn name
+ for_ integers $ \i ->
+ for_ bits $ \b -> do
+ let actual = f i b
+ expected = model i b
+ valid = if integerCheck actual then "valid" else "invalid"
+ matches = if actual == expected then "matches" else "differs"
+ putStrLn $ " " ++ show i ++ " " ++ show b ++ " -> " ++ show actual
+ ++ " [" ++ valid ++ ", " ++ matches ++ "]"
+ putStrLn ""
+
+main :: IO ()
+main = do
+ testXBit "setBit" setBit (\i b -> i .|. bit b)
+ testXBit "clearBit" clearBit (\i b -> i .&. complement (bit b))
+ testXBit "complementBit" complementBit (\i b -> i `xor` bit b)
=====================================
testsuite/tests/numeric/should_run/T21176.stdout
=====================================
@@ -0,0 +1,381 @@
+setBit
+ -9223372036854775810 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 62 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 63 -> -2 [valid, matches]
+ -9223372036854775810 64 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 62 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 63 -> -1 [valid, matches]
+ -9223372036854775809 64 -> -9223372036854775809 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775808 62 -> -4611686018427387904 [valid, matches]
+ -9223372036854775808 63 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 64 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775805 [valid, matches]
+ -9223372036854775807 62 -> -4611686018427387903 [valid, matches]
+ -9223372036854775807 63 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 64 -> -9223372036854775807 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775805 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 62 -> -4611686018427387902 [valid, matches]
+ -9223372036854775806 63 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 64 -> -9223372036854775806 [valid, matches]
+ -2147483650 0 -> -2147483649 [valid, matches]
+ -2147483650 1 -> -2147483650 [valid, matches]
+ -2147483650 62 -> -2147483650 [valid, matches]
+ -2147483650 63 -> -2147483650 [valid, matches]
+ -2147483650 64 -> -2147483650 [valid, matches]
+ -2147483649 0 -> -2147483649 [valid, matches]
+ -2147483649 1 -> -2147483649 [valid, matches]
+ -2147483649 62 -> -2147483649 [valid, matches]
+ -2147483649 63 -> -2147483649 [valid, matches]
+ -2147483649 64 -> -2147483649 [valid, matches]
+ -2147483648 0 -> -2147483647 [valid, matches]
+ -2147483648 1 -> -2147483646 [valid, matches]
+ -2147483648 62 -> -2147483648 [valid, matches]
+ -2147483648 63 -> -2147483648 [valid, matches]
+ -2147483648 64 -> -2147483648 [valid, matches]
+ -2147483647 0 -> -2147483647 [valid, matches]
+ -2147483647 1 -> -2147483645 [valid, matches]
+ -2147483647 62 -> -2147483647 [valid, matches]
+ -2147483647 63 -> -2147483647 [valid, matches]
+ -2147483647 64 -> -2147483647 [valid, matches]
+ -2147483646 0 -> -2147483645 [valid, matches]
+ -2147483646 1 -> -2147483646 [valid, matches]
+ -2147483646 62 -> -2147483646 [valid, matches]
+ -2147483646 63 -> -2147483646 [valid, matches]
+ -2147483646 64 -> -2147483646 [valid, matches]
+ -2 0 -> -1 [valid, matches]
+ -2 1 -> -2 [valid, matches]
+ -2 62 -> -2 [valid, matches]
+ -2 63 -> -2 [valid, matches]
+ -2 64 -> -2 [valid, matches]
+ -1 0 -> -1 [valid, matches]
+ -1 1 -> -1 [valid, matches]
+ -1 62 -> -1 [valid, matches]
+ -1 63 -> -1 [valid, matches]
+ -1 64 -> -1 [valid, matches]
+ 0 0 -> 1 [valid, matches]
+ 0 1 -> 2 [valid, matches]
+ 0 62 -> 4611686018427387904 [valid, matches]
+ 0 63 -> 9223372036854775808 [valid, matches]
+ 0 64 -> 18446744073709551616 [valid, matches]
+ 1 0 -> 1 [valid, matches]
+ 1 1 -> 3 [valid, matches]
+ 1 62 -> 4611686018427387905 [valid, matches]
+ 1 63 -> 9223372036854775809 [valid, matches]
+ 1 64 -> 18446744073709551617 [valid, matches]
+ 2 0 -> 3 [valid, matches]
+ 2 1 -> 2 [valid, matches]
+ 2 62 -> 4611686018427387906 [valid, matches]
+ 2 63 -> 9223372036854775810 [valid, matches]
+ 2 64 -> 18446744073709551618 [valid, matches]
+ 2147483645 0 -> 2147483645 [valid, matches]
+ 2147483645 1 -> 2147483647 [valid, matches]
+ 2147483645 62 -> 4611686020574871549 [valid, matches]
+ 2147483645 63 -> 9223372039002259453 [valid, matches]
+ 2147483645 64 -> 18446744075857035261 [valid, matches]
+ 2147483646 0 -> 2147483647 [valid, matches]
+ 2147483646 1 -> 2147483646 [valid, matches]
+ 2147483646 62 -> 4611686020574871550 [valid, matches]
+ 2147483646 63 -> 9223372039002259454 [valid, matches]
+ 2147483646 64 -> 18446744075857035262 [valid, matches]
+ 2147483647 0 -> 2147483647 [valid, matches]
+ 2147483647 1 -> 2147483647 [valid, matches]
+ 2147483647 62 -> 4611686020574871551 [valid, matches]
+ 2147483647 63 -> 9223372039002259455 [valid, matches]
+ 2147483647 64 -> 18446744075857035263 [valid, matches]
+ 2147483648 0 -> 2147483649 [valid, matches]
+ 2147483648 1 -> 2147483650 [valid, matches]
+ 2147483648 62 -> 4611686020574871552 [valid, matches]
+ 2147483648 63 -> 9223372039002259456 [valid, matches]
+ 2147483648 64 -> 18446744075857035264 [valid, matches]
+ 2147483649 0 -> 2147483649 [valid, matches]
+ 2147483649 1 -> 2147483651 [valid, matches]
+ 2147483649 62 -> 4611686020574871553 [valid, matches]
+ 2147483649 63 -> 9223372039002259457 [valid, matches]
+ 2147483649 64 -> 18446744075857035265 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775805 62 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 63 -> 18446744073709551613 [valid, matches]
+ 9223372036854775805 64 -> 27670116110564327421 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 62 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 63 -> 18446744073709551614 [valid, matches]
+ 9223372036854775806 64 -> 27670116110564327422 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 62 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 63 -> 18446744073709551615 [valid, matches]
+ 9223372036854775807 64 -> 27670116110564327423 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775810 [valid, matches]
+ 9223372036854775808 62 -> 13835058055282163712 [valid, matches]
+ 9223372036854775808 63 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 64 -> 27670116110564327424 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775811 [valid, matches]
+ 9223372036854775809 62 -> 13835058055282163713 [valid, matches]
+ 9223372036854775809 63 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 64 -> 27670116110564327425 [valid, matches]
+
+clearBit
+ -9223372036854775810 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775812 [valid, matches]
+ -9223372036854775810 62 -> -13835058055282163714 [valid, matches]
+ -9223372036854775810 63 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 64 -> -27670116110564327426 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775811 [valid, matches]
+ -9223372036854775809 62 -> -13835058055282163713 [valid, matches]
+ -9223372036854775809 63 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 64 -> -27670116110564327425 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 62 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 63 -> -18446744073709551616 [valid, matches]
+ -9223372036854775808 64 -> -27670116110564327424 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 62 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 63 -> -18446744073709551615 [valid, matches]
+ -9223372036854775807 64 -> -27670116110564327423 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775806 62 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 63 -> -18446744073709551614 [valid, matches]
+ -9223372036854775806 64 -> -27670116110564327422 [valid, matches]
+ -2147483650 0 -> -2147483650 [valid, matches]
+ -2147483650 1 -> -2147483652 [valid, matches]
+ -2147483650 62 -> -4611686020574871554 [valid, matches]
+ -2147483650 63 -> -9223372039002259458 [valid, matches]
+ -2147483650 64 -> -18446744075857035266 [valid, matches]
+ -2147483649 0 -> -2147483650 [valid, matches]
+ -2147483649 1 -> -2147483651 [valid, matches]
+ -2147483649 62 -> -4611686020574871553 [valid, matches]
+ -2147483649 63 -> -9223372039002259457 [valid, matches]
+ -2147483649 64 -> -18446744075857035265 [valid, matches]
+ -2147483648 0 -> -2147483648 [valid, matches]
+ -2147483648 1 -> -2147483648 [valid, matches]
+ -2147483648 62 -> -4611686020574871552 [valid, matches]
+ -2147483648 63 -> -9223372039002259456 [valid, matches]
+ -2147483648 64 -> -18446744075857035264 [valid, matches]
+ -2147483647 0 -> -2147483648 [valid, matches]
+ -2147483647 1 -> -2147483647 [valid, matches]
+ -2147483647 62 -> -4611686020574871551 [valid, matches]
+ -2147483647 63 -> -9223372039002259455 [valid, matches]
+ -2147483647 64 -> -18446744075857035263 [valid, matches]
+ -2147483646 0 -> -2147483646 [valid, matches]
+ -2147483646 1 -> -2147483648 [valid, matches]
+ -2147483646 62 -> -4611686020574871550 [valid, matches]
+ -2147483646 63 -> -9223372039002259454 [valid, matches]
+ -2147483646 64 -> -18446744075857035262 [valid, matches]
+ -2 0 -> -2 [valid, matches]
+ -2 1 -> -4 [valid, matches]
+ -2 62 -> -4611686018427387906 [valid, matches]
+ -2 63 -> -9223372036854775810 [valid, matches]
+ -2 64 -> -18446744073709551618 [valid, matches]
+ -1 0 -> -2 [valid, matches]
+ -1 1 -> -3 [valid, matches]
+ -1 62 -> -4611686018427387905 [valid, matches]
+ -1 63 -> -9223372036854775809 [valid, matches]
+ -1 64 -> -18446744073709551617 [valid, matches]
+ 0 0 -> 0 [valid, matches]
+ 0 1 -> 0 [valid, matches]
+ 0 62 -> 0 [valid, matches]
+ 0 63 -> 0 [valid, matches]
+ 0 64 -> 0 [valid, matches]
+ 1 0 -> 0 [valid, matches]
+ 1 1 -> 1 [valid, matches]
+ 1 62 -> 1 [valid, matches]
+ 1 63 -> 1 [valid, matches]
+ 1 64 -> 1 [valid, matches]
+ 2 0 -> 2 [valid, matches]
+ 2 1 -> 0 [valid, matches]
+ 2 62 -> 2 [valid, matches]
+ 2 63 -> 2 [valid, matches]
+ 2 64 -> 2 [valid, matches]
+ 2147483645 0 -> 2147483644 [valid, matches]
+ 2147483645 1 -> 2147483645 [valid, matches]
+ 2147483645 62 -> 2147483645 [valid, matches]
+ 2147483645 63 -> 2147483645 [valid, matches]
+ 2147483645 64 -> 2147483645 [valid, matches]
+ 2147483646 0 -> 2147483646 [valid, matches]
+ 2147483646 1 -> 2147483644 [valid, matches]
+ 2147483646 62 -> 2147483646 [valid, matches]
+ 2147483646 63 -> 2147483646 [valid, matches]
+ 2147483646 64 -> 2147483646 [valid, matches]
+ 2147483647 0 -> 2147483646 [valid, matches]
+ 2147483647 1 -> 2147483645 [valid, matches]
+ 2147483647 62 -> 2147483647 [valid, matches]
+ 2147483647 63 -> 2147483647 [valid, matches]
+ 2147483647 64 -> 2147483647 [valid, matches]
+ 2147483648 0 -> 2147483648 [valid, matches]
+ 2147483648 1 -> 2147483648 [valid, matches]
+ 2147483648 62 -> 2147483648 [valid, matches]
+ 2147483648 63 -> 2147483648 [valid, matches]
+ 2147483648 64 -> 2147483648 [valid, matches]
+ 2147483649 0 -> 2147483648 [valid, matches]
+ 2147483649 1 -> 2147483649 [valid, matches]
+ 2147483649 62 -> 2147483649 [valid, matches]
+ 2147483649 63 -> 2147483649 [valid, matches]
+ 2147483649 64 -> 2147483649 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775804 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 62 -> 4611686018427387901 [valid, matches]
+ 9223372036854775805 63 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 64 -> 9223372036854775805 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775804 [valid, matches]
+ 9223372036854775806 62 -> 4611686018427387902 [valid, matches]
+ 9223372036854775806 63 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 64 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775807 62 -> 4611686018427387903 [valid, matches]
+ 9223372036854775807 63 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 64 -> 9223372036854775807 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 62 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 63 -> 0 [valid, matches]
+ 9223372036854775808 64 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 62 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 63 -> 1 [valid, matches]
+ 9223372036854775809 64 -> 9223372036854775809 [valid, matches]
+
+complementBit
+ -9223372036854775810 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775812 [valid, matches]
+ -9223372036854775810 62 -> -13835058055282163714 [valid, matches]
+ -9223372036854775810 63 -> -2 [valid, matches]
+ -9223372036854775810 64 -> -27670116110564327426 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775811 [valid, matches]
+ -9223372036854775809 62 -> -13835058055282163713 [valid, matches]
+ -9223372036854775809 63 -> -1 [valid, matches]
+ -9223372036854775809 64 -> -27670116110564327425 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775808 62 -> -4611686018427387904 [valid, matches]
+ -9223372036854775808 63 -> -18446744073709551616 [valid, matches]
+ -9223372036854775808 64 -> -27670116110564327424 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775805 [valid, matches]
+ -9223372036854775807 62 -> -4611686018427387903 [valid, matches]
+ -9223372036854775807 63 -> -18446744073709551615 [valid, matches]
+ -9223372036854775807 64 -> -27670116110564327423 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775805 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775806 62 -> -4611686018427387902 [valid, matches]
+ -9223372036854775806 63 -> -18446744073709551614 [valid, matches]
+ -9223372036854775806 64 -> -27670116110564327422 [valid, matches]
+ -2147483650 0 -> -2147483649 [valid, matches]
+ -2147483650 1 -> -2147483652 [valid, matches]
+ -2147483650 62 -> -4611686020574871554 [valid, matches]
+ -2147483650 63 -> -9223372039002259458 [valid, matches]
+ -2147483650 64 -> -18446744075857035266 [valid, matches]
+ -2147483649 0 -> -2147483650 [valid, matches]
+ -2147483649 1 -> -2147483651 [valid, matches]
+ -2147483649 62 -> -4611686020574871553 [valid, matches]
+ -2147483649 63 -> -9223372039002259457 [valid, matches]
+ -2147483649 64 -> -18446744075857035265 [valid, matches]
+ -2147483648 0 -> -2147483647 [valid, matches]
+ -2147483648 1 -> -2147483646 [valid, matches]
+ -2147483648 62 -> -4611686020574871552 [valid, matches]
+ -2147483648 63 -> -9223372039002259456 [valid, matches]
+ -2147483648 64 -> -18446744075857035264 [valid, matches]
+ -2147483647 0 -> -2147483648 [valid, matches]
+ -2147483647 1 -> -2147483645 [valid, matches]
+ -2147483647 62 -> -4611686020574871551 [valid, matches]
+ -2147483647 63 -> -9223372039002259455 [valid, matches]
+ -2147483647 64 -> -18446744075857035263 [valid, matches]
+ -2147483646 0 -> -2147483645 [valid, matches]
+ -2147483646 1 -> -2147483648 [valid, matches]
+ -2147483646 62 -> -4611686020574871550 [valid, matches]
+ -2147483646 63 -> -9223372039002259454 [valid, matches]
+ -2147483646 64 -> -18446744075857035262 [valid, matches]
+ -2 0 -> -1 [valid, matches]
+ -2 1 -> -4 [valid, matches]
+ -2 62 -> -4611686018427387906 [valid, matches]
+ -2 63 -> -9223372036854775810 [valid, matches]
+ -2 64 -> -18446744073709551618 [valid, matches]
+ -1 0 -> -2 [valid, matches]
+ -1 1 -> -3 [valid, matches]
+ -1 62 -> -4611686018427387905 [valid, matches]
+ -1 63 -> -9223372036854775809 [valid, matches]
+ -1 64 -> -18446744073709551617 [valid, matches]
+ 0 0 -> 1 [valid, matches]
+ 0 1 -> 2 [valid, matches]
+ 0 62 -> 4611686018427387904 [valid, matches]
+ 0 63 -> 9223372036854775808 [valid, matches]
+ 0 64 -> 18446744073709551616 [valid, matches]
+ 1 0 -> 0 [valid, matches]
+ 1 1 -> 3 [valid, matches]
+ 1 62 -> 4611686018427387905 [valid, matches]
+ 1 63 -> 9223372036854775809 [valid, matches]
+ 1 64 -> 18446744073709551617 [valid, matches]
+ 2 0 -> 3 [valid, matches]
+ 2 1 -> 0 [valid, matches]
+ 2 62 -> 4611686018427387906 [valid, matches]
+ 2 63 -> 9223372036854775810 [valid, matches]
+ 2 64 -> 18446744073709551618 [valid, matches]
+ 2147483645 0 -> 2147483644 [valid, matches]
+ 2147483645 1 -> 2147483647 [valid, matches]
+ 2147483645 62 -> 4611686020574871549 [valid, matches]
+ 2147483645 63 -> 9223372039002259453 [valid, matches]
+ 2147483645 64 -> 18446744075857035261 [valid, matches]
+ 2147483646 0 -> 2147483647 [valid, matches]
+ 2147483646 1 -> 2147483644 [valid, matches]
+ 2147483646 62 -> 4611686020574871550 [valid, matches]
+ 2147483646 63 -> 9223372039002259454 [valid, matches]
+ 2147483646 64 -> 18446744075857035262 [valid, matches]
+ 2147483647 0 -> 2147483646 [valid, matches]
+ 2147483647 1 -> 2147483645 [valid, matches]
+ 2147483647 62 -> 4611686020574871551 [valid, matches]
+ 2147483647 63 -> 9223372039002259455 [valid, matches]
+ 2147483647 64 -> 18446744075857035263 [valid, matches]
+ 2147483648 0 -> 2147483649 [valid, matches]
+ 2147483648 1 -> 2147483650 [valid, matches]
+ 2147483648 62 -> 4611686020574871552 [valid, matches]
+ 2147483648 63 -> 9223372039002259456 [valid, matches]
+ 2147483648 64 -> 18446744075857035264 [valid, matches]
+ 2147483649 0 -> 2147483648 [valid, matches]
+ 2147483649 1 -> 2147483651 [valid, matches]
+ 2147483649 62 -> 4611686020574871553 [valid, matches]
+ 2147483649 63 -> 9223372039002259457 [valid, matches]
+ 2147483649 64 -> 18446744075857035265 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775804 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775805 62 -> 4611686018427387901 [valid, matches]
+ 9223372036854775805 63 -> 18446744073709551613 [valid, matches]
+ 9223372036854775805 64 -> 27670116110564327421 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775804 [valid, matches]
+ 9223372036854775806 62 -> 4611686018427387902 [valid, matches]
+ 9223372036854775806 63 -> 18446744073709551614 [valid, matches]
+ 9223372036854775806 64 -> 27670116110564327422 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775807 62 -> 4611686018427387903 [valid, matches]
+ 9223372036854775807 63 -> 18446744073709551615 [valid, matches]
+ 9223372036854775807 64 -> 27670116110564327423 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775810 [valid, matches]
+ 9223372036854775808 62 -> 13835058055282163712 [valid, matches]
+ 9223372036854775808 63 -> 0 [valid, matches]
+ 9223372036854775808 64 -> 27670116110564327424 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775811 [valid, matches]
+ 9223372036854775809 62 -> 13835058055282163713 [valid, matches]
+ 9223372036854775809 63 -> 1 [valid, matches]
+ 9223372036854775809 64 -> 27670116110564327425 [valid, matches]
+
=====================================
testsuite/tests/numeric/should_run/all.T
=====================================
@@ -101,3 +101,4 @@ test('T24245', normal, compile_and_run, [''])
test('T25653', normal, compile_and_run, [''])
test('T18619', exit_code(1), compile_and_run, [''])
test('T26230', normal, compile_and_run, [''])
+test('T21176', normal, compile_and_run, [''])
=====================================
testsuite/tests/simplCore/should_compile/T8832.hs
=====================================
@@ -23,3 +23,9 @@ T(w32,Word32)
T(w64,Word64)
T(z,Integer)
+
+zset :: Integer
+zset = setBit (bit 0) 0
+
+zcompl :: Integer
+zcompl = complementBit (bit 0) 0
=====================================
testsuite/tests/simplCore/should_compile/T8832.stdout
=====================================
@@ -8,4 +8,6 @@ w8 = GHC.Internal.Word.W8# 0#Word8
w16 = GHC.Internal.Word.W16# 0#Word16
w32 = GHC.Internal.Word.W32# 0#Word32
w64 = GHC.Internal.Word.W64# 0#Word64
-z = GHC.Internal.Bignum.Integer.IS 0#
+zcompl = GHC.Internal.Bignum.Integer.IS 0#
+zset = GHC.Internal.Bignum.Integer.IS 1#
+z = zcompl
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612095c20fb41fe0243f10cc013227e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612095c20fb41fe0243f10cc013227e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sjakobi/T21176-integer-bits] Add explicit setBit/clearBit/complementBit for instance Bits Integer (#21176)
by Simon Jakobi (@sjakobi2) 15 Jun '26
by Simon Jakobi (@sjakobi2) 15 Jun '26
15 Jun '26
Simon Jakobi pushed to branch wip/sjakobi/T21176-integer-bits at Glasgow Haskell Compiler / GHC
Commits:
612095c2 by Simon Jakobi at 2026-06-15T13:53:11+02:00
Add explicit setBit/clearBit/complementBit for instance Bits Integer (#21176)
The default setBit, clearBit, and complementBit methods allocate
intermediate Integers per call. Define them explicitly via the new
integerSetBit[#], integerClearBit[#] and integerComplementBit[#], built
on the BigNat# primitives, which avoid those allocations. Allocation is not
eliminated entirely -- the negative (IN) cases would need in-place mutation,
which is left as future work.
The default methods constant-folded on literal arguments via the
integerOr/integerAnd/integerXor rules, which fold literal Integers of any
size. The explicit functions have no such rule, so they (their Word-argument
wrappers, and the Bits Integer methods) are marked INLINE to expose the
underlying primops to the simplifier; see Note [INLINE for constant folding
of bit operations]. This restores folding only on the small-int (IS) path --
large literal Integers (IP/IN) are no longer constant-folded, a minor
regression for that case. T8832 covers the IS-path folding.
The new golden-output test T21176 checks all three operations against the
default implementations across the sign/size boundaries, recording each
result plus its integerCheck validity. The base and ghc-bignum interface-
stability export goldens gain the new functions.
The main changelog entry lives in changelog.d under a new ghc-internal
section (renamed from ghc-prim).
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
11 changed files:
- + changelog.d/T21176
- changelog.d/config
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
- libraries/ghc-internal/src/GHC/Internal/Bits.hs
- testsuite/tests/interface-stability/ghc-bignum-exports.stdout
- + testsuite/tests/numeric/should_run/T21176.hs
- + testsuite/tests/numeric/should_run/T21176.stdout
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/simplCore/should_compile/T8832.hs
- testsuite/tests/simplCore/should_compile/T8832.stdout
Changes:
=====================================
changelog.d/T21176
=====================================
@@ -0,0 +1,4 @@
+section: ghc-internal
+synopsis: Give ``setBit``, ``clearBit`` and ``complementBit`` explicit definitions in ``instance Bits Integer``, backed by new ``integerSetBit[#]``, ``integerClearBit[#]`` and ``integerComplementBit[#]`` functions. These avoid the intermediate ``Integer`` allocations of the previous default methods, although allocation is not eliminated entirely — notably the negative (``IN``) cases would require in-place mutation, which is left as future work. As a trade-off, constant folding of these operations now applies only to small (machine-word-sized) literal arguments; the previous default methods folded literal ``Integer`` arguments of any size via the ``integerOr``/``integerAnd``/``integerXor`` rules.
+issues: #21176
+mrs: !7772
=====================================
changelog.d/config
=====================================
@@ -27,7 +27,7 @@ sections: {
cmm Cmm
build-tools Build tools
base ``base`` library
- ghc-prim ``ghc-prim`` library
+ ghc-internal ``ghc-internal`` library
ghc-lib ``ghc`` library
ghc-heap ``ghc-heap`` library
ghc-experimental ``ghc-experimental`` library
=====================================
libraries/base/changelog.md
=====================================
@@ -1,6 +1,7 @@
# Changelog for [`base` package](http://hackage.haskell.org/package/base)
## 4.24.0.0 *TBA*
+ * Give `setBit`, `clearBit` and `complementBit` explicit definitions in `instance Bits Integer`, reducing intermediate allocations. ([GHC #21176](https://gitlab.haskell.org/ghc/ghc/-/issues/21176))
* Add `Bounded` instances for `Double`, `Float`, `CDouble` and `CFloat`. ([CLC proposal #402](https://github.com/haskell/core-libraries-committee/issues/402))
* Ensure that `Data.List.elem` and `notElem` can be specialized even when no list fusion happens. ([CLC proposal #412)(https://github.com/haskell/core-libraries-committee/issues/412))
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
=====================================
@@ -133,6 +133,12 @@ module GHC.Internal.Bignum.Integer
, integerBit
, integerTestBit#
, integerTestBit
+ , integerSetBit#
+ , integerSetBit
+ , integerClearBit#
+ , integerClearBit
+ , integerComplementBit#
+ , integerComplementBit
, integerShiftR#
, integerShiftR
, integerShiftL#
@@ -707,6 +713,113 @@ integerTestBit# (IN x) i
integerTestBit :: Integer -> Word -> Bool
integerTestBit !i (W# n) = isTrue# (integerTestBit# i n)
+{- Note [INLINE for constant folding of bit operations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+While there are no dedicated constant-folding rules for
+integerSetBit#/integerClearBit#/integerComplementBit#, we do INLINE them (and
+their Word-argument wrappers and the corresponding Bits Integer methods) to make
+the underlying primops accessible for constant folding, e.g. so that
+`clearBit (bit 0) 0 :: Integer` folds to `IS 0#`. Test T8832 checks the folding
+for all three operations.
+-}
+
+-- | Set the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerSetBit# :: Integer -> Word# -> Integer
+{-# INLINE integerSetBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerSetBit# n@(IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `orI#` uncheckedIShiftL# 1# (word2Int# i))
+ | isTrue# (x >=# 0#)
+ = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
+ | True
+ = n
+integerSetBit# (IP x) i = IP (bigNatSetBit# x i)
+integerSetBit# (IN x) i = integerFromBigNatNeg#
+ (bigNatAddWord#
+ (bigNatClearBit# (bigNatSubWordUnsafe# x 1##) i)
+ 1##)
+
+-- | Set the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerSetBit :: Integer -> Word -> Integer
+{-# INLINE integerSetBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerSetBit !i (W# n) = integerSetBit# i n
+
+-- | Clear the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerClearBit# :: Integer -> Word# -> Integer
+{-# INLINE integerClearBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerClearBit# n@(IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `andI#` notI# (uncheckedIShiftL# 1# (word2Int# i)))
+ | isTrue# (x >=# 0#)
+ = n
+ | True
+ = IN (bigNatAddWord#
+ (bigNatSetBit#
+ (bigNatFromWord#
+ (minusWord# (int2Word# (negateInt# x)) 1##))
+ i)
+ 1##)
+integerClearBit# (IP x) i = integerFromBigNat# (bigNatClearBit# x i)
+integerClearBit# (IN x) i = IN (bigNatAddWord#
+ (bigNatSetBit# (bigNatSubWordUnsafe# x 1##) i)
+ 1##)
+
+-- | Clear the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerClearBit :: Integer -> Word -> Integer
+{-# INLINE integerClearBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerClearBit !i (W# n) = integerClearBit# i n
+
+-- | Reverse the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerComplementBit# :: Integer -> Word# -> Integer
+{-# INLINE integerComplementBit# #-} -- See Note [INLINE for constant folding of bit operations]
+integerComplementBit# (IS x) i
+ | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
+ = IS (x `xorI#` uncheckedIShiftL# 1# (word2Int# i))
+ | isTrue# (x >=# 0#)
+ = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
+ | True
+ = IN (bigNatAddWord#
+ (bigNatSetBit#
+ (bigNatFromWord# (minusWord# (int2Word# (negateInt# x)) 1##))
+ i)
+ 1##)
+integerComplementBit# (IP x) i = integerFromBigNat# (bigNatComplementBit# x i)
+integerComplementBit# (IN x) i = integerFromBigNatNeg#
+ (bigNatAddWord#
+ (bigNatComplementBit#
+ (bigNatSubWordUnsafe# x 1##)
+ i)
+ 1##)
+
+-- | Reverse the /n/-th bit.
+--
+-- Fake 2's complement for negative values (might be slow)
+--
+-- @since 10.201.0
+integerComplementBit :: Integer -> Word -> Integer
+{-# INLINE integerComplementBit #-} -- See Note [INLINE for constant folding of bit operations]
+integerComplementBit !i (W# n) = integerComplementBit# i n
+
-- | Shift-right operation
--
-- Fake 2's complement for negative values (might be slow)
=====================================
libraries/ghc-internal/src/GHC/Internal/Bits.hs
=====================================
@@ -564,6 +564,15 @@ instance Bits Integer where
| otherwise = integerShiftR x (fromIntegral (negate i))
testBit x i = integerTestBit x (fromIntegral i)
zeroBits = integerZero
+ -- INLINE on setBit/clearBit/complementBit preserves constant folding;
+ -- see Note [INLINE for constant folding of bit operations] in
+ -- GHC.Internal.Bignum.Integer.
+ setBit x i = integerSetBit x (fromIntegral i)
+ {-# INLINE setBit #-}
+ clearBit x i = integerClearBit x (fromIntegral i)
+ {-# INLINE clearBit #-}
+ complementBit x i = integerComplementBit x (fromIntegral i)
+ {-# INLINE complementBit #-}
bit (I# i) = integerBit# (int2Word# i)
popCount x = I# (integerPopCount# x)
=====================================
testsuite/tests/interface-stability/ghc-bignum-exports.stdout
=====================================
@@ -201,8 +201,12 @@ module GHC.Num.Integer where
integerBit# :: GHC.Internal.Prim.Word# -> Integer
integerCheck :: Integer -> GHC.Internal.Types.Bool
integerCheck# :: Integer -> GHC.Internal.Bignum.Primitives.Bool#
+ integerClearBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerClearBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerCompare :: Integer -> Integer -> GHC.Internal.Types.Ordering
integerComplement :: Integer -> Integer
+ integerComplementBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerComplementBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerDecodeDouble# :: GHC.Internal.Prim.Double# -> (# Integer, GHC.Internal.Prim.Int# #)
integerDiv :: Integer -> Integer -> Integer
integerDivMod :: Integer -> Integer -> (Integer, Integer)
@@ -266,6 +270,8 @@ module GHC.Num.Integer where
integerQuotRem# :: Integer -> Integer -> (# Integer, Integer #)
integerRecipMod# :: Integer -> GHC.Internal.Bignum.Natural.Natural -> (# GHC.Internal.Bignum.Natural.Natural | () #)
integerRem :: Integer -> Integer -> Integer
+ integerSetBit :: Integer -> GHC.Internal.Types.Word -> Integer
+ integerSetBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerShiftL :: Integer -> GHC.Internal.Types.Word -> Integer
integerShiftL# :: Integer -> GHC.Internal.Prim.Word# -> Integer
integerShiftR :: Integer -> GHC.Internal.Types.Word -> Integer
=====================================
testsuite/tests/numeric/should_run/T21176.hs
=====================================
@@ -0,0 +1,38 @@
+module Main where
+
+import Data.Bits
+import Data.Int (Int32, Int64)
+import Data.Foldable (for_)
+import GHC.Num.Integer (integerCheck)
+
+integers :: [Integer]
+integers = concatMap neighbours [minInt64, minInt32, 0, maxInt32, maxInt64]
+ where
+ neighbours i = [i - 2, i - 1, i, i + 1, i + 2]
+ minInt64 = toInteger (minBound :: Int64)
+ minInt32 = toInteger (minBound :: Int32)
+ maxInt32 = toInteger (maxBound :: Int32)
+ maxInt64 = toInteger (maxBound :: Int64)
+
+bits :: [Int]
+bits = [0, 1, x - 1, x, x + 1]
+ where x = finiteBitSize (0 :: Int) - 1
+
+testXBit :: String -> (Integer -> Int -> Integer) -> (Integer -> Int -> Integer) -> IO ()
+testXBit name f model = do
+ putStrLn name
+ for_ integers $ \i ->
+ for_ bits $ \b -> do
+ let actual = f i b
+ expected = model i b
+ valid = if integerCheck actual then "valid" else "invalid"
+ matches = if actual == expected then "matches" else "differs"
+ putStrLn $ " " ++ show i ++ " " ++ show b ++ " -> " ++ show actual
+ ++ " [" ++ valid ++ ", " ++ matches ++ "]"
+ putStrLn ""
+
+main :: IO ()
+main = do
+ testXBit "setBit" setBit (\i b -> i .|. bit b)
+ testXBit "clearBit" clearBit (\i b -> i .&. complement (bit b))
+ testXBit "complementBit" complementBit (\i b -> i `xor` bit b)
=====================================
testsuite/tests/numeric/should_run/T21176.stdout
=====================================
@@ -0,0 +1,381 @@
+setBit
+ -9223372036854775810 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 62 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 63 -> -2 [valid, matches]
+ -9223372036854775810 64 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 62 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 63 -> -1 [valid, matches]
+ -9223372036854775809 64 -> -9223372036854775809 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775808 62 -> -4611686018427387904 [valid, matches]
+ -9223372036854775808 63 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 64 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775805 [valid, matches]
+ -9223372036854775807 62 -> -4611686018427387903 [valid, matches]
+ -9223372036854775807 63 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 64 -> -9223372036854775807 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775805 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 62 -> -4611686018427387902 [valid, matches]
+ -9223372036854775806 63 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 64 -> -9223372036854775806 [valid, matches]
+ -2147483650 0 -> -2147483649 [valid, matches]
+ -2147483650 1 -> -2147483650 [valid, matches]
+ -2147483650 62 -> -2147483650 [valid, matches]
+ -2147483650 63 -> -2147483650 [valid, matches]
+ -2147483650 64 -> -2147483650 [valid, matches]
+ -2147483649 0 -> -2147483649 [valid, matches]
+ -2147483649 1 -> -2147483649 [valid, matches]
+ -2147483649 62 -> -2147483649 [valid, matches]
+ -2147483649 63 -> -2147483649 [valid, matches]
+ -2147483649 64 -> -2147483649 [valid, matches]
+ -2147483648 0 -> -2147483647 [valid, matches]
+ -2147483648 1 -> -2147483646 [valid, matches]
+ -2147483648 62 -> -2147483648 [valid, matches]
+ -2147483648 63 -> -2147483648 [valid, matches]
+ -2147483648 64 -> -2147483648 [valid, matches]
+ -2147483647 0 -> -2147483647 [valid, matches]
+ -2147483647 1 -> -2147483645 [valid, matches]
+ -2147483647 62 -> -2147483647 [valid, matches]
+ -2147483647 63 -> -2147483647 [valid, matches]
+ -2147483647 64 -> -2147483647 [valid, matches]
+ -2147483646 0 -> -2147483645 [valid, matches]
+ -2147483646 1 -> -2147483646 [valid, matches]
+ -2147483646 62 -> -2147483646 [valid, matches]
+ -2147483646 63 -> -2147483646 [valid, matches]
+ -2147483646 64 -> -2147483646 [valid, matches]
+ -2 0 -> -1 [valid, matches]
+ -2 1 -> -2 [valid, matches]
+ -2 62 -> -2 [valid, matches]
+ -2 63 -> -2 [valid, matches]
+ -2 64 -> -2 [valid, matches]
+ -1 0 -> -1 [valid, matches]
+ -1 1 -> -1 [valid, matches]
+ -1 62 -> -1 [valid, matches]
+ -1 63 -> -1 [valid, matches]
+ -1 64 -> -1 [valid, matches]
+ 0 0 -> 1 [valid, matches]
+ 0 1 -> 2 [valid, matches]
+ 0 62 -> 4611686018427387904 [valid, matches]
+ 0 63 -> 9223372036854775808 [valid, matches]
+ 0 64 -> 18446744073709551616 [valid, matches]
+ 1 0 -> 1 [valid, matches]
+ 1 1 -> 3 [valid, matches]
+ 1 62 -> 4611686018427387905 [valid, matches]
+ 1 63 -> 9223372036854775809 [valid, matches]
+ 1 64 -> 18446744073709551617 [valid, matches]
+ 2 0 -> 3 [valid, matches]
+ 2 1 -> 2 [valid, matches]
+ 2 62 -> 4611686018427387906 [valid, matches]
+ 2 63 -> 9223372036854775810 [valid, matches]
+ 2 64 -> 18446744073709551618 [valid, matches]
+ 2147483645 0 -> 2147483645 [valid, matches]
+ 2147483645 1 -> 2147483647 [valid, matches]
+ 2147483645 62 -> 4611686020574871549 [valid, matches]
+ 2147483645 63 -> 9223372039002259453 [valid, matches]
+ 2147483645 64 -> 18446744075857035261 [valid, matches]
+ 2147483646 0 -> 2147483647 [valid, matches]
+ 2147483646 1 -> 2147483646 [valid, matches]
+ 2147483646 62 -> 4611686020574871550 [valid, matches]
+ 2147483646 63 -> 9223372039002259454 [valid, matches]
+ 2147483646 64 -> 18446744075857035262 [valid, matches]
+ 2147483647 0 -> 2147483647 [valid, matches]
+ 2147483647 1 -> 2147483647 [valid, matches]
+ 2147483647 62 -> 4611686020574871551 [valid, matches]
+ 2147483647 63 -> 9223372039002259455 [valid, matches]
+ 2147483647 64 -> 18446744075857035263 [valid, matches]
+ 2147483648 0 -> 2147483649 [valid, matches]
+ 2147483648 1 -> 2147483650 [valid, matches]
+ 2147483648 62 -> 4611686020574871552 [valid, matches]
+ 2147483648 63 -> 9223372039002259456 [valid, matches]
+ 2147483648 64 -> 18446744075857035264 [valid, matches]
+ 2147483649 0 -> 2147483649 [valid, matches]
+ 2147483649 1 -> 2147483651 [valid, matches]
+ 2147483649 62 -> 4611686020574871553 [valid, matches]
+ 2147483649 63 -> 9223372039002259457 [valid, matches]
+ 2147483649 64 -> 18446744075857035265 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775805 62 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 63 -> 18446744073709551613 [valid, matches]
+ 9223372036854775805 64 -> 27670116110564327421 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 62 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 63 -> 18446744073709551614 [valid, matches]
+ 9223372036854775806 64 -> 27670116110564327422 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 62 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 63 -> 18446744073709551615 [valid, matches]
+ 9223372036854775807 64 -> 27670116110564327423 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775810 [valid, matches]
+ 9223372036854775808 62 -> 13835058055282163712 [valid, matches]
+ 9223372036854775808 63 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 64 -> 27670116110564327424 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775811 [valid, matches]
+ 9223372036854775809 62 -> 13835058055282163713 [valid, matches]
+ 9223372036854775809 63 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 64 -> 27670116110564327425 [valid, matches]
+
+clearBit
+ -9223372036854775810 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775812 [valid, matches]
+ -9223372036854775810 62 -> -13835058055282163714 [valid, matches]
+ -9223372036854775810 63 -> -9223372036854775810 [valid, matches]
+ -9223372036854775810 64 -> -27670116110564327426 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775811 [valid, matches]
+ -9223372036854775809 62 -> -13835058055282163713 [valid, matches]
+ -9223372036854775809 63 -> -9223372036854775809 [valid, matches]
+ -9223372036854775809 64 -> -27670116110564327425 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 62 -> -9223372036854775808 [valid, matches]
+ -9223372036854775808 63 -> -18446744073709551616 [valid, matches]
+ -9223372036854775808 64 -> -27670116110564327424 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 62 -> -9223372036854775807 [valid, matches]
+ -9223372036854775807 63 -> -18446744073709551615 [valid, matches]
+ -9223372036854775807 64 -> -27670116110564327423 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775806 62 -> -9223372036854775806 [valid, matches]
+ -9223372036854775806 63 -> -18446744073709551614 [valid, matches]
+ -9223372036854775806 64 -> -27670116110564327422 [valid, matches]
+ -2147483650 0 -> -2147483650 [valid, matches]
+ -2147483650 1 -> -2147483652 [valid, matches]
+ -2147483650 62 -> -4611686020574871554 [valid, matches]
+ -2147483650 63 -> -9223372039002259458 [valid, matches]
+ -2147483650 64 -> -18446744075857035266 [valid, matches]
+ -2147483649 0 -> -2147483650 [valid, matches]
+ -2147483649 1 -> -2147483651 [valid, matches]
+ -2147483649 62 -> -4611686020574871553 [valid, matches]
+ -2147483649 63 -> -9223372039002259457 [valid, matches]
+ -2147483649 64 -> -18446744075857035265 [valid, matches]
+ -2147483648 0 -> -2147483648 [valid, matches]
+ -2147483648 1 -> -2147483648 [valid, matches]
+ -2147483648 62 -> -4611686020574871552 [valid, matches]
+ -2147483648 63 -> -9223372039002259456 [valid, matches]
+ -2147483648 64 -> -18446744075857035264 [valid, matches]
+ -2147483647 0 -> -2147483648 [valid, matches]
+ -2147483647 1 -> -2147483647 [valid, matches]
+ -2147483647 62 -> -4611686020574871551 [valid, matches]
+ -2147483647 63 -> -9223372039002259455 [valid, matches]
+ -2147483647 64 -> -18446744075857035263 [valid, matches]
+ -2147483646 0 -> -2147483646 [valid, matches]
+ -2147483646 1 -> -2147483648 [valid, matches]
+ -2147483646 62 -> -4611686020574871550 [valid, matches]
+ -2147483646 63 -> -9223372039002259454 [valid, matches]
+ -2147483646 64 -> -18446744075857035262 [valid, matches]
+ -2 0 -> -2 [valid, matches]
+ -2 1 -> -4 [valid, matches]
+ -2 62 -> -4611686018427387906 [valid, matches]
+ -2 63 -> -9223372036854775810 [valid, matches]
+ -2 64 -> -18446744073709551618 [valid, matches]
+ -1 0 -> -2 [valid, matches]
+ -1 1 -> -3 [valid, matches]
+ -1 62 -> -4611686018427387905 [valid, matches]
+ -1 63 -> -9223372036854775809 [valid, matches]
+ -1 64 -> -18446744073709551617 [valid, matches]
+ 0 0 -> 0 [valid, matches]
+ 0 1 -> 0 [valid, matches]
+ 0 62 -> 0 [valid, matches]
+ 0 63 -> 0 [valid, matches]
+ 0 64 -> 0 [valid, matches]
+ 1 0 -> 0 [valid, matches]
+ 1 1 -> 1 [valid, matches]
+ 1 62 -> 1 [valid, matches]
+ 1 63 -> 1 [valid, matches]
+ 1 64 -> 1 [valid, matches]
+ 2 0 -> 2 [valid, matches]
+ 2 1 -> 0 [valid, matches]
+ 2 62 -> 2 [valid, matches]
+ 2 63 -> 2 [valid, matches]
+ 2 64 -> 2 [valid, matches]
+ 2147483645 0 -> 2147483644 [valid, matches]
+ 2147483645 1 -> 2147483645 [valid, matches]
+ 2147483645 62 -> 2147483645 [valid, matches]
+ 2147483645 63 -> 2147483645 [valid, matches]
+ 2147483645 64 -> 2147483645 [valid, matches]
+ 2147483646 0 -> 2147483646 [valid, matches]
+ 2147483646 1 -> 2147483644 [valid, matches]
+ 2147483646 62 -> 2147483646 [valid, matches]
+ 2147483646 63 -> 2147483646 [valid, matches]
+ 2147483646 64 -> 2147483646 [valid, matches]
+ 2147483647 0 -> 2147483646 [valid, matches]
+ 2147483647 1 -> 2147483645 [valid, matches]
+ 2147483647 62 -> 2147483647 [valid, matches]
+ 2147483647 63 -> 2147483647 [valid, matches]
+ 2147483647 64 -> 2147483647 [valid, matches]
+ 2147483648 0 -> 2147483648 [valid, matches]
+ 2147483648 1 -> 2147483648 [valid, matches]
+ 2147483648 62 -> 2147483648 [valid, matches]
+ 2147483648 63 -> 2147483648 [valid, matches]
+ 2147483648 64 -> 2147483648 [valid, matches]
+ 2147483649 0 -> 2147483648 [valid, matches]
+ 2147483649 1 -> 2147483649 [valid, matches]
+ 2147483649 62 -> 2147483649 [valid, matches]
+ 2147483649 63 -> 2147483649 [valid, matches]
+ 2147483649 64 -> 2147483649 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775804 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 62 -> 4611686018427387901 [valid, matches]
+ 9223372036854775805 63 -> 9223372036854775805 [valid, matches]
+ 9223372036854775805 64 -> 9223372036854775805 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775804 [valid, matches]
+ 9223372036854775806 62 -> 4611686018427387902 [valid, matches]
+ 9223372036854775806 63 -> 9223372036854775806 [valid, matches]
+ 9223372036854775806 64 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775807 62 -> 4611686018427387903 [valid, matches]
+ 9223372036854775807 63 -> 9223372036854775807 [valid, matches]
+ 9223372036854775807 64 -> 9223372036854775807 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 62 -> 9223372036854775808 [valid, matches]
+ 9223372036854775808 63 -> 0 [valid, matches]
+ 9223372036854775808 64 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 62 -> 9223372036854775809 [valid, matches]
+ 9223372036854775809 63 -> 1 [valid, matches]
+ 9223372036854775809 64 -> 9223372036854775809 [valid, matches]
+
+complementBit
+ -9223372036854775810 0 -> -9223372036854775809 [valid, matches]
+ -9223372036854775810 1 -> -9223372036854775812 [valid, matches]
+ -9223372036854775810 62 -> -13835058055282163714 [valid, matches]
+ -9223372036854775810 63 -> -2 [valid, matches]
+ -9223372036854775810 64 -> -27670116110564327426 [valid, matches]
+ -9223372036854775809 0 -> -9223372036854775810 [valid, matches]
+ -9223372036854775809 1 -> -9223372036854775811 [valid, matches]
+ -9223372036854775809 62 -> -13835058055282163713 [valid, matches]
+ -9223372036854775809 63 -> -1 [valid, matches]
+ -9223372036854775809 64 -> -27670116110564327425 [valid, matches]
+ -9223372036854775808 0 -> -9223372036854775807 [valid, matches]
+ -9223372036854775808 1 -> -9223372036854775806 [valid, matches]
+ -9223372036854775808 62 -> -4611686018427387904 [valid, matches]
+ -9223372036854775808 63 -> -18446744073709551616 [valid, matches]
+ -9223372036854775808 64 -> -27670116110564327424 [valid, matches]
+ -9223372036854775807 0 -> -9223372036854775808 [valid, matches]
+ -9223372036854775807 1 -> -9223372036854775805 [valid, matches]
+ -9223372036854775807 62 -> -4611686018427387903 [valid, matches]
+ -9223372036854775807 63 -> -18446744073709551615 [valid, matches]
+ -9223372036854775807 64 -> -27670116110564327423 [valid, matches]
+ -9223372036854775806 0 -> -9223372036854775805 [valid, matches]
+ -9223372036854775806 1 -> -9223372036854775808 [valid, matches]
+ -9223372036854775806 62 -> -4611686018427387902 [valid, matches]
+ -9223372036854775806 63 -> -18446744073709551614 [valid, matches]
+ -9223372036854775806 64 -> -27670116110564327422 [valid, matches]
+ -2147483650 0 -> -2147483649 [valid, matches]
+ -2147483650 1 -> -2147483652 [valid, matches]
+ -2147483650 62 -> -4611686020574871554 [valid, matches]
+ -2147483650 63 -> -9223372039002259458 [valid, matches]
+ -2147483650 64 -> -18446744075857035266 [valid, matches]
+ -2147483649 0 -> -2147483650 [valid, matches]
+ -2147483649 1 -> -2147483651 [valid, matches]
+ -2147483649 62 -> -4611686020574871553 [valid, matches]
+ -2147483649 63 -> -9223372039002259457 [valid, matches]
+ -2147483649 64 -> -18446744075857035265 [valid, matches]
+ -2147483648 0 -> -2147483647 [valid, matches]
+ -2147483648 1 -> -2147483646 [valid, matches]
+ -2147483648 62 -> -4611686020574871552 [valid, matches]
+ -2147483648 63 -> -9223372039002259456 [valid, matches]
+ -2147483648 64 -> -18446744075857035264 [valid, matches]
+ -2147483647 0 -> -2147483648 [valid, matches]
+ -2147483647 1 -> -2147483645 [valid, matches]
+ -2147483647 62 -> -4611686020574871551 [valid, matches]
+ -2147483647 63 -> -9223372039002259455 [valid, matches]
+ -2147483647 64 -> -18446744075857035263 [valid, matches]
+ -2147483646 0 -> -2147483645 [valid, matches]
+ -2147483646 1 -> -2147483648 [valid, matches]
+ -2147483646 62 -> -4611686020574871550 [valid, matches]
+ -2147483646 63 -> -9223372039002259454 [valid, matches]
+ -2147483646 64 -> -18446744075857035262 [valid, matches]
+ -2 0 -> -1 [valid, matches]
+ -2 1 -> -4 [valid, matches]
+ -2 62 -> -4611686018427387906 [valid, matches]
+ -2 63 -> -9223372036854775810 [valid, matches]
+ -2 64 -> -18446744073709551618 [valid, matches]
+ -1 0 -> -2 [valid, matches]
+ -1 1 -> -3 [valid, matches]
+ -1 62 -> -4611686018427387905 [valid, matches]
+ -1 63 -> -9223372036854775809 [valid, matches]
+ -1 64 -> -18446744073709551617 [valid, matches]
+ 0 0 -> 1 [valid, matches]
+ 0 1 -> 2 [valid, matches]
+ 0 62 -> 4611686018427387904 [valid, matches]
+ 0 63 -> 9223372036854775808 [valid, matches]
+ 0 64 -> 18446744073709551616 [valid, matches]
+ 1 0 -> 0 [valid, matches]
+ 1 1 -> 3 [valid, matches]
+ 1 62 -> 4611686018427387905 [valid, matches]
+ 1 63 -> 9223372036854775809 [valid, matches]
+ 1 64 -> 18446744073709551617 [valid, matches]
+ 2 0 -> 3 [valid, matches]
+ 2 1 -> 0 [valid, matches]
+ 2 62 -> 4611686018427387906 [valid, matches]
+ 2 63 -> 9223372036854775810 [valid, matches]
+ 2 64 -> 18446744073709551618 [valid, matches]
+ 2147483645 0 -> 2147483644 [valid, matches]
+ 2147483645 1 -> 2147483647 [valid, matches]
+ 2147483645 62 -> 4611686020574871549 [valid, matches]
+ 2147483645 63 -> 9223372039002259453 [valid, matches]
+ 2147483645 64 -> 18446744075857035261 [valid, matches]
+ 2147483646 0 -> 2147483647 [valid, matches]
+ 2147483646 1 -> 2147483644 [valid, matches]
+ 2147483646 62 -> 4611686020574871550 [valid, matches]
+ 2147483646 63 -> 9223372039002259454 [valid, matches]
+ 2147483646 64 -> 18446744075857035262 [valid, matches]
+ 2147483647 0 -> 2147483646 [valid, matches]
+ 2147483647 1 -> 2147483645 [valid, matches]
+ 2147483647 62 -> 4611686020574871551 [valid, matches]
+ 2147483647 63 -> 9223372039002259455 [valid, matches]
+ 2147483647 64 -> 18446744075857035263 [valid, matches]
+ 2147483648 0 -> 2147483649 [valid, matches]
+ 2147483648 1 -> 2147483650 [valid, matches]
+ 2147483648 62 -> 4611686020574871552 [valid, matches]
+ 2147483648 63 -> 9223372039002259456 [valid, matches]
+ 2147483648 64 -> 18446744075857035264 [valid, matches]
+ 2147483649 0 -> 2147483648 [valid, matches]
+ 2147483649 1 -> 2147483651 [valid, matches]
+ 2147483649 62 -> 4611686020574871553 [valid, matches]
+ 2147483649 63 -> 9223372039002259457 [valid, matches]
+ 2147483649 64 -> 18446744075857035265 [valid, matches]
+ 9223372036854775805 0 -> 9223372036854775804 [valid, matches]
+ 9223372036854775805 1 -> 9223372036854775807 [valid, matches]
+ 9223372036854775805 62 -> 4611686018427387901 [valid, matches]
+ 9223372036854775805 63 -> 18446744073709551613 [valid, matches]
+ 9223372036854775805 64 -> 27670116110564327421 [valid, matches]
+ 9223372036854775806 0 -> 9223372036854775807 [valid, matches]
+ 9223372036854775806 1 -> 9223372036854775804 [valid, matches]
+ 9223372036854775806 62 -> 4611686018427387902 [valid, matches]
+ 9223372036854775806 63 -> 18446744073709551614 [valid, matches]
+ 9223372036854775806 64 -> 27670116110564327422 [valid, matches]
+ 9223372036854775807 0 -> 9223372036854775806 [valid, matches]
+ 9223372036854775807 1 -> 9223372036854775805 [valid, matches]
+ 9223372036854775807 62 -> 4611686018427387903 [valid, matches]
+ 9223372036854775807 63 -> 18446744073709551615 [valid, matches]
+ 9223372036854775807 64 -> 27670116110564327423 [valid, matches]
+ 9223372036854775808 0 -> 9223372036854775809 [valid, matches]
+ 9223372036854775808 1 -> 9223372036854775810 [valid, matches]
+ 9223372036854775808 62 -> 13835058055282163712 [valid, matches]
+ 9223372036854775808 63 -> 0 [valid, matches]
+ 9223372036854775808 64 -> 27670116110564327424 [valid, matches]
+ 9223372036854775809 0 -> 9223372036854775808 [valid, matches]
+ 9223372036854775809 1 -> 9223372036854775811 [valid, matches]
+ 9223372036854775809 62 -> 13835058055282163713 [valid, matches]
+ 9223372036854775809 63 -> 1 [valid, matches]
+ 9223372036854775809 64 -> 27670116110564327425 [valid, matches]
+
=====================================
testsuite/tests/numeric/should_run/all.T
=====================================
@@ -101,3 +101,4 @@ test('T24245', normal, compile_and_run, [''])
test('T25653', normal, compile_and_run, [''])
test('T18619', exit_code(1), compile_and_run, [''])
test('T26230', normal, compile_and_run, [''])
+test('T21176', normal, compile_and_run, [''])
=====================================
testsuite/tests/simplCore/should_compile/T8832.hs
=====================================
@@ -23,3 +23,9 @@ T(w32,Word32)
T(w64,Word64)
T(z,Integer)
+
+zset :: Integer
+zset = setBit (bit 0) 0
+
+zcompl :: Integer
+zcompl = complementBit (bit 0) 0
=====================================
testsuite/tests/simplCore/should_compile/T8832.stdout
=====================================
@@ -8,4 +8,6 @@ w8 = GHC.Internal.Word.W8# 0#Word8
w16 = GHC.Internal.Word.W16# 0#Word16
w32 = GHC.Internal.Word.W32# 0#Word32
w64 = GHC.Internal.Word.W64# 0#Word64
-z = GHC.Internal.Bignum.Integer.IS 0#
+zcompl = GHC.Internal.Bignum.Integer.IS 0#
+zset = GHC.Internal.Bignum.Integer.IS 1#
+z = zcompl
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612095c20fb41fe0243f10cc013227e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612095c20fb41fe0243f10cc013227e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/sort-usages] 34 commits: fix typo : compete with performance, not complete
by Wolfgang Jeltsch (@jeltsch) 15 Jun '26
by Wolfgang Jeltsch (@jeltsch) 15 Jun '26
15 Jun '26
Wolfgang Jeltsch pushed to branch wip/sort-usages at Glasgow Haskell Compiler / GHC
Commits:
f2f5c6ba by Nikita Efremov at 2026-06-02T16:04:54+00:00
fix typo : compete with performance, not complete
- - - - -
5524ea0e by Wolfgang Jeltsch at 2026-06-03T08:01:26-04:00
Make the current `base` buildable with GHC 9.14
This comprises the following changes:
* Disable some imports into `GHC.Base` for GHC 9.14
* Disable some imports into `Prelude` for GHC 9.14
* Disable separate `ArrowLoop` import for GHC 9.14
* Disable `GHC.Internal.STM` import for GHC 9.14
* Disable `GHC.Internal.Unicode.Version` import for GHC 9.14
* Disable `GHC.Internal.TH.Monad` import for GHC 9.14
* Add alternative `fixIO` import for GHC 9.14
* Add alternative `unsafeCodeCoerce` import for GHC 9.14
* Disable hiding of imported SIMD operations for GHC 9.14
* Disable use of GHC 9.14’s `printToHandleFinalizerExceptionHandler`
* Enable use of `getFileHash` from `ghc-internal` for GHC 9.14
* Make `thenA` available for GHC 9.14
* Make `thenM` available for GHC 9.14
* Disable translation of `IoManagerFlagPoll` for GHC 9.14
* Add `hGetNewlineMode` for GHC 9.14
- - - - -
d3438055 by Enrico Maria De Angelis at 2026-06-03T08:02:17-04:00
Fix #27067 - Clarify haddocks on `minusNaturalMaybe`
- - - - -
f9bcfac2 by sheaf at 2026-06-03T14:47:19-04:00
Avoid mkTick in Core Prep breaking ANF
As discovered in #27182, mkTick can break ANF. This patch introduces a
variant of mkTick that skips the single optimisation that could break
ANF. This is preferrable over switching to the raw Tick constructor,
as the latter may introduce spurious cost centres in profiling reports.
This is a temporary measure until we more thoroughly refactor how
mkTick works (see #27141).
See Note [mkTick breaks ANF] in GHC.CoreToStg.Prep.
Fixes #27182
- - - - -
cf1fd661 by Artem Pelenitsyn at 2026-06-03T14:48:09-04:00
clarify comment for getSizeofMutableByteArray#: we get the size in bytes, not "elements"
- - - - -
a3b431f3 by David Eichmann at 2026-06-04T10:10:19+00:00
Hadrian: convert env variable ACLOCAL_PATH to unix paths.
Convert ACLOCAL_PATH to a unix style path when invoking autoreconf.
Autoreconf doesn't handle windows paths.
See Note [Autoreconf unix paths from ACLOCAL_PATH].
Fixes #27311
- - - - -
18f6138a by Simon Jakobi at 2026-06-04T20:20:31-04:00
testsuite: Deduplicate --only test names
config.only is assumed to be a set, but supplying --only overwrote it
with the (list) argparse result, which can contain duplicates. When a
test ran, config.only.remove(name) dropped only the first occurrence,
so a duplicated name lingered and was later misreported as a
"test not found" framework failure. Store it as a set instead.
Fixes #27322
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
2f3cc9ff by Simon Jakobi at 2026-06-08T07:55:49-04:00
testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
The ghc-bignum package was merged into ghc-internal, so the BIGNUM_GMP
probe in test.mk ran `ghc-pkg field ghc-bignum exposed-modules`, which
fails with "cannot find package ghc-bignum". That error went to stderr
and leaked into the captured stderr of every makefile_test, causing
spurious [bad stderr] failures across the suite. The probe also silently
returned empty, so config.have_fast_bignum was wrongly False even on GMP
builds.
Probe ghc-internal's extra-libraries for the gmp library instead: the
GMP backend module is an other-module (not exposed), but GMP_LIBS adds
gmp to extra-libraries only on a GMP build, so this distinguishes the
backends. Redirect stderr to keep any future missing-package error off
the harness's stderr.
This also removes a stale comment as per suggestion from hsyl20.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
eb3bf6e7 by Alan Zimmerman at 2026-06-08T07:56:32-04:00
EPA: Rename Transform.anchorEof to addModuleCommentOrigDeltas
This now matches what it actually does.
- - - - -
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
333df444 by sheaf at 2026-06-10T05:10:25-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
98c20394 by sheaf at 2026-06-10T05:11:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
5ac9ce7d by Zubin Duggal at 2026-06-10T21:26:32+05:30
hadrian: Remove old package.conf files when generating new ones
Old package.conf files might exists with different hashes, causing issues like #26661
Fixes #26661
- - - - -
c9015f09 by sheaf at 2026-06-11T12:40:28-04:00
Fix AArch64 clobbering bug for MUL2
On AArch64, the code generator could clobber one of the input operands
when computing the lower bits of a MUL2 operation. This rendered invalid
the subsequent computation of the high bits.
This commit fixes that by using a temporary register. The register
allocator can remove the redundant move in the common case when the
registers do not conflict.
Fixes #27046
- - - - -
7ab90288 by Rodrigo Mesquita at 2026-06-11T12:41:11-04:00
fix: make T27131 less flaky
It seems that T27131 fails flakily in a race where we check the flag
before the capability had the chance to process the mailbox which sets
the flag. This seemingly should only happen if the capability ends up
being the same for setting and checking the flag.
- - - - -
8965cb76 by Marc Scholten at 2026-06-12T04:53:22-04:00
haddock: render modules concurrently
- - - - -
8cc0b64a by Duncan Coutts at 2026-06-12T04:54:06-04:00
Promote HAVE_PREEMPTION from Timer.c to OSThreads.h
We will want to know about HAVE_PREEMPTION in more places.
HAVE_PREEMPTION tells us that we do have OS threads available,
irrespective of whether THREADED is defined. In particular,
HAVE_PREEMPTION is defined on all proper OSs, but not on WASM (and
hyopthetically may not be true on some other platforms like
micro-controllers, RTOSs, VM hypervisors etc).
- - - - -
cce574ed by Duncan Coutts at 2026-06-12T04:54:06-04:00
Define ACQUIRE_LOCK_ALWAYS and friends
Fix issue #27335
Like the atomic _ALWAYS variants, these lock actions are always defined,
rather than being dependent on whether we are in the THREADED case. All
the "normal" LOCK macros are defined to be no-ops when !THREADED.
The use case for the _ALWAYS variants is where we are using OS threads
even in the non-threaded RTS. This includes everything to do with the
timer/ticker thread, which is used in the non-threaded RTS too.
In particular, we will want to use this for eventlog things, because the
timer thread performs eventlogging concurrently with the main
capability, even in the non-threaded RTS.
- - - - -
1f28d1f6 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Use ACQUIRE/RELEASE_LOCK_ALWAYS with eventBufMutex
Even in the non-threaded RTS the eventBufMutex is needed by both the
main capability and the timer/ticker thread, so always use the mutex.
This should fix #25165 which is about the main capability and the timer
thread posting events to the eventlog buffer concurrently and thereby
corrupting the buffer data.
- - - - -
0ff29782 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Expose eventBufMutex in the EventLog interface/header
We will need it in forkProcess to ensure we don't write to the global
eventlog buffer concurrently with trying to flush eventlog buffers and
do the fork().
- - - - -
7a688395 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Split flushAllCapsEventsBufs into safe and unlocked version
Following the convention that unlocked versions have a trailing _
underscore in their name. This one requires the caller to hold the
eventlog global buffer mutex. We will need this in forkProcess.
- - - - -
341ed474 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in setNumCapabilities
Historically, the comment here was:
We must stop the interval timer while we are changing the
capabilities array lest handle_tick may try to context switch
an old capability. See #17289.
and
We must disable the timer while we do this since the tick handler may
call contextSwitchAllCapabilities, which may see the capabilities array
as we free it.
What this refers to is that historically, when changing the number of
capabilities, the array of capabilities was reallocated to a new size,
allocating new ones and freeing the old ones, thus invalidating all
existing capbility pointers.
Strangely, for good measure the code used to call stopTimer twice (hence
the two similar comments above).
However, since commit a3eccf06292dd666b24606251a52da2b466a9612, the
capabilities array is no longer reallocated. Instead the array is
allcoated once on RTS startup to the maximum size it could ever be
allowed to be, and then capabilities get enabled/disabled at runtime. So
the capability pointers never become invalid anymore. At worst, they may
point to capabilities that are disabled.
Thus we no longer need to stop the timer (twice) while we change the
number of enabled capabilities. This also partially solves issue #27105,
which notes that stopTimer is being used as if it were synchronous, when
it is not. At least for this case, the solution is that stopTimer is not
needed at all!
- - - - -
674858e3 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in forkProcess
but replace it with taking the eventlog buffer lock during the fork.
Fixes issue #27105
The original reason to block the timer during a fork was that
historically the timer was implemented using a periodic timer signal,
and the signal itself would interrupt the fork system call (returning
EINTR). For large processes (where fork() takes a while) this could
permanently livelock: the timer always would go off before the fork
could complete, which got retried in a loop forever.
The timer is no longer implemented as a unix signal, but uses threads.
Thus the original problem no longer exists. The only remaining reason to
block the timer tick is to prevent actions taken by the tick from
interfering with the delicate process involved in fork (taking a load of
locks and pausing everything).
The only thing we need to do is to prevent the eventlog from being
written to or flushed while the fork is taking place. To achieve this
all we need to do is hold the mutex for the global eventlog buffer.
This removes the last use of stopTimer that expects stopTimer to work
synchronously (which it was not) and thus solves issue #27105. To be
clear, we solve issue #27105 not by making stopTimer synchronous, but by
eliminating the use sites that expected it to be synchronous.
- - - - -
40764930 by sheaf at 2026-06-12T14:54:43-04:00
Add type family performance test for #26426
Some GHC versions produced large numbers of coercions after typechecking
and desugaring when compiling the program in #26426:
Version | Typechecker time | Typechecker allocations | Coercions
-------:|-----------------:|------------------------:|---------:
9.6 | 47 ms | 48 MB | 110k
9.8 | 1000 ms | 486 MB | 10,437k
9.10 | 922 ms | 489 MB | 10,436k
9.12 | 906 ms | 482 MB | 10,437k
9.14 | 63 ms | 55 MB | 333k
10.0 | 47 ms | 64 MB | 35k
The improvement 9.12 -> 9.14 was due to commit 22d11fa818fae2c95c494fc0fac1f8cb4c6e7cb6,
while the improvement 9.14 -> 10.0 was due to commit 0b7df6db9e46df40e86fbff1a66dc10440b99db5.
As the behaviour of GHC seems better than it's ever been on this program,
we declare victory, adding this performance test to ensure we don't
regress on this program.
On the way, we update Note [Combining equalities] in GHC.Tc.SolveR.Equality
with the explanation of the 9.12 -> 9.14 improvement (getting rid of an
exponential blowup in coercion sizes), and we update
Note [Exploiting closed type families] in GHC.Tc.Solver.FunDeps with
the explanation of the 9.14 -> 10.0 improvement (bringing down coercion
size growth from cubic to quadratic).
- - - - -
0f3d0a71 by Zubin Duggal at 2026-06-12T14:55:30-04:00
compiler: mark tool messages as errors/warnings depending on the exit code
Fixes #27370
- - - - -
d9ea2d76 by mangoiv at 2026-06-13T04:41:51-04:00
libraries/process: bump submodule to v1.6.30.0
- bump the submodule to the appropriate tag
- suppress benign warning resulting from the change
- - - - -
6ebaaba3 by David Eichmann at 2026-06-13T04:42:37-04:00
ghc-toolchain: don't throw when candidate executables are not found
Fixes #27369
- - - - -
6c65e1e1 by David Eichmann at 2026-06-13T04:43:23-04:00
CI: lint-changelog checks for no-changelog label in script instead of rules
- - - - -
b69b707a by Ian-Woo Kim at 2026-06-15T13:42:25+02:00
Make the order of usages deterministic
It has been observed that the ordering of usages can be non-determinstic
in parallel builds. Therefore, this contribution introduces sorting of
usages based on a platform- and race-independent sorting criterion.
Resolves #26877.
Co-authored-by: Wolfgang Jeltsch <wolfgang(a)well-typed.com>
- - - - -
524ade3f by Wolfgang Jeltsch at 2026-06-15T13:42:40+02:00
Change the descriptions of two existing changelog entries
The descriptions now describe the changes in a user-friendly manner, as
opposed to describing the contributions that led to these changes in a
developer-friendly manner.
- - - - -
108 changed files:
- .gitlab-ci.yml
- boot
- + changelog.d/T27046
- + changelog.d/T27182.md
- + changelog.d/T27225
- + changelog.d/T27317
- + changelog.d/T27359
- + changelog.d/deterministic-usage-order
- changelog.d/hadrian-response-files.md
- + changelog.d/hadrian-stale-package-confs-26661
- changelog.d/module-graph-reuse-in-downsweep
- changelog.d/more-efficient-home-unit-imports-finding
- + changelog.d/tool-messages-27370
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Utils/Logger.hs
- docs/users_guide/javascript.rst
- docs/users_guide/using.rst
- hadrian/build-cabal
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Arrow.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- libraries/base/src/Data/Fixed.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/src/GHC/Conc/Sync.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/GHC/Weak.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/System/Mem/Weak.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- libraries/ghc-internal/src/GHC/Internal/Natural.hs
- libraries/process
- rts/Capability.c
- rts/Schedule.c
- rts/Timer.c
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/include/rts/OSThreads.h
- testsuite/driver/runtests.py
- testsuite/driver/testlib.py
- testsuite/mk/test.mk
- + testsuite/tests/codeGen/should_run/T27046.hs
- + testsuite/tests/codeGen/should_run/T27046_cmm.cmm
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/driver/T27370/Makefile
- + testsuite/tests/driver/T27370/T27370.hs
- + testsuite/tests/driver/T27370/T27370.pp
- + testsuite/tests/driver/T27370/T27370.stderr
- + testsuite/tests/driver/T27370/all.T
- + testsuite/tests/perf/compiler/T26426.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/profiling/should_compile/T27182.hs
- testsuite/tests/profiling/should_compile/all.T
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- testsuite/tests/rts/T27131.hs
- testsuite/tests/rts/T27131.stdout
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/all.T
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml.hs
- utils/haddock/haddock-api/src/Haddock/Options.hs
- utils/haddock/haddock-api/src/Haddock/Utils.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f49f411f5a429f2a2b725e5a025c9e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f49f411f5a429f2a2b725e5a025c9e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Drop `preloadClosure` from `UnitState`
by Marge Bot (@marge-bot) 15 Jun '26
by Marge Bot (@marge-bot) 15 Jun '26
15 Jun '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
b5d7db73 by fendor at 2026-06-15T07:25:31-04:00
Drop `preloadClosure` from `UnitState`
It is always hard-coded to the same value.
Backpack Unit instantiation isn't using it any more.
Allows us to simplify the API and get rid of `improveUnit`.
- - - - -
c74424c6 by ARATA Mizuki at 2026-06-15T07:25:37-04:00
RISC-V NCG: Zero-extend the result of castFloatToWord32
According to the ISA manual, FMV.X.W sign-extends the result.
We need to truncate the result to avoid creating an exotic Word32 value.
Fixes #27300
- - - - -
8bf2acba by ARATA Mizuki at 2026-06-15T07:25:37-04:00
RISC-V NCG: Treat d28-d31 (ft8-ft11) as caller-saved
According to the calling convention, the registers d28-d31 (ft8-ft11) are caller-saved.
Fixes #27306
- - - - -
f28947ed by ARATA Mizuki at 2026-06-15T07:25:37-04:00
RISC-V NCG: Set rounding mode when emitting `truncate`
If we omit the rounding mode for `fcvt`, `dyn` will be used.
We do not want that for `truncate`, so we set `rtz`.
In other places, we set `rne` because we do not use the dynamic rounding mode.
Fixes #27303
- - - - -
4bb7a7be by Zubin Duggal at 2026-06-15T07:25:38-04:00
rts: fix validate build with gcc 16. `__attribute__((regparm(1)))` is ignored on x86_64 and now
gcc warns that it is ignored:
rts/sm/Evac.h:35:1: error:
error: ‘regparm’ attribute ignored [-Werror=attributes]
See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=ccead81bbc39668376eb5cf47066a…
Fixes #27366
- - - - -
14 changed files:
- + changelog.d/T27308
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/Regs.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- rts/sm/Evac.h
- testsuite/tests/codeGen/should_run/T16617.hs
- testsuite/tests/codeGen/should_run/T16617.stdout
Changes:
=====================================
changelog.d/T27308
=====================================
@@ -0,0 +1,10 @@
+section: compiler
+synopsis: Drop `preloadClosure` from `UnitState`
+issues: #27308
+mrs: !16108
+
+description: {
+ Drop `preloadClosure` from `UnitState` as it is always set to the empty set.
+ This allows to simplify the `UnitState` and related functions.
+}
+
=====================================
compiler/GHC/CmmToAsm/RV64/CodeGen.hs
=====================================
@@ -718,7 +718,7 @@ getRegister' config plat expr =
( \dst ->
code
`appOL` code_x
- `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg_x)) -- (Signed ConVerT Float)
+ `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg_x) Rne) -- (Signed ConVerT Float)
)
MO_SF_Round from to ->
pure
@@ -726,7 +726,7 @@ getRegister' config plat expr =
(floatFormat to)
( \dst ->
code
- `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg)) -- (Signed ConVerT Float)
+ `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg) Rne) -- (Signed ConVerT Float)
)
-- TODO: Can this case happen?
MO_FS_Truncate from to
@@ -738,7 +738,7 @@ getRegister' config plat expr =
code
`snocOL`
-- W32 is the smallest width to convert to. Decrease width afterwards.
- annExpr expr (FCVT FloatToInt (OpReg W32 dst) (OpReg from reg))
+ annExpr expr (FCVT FloatToInt (OpReg W32 dst) (OpReg from reg) Rtz)
`appOL` signExtendAdjustPrecission W32 to dst dst -- (float convert (-> zero) signed)
)
MO_FS_Truncate from to ->
@@ -747,7 +747,7 @@ getRegister' config plat expr =
(intFormat to)
( \dst ->
code
- `snocOL` annExpr expr (FCVT FloatToInt (OpReg to dst) (OpReg from reg))
+ `snocOL` annExpr expr (FCVT FloatToInt (OpReg to dst) (OpReg from reg) Rtz)
`appOL` truncateReg from to dst -- (float convert (-> zero) signed)
)
MO_UU_Conv from to
@@ -769,9 +769,18 @@ getRegister' config plat expr =
`appOL` truncateReg from to dst
)
MO_SS_Conv from to -> ss_conv from to reg code
- MO_FF_Conv from to -> return $ Any (floatFormat to) (\dst -> code `snocOL` annExpr e (FCVT FloatToFloat (OpReg to dst) (OpReg from reg)))
+ MO_FF_Conv from to -> return $ Any (floatFormat to) (\dst -> code `snocOL` annExpr e (FCVT FloatToFloat (OpReg to dst) (OpReg from reg) Rne))
MO_WF_Bitcast w -> return $ Any (floatFormat w) (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg))
- MO_FW_Bitcast w -> return $ Any (intFormat w) (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg))
+ MO_FW_Bitcast w ->
+ return
+ $ Any
+ (intFormat w)
+ ( \dst ->
+ code
+ `snocOL` MOV (OpReg w dst) (OpReg w reg)
+ -- FMV.X.W sign-extends the value, so truncate the result
+ `appOL` truncateReg W64 w dst
+ )
-- Conversions
-- TODO: Duplication with MO_UU_Conv
=====================================
compiler/GHC/CmmToAsm/RV64/Instr.hs
=====================================
@@ -106,7 +106,7 @@ regUsageOfInstr platform instr = case instr of
LDR _ dst src -> usage (regOp src, regOp dst)
LDRU _ dst src -> usage (regOp src, regOp dst)
FENCE _ _ -> usage ([], [])
- FCVT _variant dst src -> usage (regOp src, regOp dst)
+ FCVT _variant dst src _rm -> usage (regOp src, regOp dst)
FABS dst src -> usage (regOp src, regOp dst)
FMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
FMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
@@ -165,6 +165,7 @@ callerSavedRegisters =
++ map regSingle [t3RegNo .. t6RegNo]
++ map regSingle [ft0RegNo .. ft7RegNo]
++ map regSingle [fa0RegNo .. fa7RegNo]
+ ++ map regSingle [ft8RegNo .. ft11RegNo]
-- | Apply a given mapping to all the register references in this instruction.
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
@@ -205,7 +206,7 @@ patchRegsOfInstr instr env = case instr of
LDR f o1 o2 -> LDR f (patchOp o1) (patchOp o2)
LDRU f o1 o2 -> LDRU f (patchOp o1) (patchOp o2)
FENCE o1 o2 -> FENCE o1 o2
- FCVT variant o1 o2 -> FCVT variant (patchOp o1) (patchOp o2)
+ FCVT variant o1 o2 rm -> FCVT variant (patchOp o1) (patchOp o2) rm
FABS o1 o2 -> FABS (patchOp o1) (patchOp o2)
FMIN o1 o2 o3 -> FMIN (patchOp o1) (patchOp o2) (patchOp o3)
FMAX o1 o2 o3 -> FMAX (patchOp o1) (patchOp o2) (patchOp o3)
@@ -612,7 +613,7 @@ data Instr
-- Memory barrier.
FENCE FenceType FenceType
| -- | Floating point conversion
- FCVT FcvtVariant Operand Operand
+ FCVT FcvtVariant Operand Operand RoundingMode
| -- | Floating point ABSolute value
FABS Operand Operand
@@ -636,6 +637,21 @@ data FenceType = FenceRead | FenceWrite | FenceReadWrite
-- | Variant of a floating point conversion instruction
data FcvtVariant = FloatToFloat | IntToFloat | FloatToInt
+-- | The rounding mode associated with an instruction
+data RoundingMode
+ = -- | Round to nearest, ties to even
+ Rne
+ | -- | Round toward zero
+ Rtz
+ | -- | Round downward (toward negative infinity)
+ Rdn
+ | -- | Round upward (toward positive infinity)
+ Rup
+ | -- | Round to nearest, ties to max magnitude
+ Rmm
+ | -- | Dynamic rounding mode
+ Dyn
+
instrCon :: Instr -> String
instrCon i =
case i of
=====================================
compiler/GHC/CmmToAsm/RV64/Ppr.hs
=====================================
@@ -406,6 +406,17 @@ pprReg w r = case r of
-- no support for widths > W64.
| otherwise = pprPanic "Unsupported width in register (max is 64)" (ppr w <+> int i)
+-- | Pretty print a rounding mode
+--
+-- If the rounding mode is omitted, 'dyn' will be used.
+pprRm :: IsLine doc => RoundingMode -> doc
+pprRm Rne = text "rne"
+pprRm Rtz = text "rtz"
+pprRm Rdn = text "rdn"
+pprRm Rup = text "rup"
+pprRm Rmm = text "rmm"
+pprRm Dyn = text "dyn"
+
-- | Single precission `Operand` (floating-point)
isSingleOp :: Operand -> Bool
isSingleOp (OpReg W32 _) = True
@@ -643,25 +654,26 @@ pprInstr platform instr = case instr of
LDRU FF64 o1 o2@(OpAddr (AddrRegImm _ _)) -> op2 (text "\tfld") o1 o2
LDRU f o1 o2 -> pprPanic "Unsupported unsigned load" ((text . show) f <+> pprOp platform o1 <+> pprOp platform o2)
FENCE r w -> line $ text "\tfence" <+> pprFenceType r <> char ',' <+> pprFenceType w
- FCVT FloatToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.s.d") o1 o2
- FCVT FloatToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.d.s") o1 o2
- FCVT FloatToFloat o1 o2 ->
+ FCVT FloatToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) rm -> op2rm (text "\tfcvt.s.d") o1 o2 rm
+ -- The assembler seems to be unhappy with explicit rounding mode on fcvt.d.s
+ FCVT FloatToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) _rm -> op2 (text "\tfcvt.d.s") o1 o2
+ FCVT FloatToFloat o1 o2 rm ->
pprPanic "RV64.pprInstr - impossible float to float conversion"
- $ line (pprOp platform o1 <> text "->" <> pprOp platform o2)
- FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.s.w") o1 o2
- FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.s.l") o1 o2
- FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.d.w") o1 o2
- FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.d.l") o1 o2
- FCVT IntToFloat o1 o2 ->
+ $ line (pprOp platform o1 <> text "->" <> pprOp platform o2 <> text "," <> pprRm rm)
+ FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W32 _) rm -> op2rm (text "\tfcvt.s.w") o1 o2 rm
+ FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) rm -> op2rm (text "\tfcvt.s.l") o1 o2 rm
+ FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) rm -> op2rm (text "\tfcvt.d.w") o1 o2 rm
+ FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W64 _) rm -> op2rm (text "\tfcvt.d.l") o1 o2 rm
+ FCVT IntToFloat o1 o2 rm ->
pprPanic "RV64.pprInstr - impossible integer to float conversion"
- $ line (pprOp platform o1 <> text "->" <> pprOp platform o2)
- FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.w.s") o1 o2
- FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.w.d") o1 o2
- FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.l.s") o1 o2
- FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.l.d") o1 o2
- FCVT FloatToInt o1 o2 ->
+ $ line (pprOp platform o1 <> text "->" <> pprOp platform o2 <> text "," <> pprRm rm)
+ FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W32 _) rm -> op2rm (text "\tfcvt.w.s") o1 o2 rm
+ FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W64 _) rm -> op2rm (text "\tfcvt.w.d") o1 o2 rm
+ FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W32 _) rm -> op2rm (text "\tfcvt.l.s") o1 o2 rm
+ FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W64 _) rm -> op2rm (text "\tfcvt.l.d") o1 o2 rm
+ FCVT FloatToInt o1 o2 rm ->
pprPanic "RV64.pprInstr - impossible float to integer conversion"
- $ line (pprOp platform o1 <> text "->" <> pprOp platform o2)
+ $ line (pprOp platform o1 <> text "->" <> pprOp platform o2 <> text "," <> pprRm rm)
FABS o1 o2 | isSingleOp o2 -> op2 (text "\tfabs.s") o1 o2
FABS o1 o2 | isDoubleOp o2 -> op2 (text "\tfabs.d") o1 o2
FMIN o1 o2 o3 | isSingleOp o1 -> op3 (text "\tfmin.s") o1 o2 o3
@@ -678,6 +690,8 @@ pprInstr platform instr = case instr of
instr -> panic $ "RV64.pprInstr - Unknown instruction: " ++ instrCon instr
where
op2 op o1 o2 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2
+ op2rm op o1 o2 Dyn = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2
+ op2rm op o1 o2 rm = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprRm rm
op3 op o1 o2 o3 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3
op4 op o1 o2 o3 o4 = line $ op <+> pprOp platform o1 <> comma <+> pprOp platform o2 <> comma <+> pprOp platform o3 <> comma <+> pprOp platform o4
pprFenceType FenceRead = text "r"
=====================================
compiler/GHC/CmmToAsm/RV64/Regs.hs
=====================================
@@ -53,9 +53,14 @@ d7RegNo, ft7RegNo :: RegNo
d7RegNo = 39
ft7RegNo = d7RegNo
+d28RegNo, ft8RegNo :: RegNo
+d28RegNo = 60
+ft8RegNo = d28RegNo
+
-- | Last floating point register.
-d31RegNo :: RegNo
+d31RegNo, ft11RegNo :: RegNo
d31RegNo = 63
+ft11RegNo = d31RegNo
a0RegNo, x10RegNo :: RegNo
x10RegNo = 10
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -242,7 +242,6 @@ withBkpSession cid insts deps session_type do_this = do
-- Synthesize the flags
, packageFlags = packageFlags dflags ++ map (\(uid0, rn) ->
let uid = unwireUnit unit_state
- $ improveUnit unit_state
$ renameHoleUnit unit_state (listToUFM insts) uid0
in ExposePackage
(showSDoc dflags
@@ -311,19 +310,16 @@ buildUnit session cid insts lunit = do
-- The compilation dependencies are just the appropriately filled
-- in unit IDs which must be compiled before we can compile.
let hsubst = listToUFM insts
- deps0 = map (renameHoleUnit (hsc_units hsc_env) hsubst) raw_deps
+ deps = map (renameHoleUnit (hsc_units hsc_env) hsubst) raw_deps
-- Build dependencies OR make sure they make sense. BUT NOTE,
-- we can only check the ones that are fully filled; the rest
-- we have to defer until we've typechecked our local signature.
-- TODO: work this into GHC.Driver.Make!!
- forM_ (zip [1..] deps0) $ \(i, dep) ->
+ forM_ (zip [1..] deps) $ \(i, dep) ->
case session of
TcSession -> return ()
- _ -> compileInclude (length deps0) (i, dep)
-
- -- IMPROVE IT
- let deps = map (improveUnit (hsc_units hsc_env)) deps0
+ _ -> compileInclude (length deps) (i, dep)
mb_old_eps <- case session of
TcSession -> fmap Just getEpsGhc
=====================================
compiler/GHC/Iface/Load.hs
=====================================
@@ -914,13 +914,13 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
&& not (isOneShot (ghcMode dflags))
then return (Failed (HomeModError mod loc))
else do
- r <- read_file hooks logger name_cache unit_state dflags wanted_mod (ml_hi_file loc)
+ r <- read_file hooks logger name_cache dflags wanted_mod (ml_hi_file loc)
case r of
Failed err
-> return (Failed $ BadIfaceFile err)
Succeeded (iface,_fp)
-> do
- r2 <- load_dynamic_too_maybe hooks logger name_cache unit_state
+ r2 <- load_dynamic_too_maybe hooks logger name_cache
(setDynamicNow dflags) wanted_mod
iface loc
case r2 of
@@ -936,20 +936,20 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do
err
-- | Check if we need to try the dynamic interface for -dynamic-too
-load_dynamic_too_maybe :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
+load_dynamic_too_maybe :: Hooks -> Logger -> NameCache -> DynFlags
-> Module -> ModIface -> ModLocation
-> IO (MaybeErr MissingInterfaceError ())
-load_dynamic_too_maybe hooks logger name_cache unit_state dflags wanted_mod iface loc
+load_dynamic_too_maybe hooks logger name_cache dflags wanted_mod iface loc
-- Indefinite interfaces are ALWAYS non-dynamic.
| not (moduleIsDefinite (mi_module iface)) = return (Succeeded ())
- | gopt Opt_BuildDynamicToo dflags = load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc
+ | gopt Opt_BuildDynamicToo dflags = load_dynamic_too hooks logger name_cache dflags wanted_mod iface loc
| otherwise = return (Succeeded ())
-load_dynamic_too :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
+load_dynamic_too :: Hooks -> Logger -> NameCache -> DynFlags
-> Module -> ModIface -> ModLocation
-> IO (MaybeErr MissingInterfaceError ())
-load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc = do
- read_file hooks logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case
+load_dynamic_too hooks logger name_cache dflags wanted_mod iface loc = do
+ read_file hooks logger name_cache dflags wanted_mod (ml_dyn_hi_file loc) >>= \case
Succeeded (dynIface, _)
| mi_mod_hash iface == mi_mod_hash dynIface
-> return (Succeeded ())
@@ -963,10 +963,10 @@ load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc
-read_file :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags
+read_file :: Hooks -> Logger -> NameCache -> DynFlags
-> Module -> FilePath
-> IO (MaybeErr ReadInterfaceError (ModIface, FilePath))
-read_file hooks logger name_cache unit_state dflags wanted_mod file_path = do
+read_file hooks logger name_cache dflags wanted_mod file_path = do
-- Figure out what is recorded in mi_module. If this is
-- a fully definite interface, it'll match exactly, but
@@ -975,7 +975,7 @@ read_file hooks logger name_cache unit_state dflags wanted_mod file_path = do
case getModuleInstantiation wanted_mod of
(_, Nothing) -> wanted_mod
(_, Just indef_mod) ->
- instModuleToModule unit_state
+ instModuleToModule
(uninstantiateInstantiatedModule indef_mod)
read_result <- readIface hooks logger dflags name_cache wanted_mod' file_path
case read_result of
=====================================
compiler/GHC/Iface/Recomp.hs
=====================================
@@ -620,7 +620,7 @@ checkMergedSignatures hsc_env mod_summary self_recomp = do
new_merged = case lookupUniqMap (requirementContext unit_state)
(ms_mod_name mod_summary) of
Nothing -> []
- Just r -> sort $ map (instModuleToModule unit_state) r
+ Just r -> sort $ map instModuleToModule r
if old_merged == new_merged
then up_to_date logger (text "signatures to merge in unchanged" $$ ppr new_merged)
else return $ needsRecompileBecause SigsMergeChanged
=====================================
compiler/GHC/Unit.hs
=====================================
@@ -226,8 +226,8 @@ on-the-fly:
A 'VirtUnit' may be indefinite or definite, it depends on whether some holes
remain in the instantiated unit OR in the instantiating units (recursively).
Having a fully instantiated (i.e. definite) virtual unit can lead to some issues
-if there is a matching compiled unit in the preload closure. See Note [VirtUnit
-to RealUnit improvement]
+if there is a matching compiled unit in the preload closure.
+See Note [VirtUnit to RealUnit improvement]
Unit database and indefinite units
----------------------------------
@@ -314,7 +314,6 @@ field in the SDocContext to pretty-print.
(i.e. GHC doesn't correctly call `pprWithUnitState` before pretty-printing a
UnitId), that's what will be shown to the user so it's no big deal.
-
Note [VirtUnit to RealUnit improvement]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -332,6 +331,8 @@ same type-checking session, their names won't match (e.g. "abc:M.X" vs
As we want them to match we just replace the virtual unit with the installed
one: for some reason this is called "improvement".
+HISTORICAL:
+
There is one last niggle: improvement based on the unit database means
that we might end up developing on a unit that is not transitively
depended upon by the units the user specified directly via command line
@@ -340,6 +341,12 @@ instantiations are out of date. The solution is to only improve a
unit id if the new unit id is part of the 'preloadClosure'; i.e., the
closure of all the units which were explicitly specified.
+NOTE:
+
+The 'preloadClosure' was completely unused, thus we removed it without
+changing any of the tests. It doesn't seem to be necessary any more.
+It is unclear at which exact point this became redundant.
+
Note [Representation of module/name variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In our ICFP'16, we use <A> to represent module holes, and {A.T} to represent
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -7,7 +7,6 @@ module GHC.Unit.State (
-- * Reading the package config, and processing cmdline args
UnitState(..),
- PreloadUnitClosure,
UnitDatabase (..),
UnitErr (..),
emptyUnitState,
@@ -29,7 +28,6 @@ module GHC.Unit.State (
lookupPackageName,
resolvePackageImport,
- improveUnit,
searchPackageId,
listVisibleModuleNames,
lookupModuleInAllUnits,
@@ -89,7 +87,6 @@ import GHC.Unit.Home
import GHC.Types.Unique.FM
import GHC.Types.Unique.DFM
-import GHC.Types.Unique.Set
import GHC.Types.Unique.DSet
import GHC.Types.Unique.Map
import GHC.Types.Unique
@@ -268,8 +265,6 @@ originEmpty :: ModuleOrigin -> Bool
originEmpty (ModOrigin Nothing [] [] False) = True
originEmpty _ = False
-type PreloadUnitClosure = UniqSet UnitId
-
-- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'.
type VisibilityMap = UniqMap Unit UnitVisibility
@@ -432,13 +427,6 @@ data UnitState = UnitState {
-- may have the 'exposed' flag be 'False'.)
unitInfoMap :: UnitInfoMap,
- -- | The set of transitively reachable units according
- -- to the explicitly provided command line arguments.
- -- A fully instantiated VirtUnit may only be replaced by a RealUnit from
- -- this set.
- -- See Note [VirtUnit to RealUnit improvement]
- preloadClosure :: PreloadUnitClosure,
-
-- | A mapping of 'PackageName' to 'UnitId'. If several units have the same
-- package name (e.g. different instantiations), then we return one of them...
-- This is used when users refer to packages in Backpack includes.
@@ -491,7 +479,6 @@ data UnitState = UnitState {
emptyUnitState :: UnitState
emptyUnitState = UnitState {
unitInfoMap = emptyUniqMap,
- preloadClosure = emptyUniqSet,
packageNameMap = emptyUFM,
wireMap = emptyUniqMap,
unwireMap = emptyUniqMap,
@@ -517,7 +504,7 @@ type UnitInfoMap = UniqMap UnitId UnitInfo
-- | Find the unit we know about with the given unit, if any
lookupUnit :: UnitState -> Unit -> Maybe UnitInfo
-lookupUnit pkgs = lookupUnit' (allowVirtualUnits pkgs) (unitInfoMap pkgs) (preloadClosure pkgs)
+lookupUnit pkgs = lookupUnit' (allowVirtualUnits pkgs) (unitInfoMap pkgs)
-- | A more specialized interface, which doesn't require a 'UnitState' (so it
-- can be used while we're initializing 'DynFlags')
@@ -525,16 +512,15 @@ lookupUnit pkgs = lookupUnit' (allowVirtualUnits pkgs) (unitInfoMap pkgs) (prelo
-- Parameters:
-- * a boolean specifying whether or not to look for on-the-fly renamed interfaces
-- * a 'UnitInfoMap'
--- * a 'PreloadUnitClosure'
-lookupUnit' :: Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo
-lookupUnit' allowOnTheFlyInst pkg_map closure u = case u of
+lookupUnit' :: Bool -> UnitInfoMap -> Unit -> Maybe UnitInfo
+lookupUnit' allowOnTheFlyInst pkg_map u = case u of
HoleUnit -> error "Hole unit"
RealUnit i -> lookupUniqMap pkg_map (unDefinite i)
VirtUnit i
| allowOnTheFlyInst
-> -- lookup UnitInfo of the indefinite unit to be instantiated and
-- instantiate it on-the-fly
- fmap (renameUnitInfo pkg_map closure (instUnitInsts i))
+ fmap (renameUnitInfo pkg_map (instUnitInsts i))
(lookupUniqMap pkg_map (instUnitInstanceOf i))
| otherwise
@@ -908,7 +894,6 @@ applyTrustFlag prec_map unusable pkgs flag =
applyPackageFlag
:: UnitPrecedenceMap
-> UnitInfoMap
- -> PreloadUnitClosure
-> UnusableUnits
-> Bool -- if False, if you expose a package, it implicitly hides
-- any previously exposed packages with the same name
@@ -917,10 +902,10 @@ applyPackageFlag
-> PackageFlag -- flag to apply
-> MaybeErr UnitErr VisibilityMap -- Now exposed
-applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag =
+applyPackageFlag prec_map pkg_map unusable no_hide_others pkgs vm flag =
case flag of
ExposePackage _ arg (ModRenaming b rns) ->
- case findPackages prec_map pkg_map closure arg pkgs unusable of
+ case findPackages prec_map pkg_map arg pkgs unusable of
Left ps -> Failed (PackageFlagErr flag ps)
Right (p:_) -> Succeeded vm'
where
@@ -984,7 +969,7 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag =
_ -> panic "applyPackageFlag"
HidePackage str ->
- case findPackages prec_map pkg_map closure (PackageArg str) pkgs unusable of
+ case findPackages prec_map pkg_map (PackageArg str) pkgs unusable of
Left ps -> Failed (PackageFlagErr flag ps)
Right ps -> Succeeded $ foldl' delFromUniqMap vm (map mkUnit ps)
@@ -993,12 +978,11 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag =
-- if the 'UnitArg' has a renaming associated with it.
findPackages :: UnitPrecedenceMap
-> UnitInfoMap
- -> PreloadUnitClosure
-> PackageArg -> [UnitInfo]
-> UnusableUnits
-> Either [(UnitInfo, UnusableUnitReason)]
[UnitInfo]
-findPackages prec_map pkg_map closure arg pkgs unusable
+findPackages prec_map pkg_map arg pkgs unusable
= let ps = mapMaybe (finder arg) pkgs
in if null ps
then Left (mapMaybe (\(x,y) -> finder arg x >>= \x' -> return (x',y))
@@ -1016,7 +1000,7 @@ findPackages prec_map pkg_map closure arg pkgs unusable
-> Just p
VirtUnit inst
| instUnitInstanceOf inst == unitId p
- -> Just (renameUnitInfo pkg_map closure (instUnitInsts inst) p)
+ -> Just (renameUnitInfo pkg_map (instUnitInsts inst) p)
_ -> Nothing
selectPackages :: UnitPrecedenceMap -> PackageArg -> [UnitInfo]
@@ -1031,10 +1015,10 @@ selectPackages prec_map arg pkgs unusable
else Right (sortByPreference prec_map ps, rest)
-- | Rename a 'UnitInfo' according to some module instantiation.
-renameUnitInfo :: UnitInfoMap -> PreloadUnitClosure -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
-renameUnitInfo pkg_map closure insts conf =
+renameUnitInfo :: UnitInfoMap -> [(ModuleName, Module)] -> UnitInfo -> UnitInfo
+renameUnitInfo pkg_map insts conf =
let hsubst = listToUFM insts
- smod = renameHoleModule' pkg_map closure hsubst
+ smod = renameHoleModule' pkg_map hsubst
new_insts = map (\(k,v) -> (k,smod v)) (unitInstantiations conf)
in conf {
unitInstantiations = new_insts,
@@ -1632,7 +1616,7 @@ mkUnitState logger cfg = do
-- user tries to enable an unusable package, we should let them know.
--
vis_map2 <- mayThrowUnitErr
- $ foldM (applyPackageFlag prec_map prelim_pkg_db emptyUniqSet unusable
+ $ foldM (applyPackageFlag prec_map prelim_pkg_db unusable
(unitConfigHideAll cfg) pkgs1)
vis_map1 other_flags
@@ -1661,7 +1645,7 @@ mkUnitState logger cfg = do
| otherwise = vis_map2
plugin_vis_map2
<- mayThrowUnitErr
- $ foldM (applyPackageFlag prec_map prelim_pkg_db emptyUniqSet unusable
+ $ foldM (applyPackageFlag prec_map prelim_pkg_db unusable
hide_plugin_pkgs pkgs1)
plugin_vis_map1
(reverse (unitConfigFlagsPlugins cfg))
@@ -1713,7 +1697,7 @@ mkUnitState logger cfg = do
$ closeUnitDeps pkg_db
$ zip (map toUnitId preload3) (repeat Nothing)
- let mod_map1 = mkModuleNameProvidersMap logger cfg pkg_db emptyUniqSet vis_map
+ let mod_map1 = mkModuleNameProvidersMap logger cfg pkg_db vis_map
mod_map2 = mkUnusableModuleNameProvidersMap unusable
mod_map = mod_map2 `plusUniqMap` mod_map1
@@ -1723,9 +1707,8 @@ mkUnitState logger cfg = do
, explicitUnits = explicit_pkgs
, homeUnitDepends = home_unit_deps
, unitInfoMap = pkg_db
- , preloadClosure = emptyUniqSet
, moduleNameProvidersMap = mod_map
- , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger cfg pkg_db emptyUniqSet plugin_vis_map
+ , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger cfg pkg_db plugin_vis_map
, packageNameMap = pkgname_map
, wireMap = wired_map
, unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
@@ -1765,10 +1748,9 @@ mkModuleNameProvidersMap
:: Logger
-> UnitConfig
-> UnitInfoMap
- -> PreloadUnitClosure
-> VisibilityMap
-> ModuleNameProvidersMap
-mkModuleNameProvidersMap logger cfg pkg_map closure vis_map =
+mkModuleNameProvidersMap logger cfg pkg_map vis_map =
-- What should we fold on? Both situations are awkward:
--
-- * Folding on the visibility map means that we won't create
@@ -1840,7 +1822,7 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map =
hiddens = [(m, mkModMap pk m ModHidden) | m <- hidden_mods]
pk = mkUnit pkg
- unit_lookup uid = lookupUnit' (unitConfigAllowVirtual cfg) pkg_map closure uid
+ unit_lookup uid = lookupUnit' (unitConfigAllowVirtual cfg) pkg_map uid
`orElse` pprPanic "unit_lookup" (ppr uid)
exposed_mods = unitExposedModules pkg
@@ -2191,44 +2173,16 @@ fsPackageName info = fs
where
PackageName fs = unitPackageName info
-
--- | Given a fully instantiated 'InstantiatedUnit', improve it into a
--- 'RealUnit' if we can find it in the package database.
-improveUnit :: UnitState -> Unit -> Unit
-improveUnit state u = improveUnit' (unitInfoMap state) (preloadClosure state) u
-
--- | Given a fully instantiated 'InstantiatedUnit', improve it into a
--- 'RealUnit' if we can find it in the package database.
-improveUnit' :: UnitInfoMap -> PreloadUnitClosure -> Unit -> Unit
-improveUnit' _ _ uid@(RealUnit _) = uid -- short circuit
-improveUnit' pkg_map closure uid =
- -- Do NOT lookup indefinite ones, they won't be useful!
- case lookupUnit' False pkg_map closure uid of
- Nothing -> uid
- Just pkg ->
- -- Do NOT improve if the indefinite unit id is not
- -- part of the closure unique set. See
- -- Note [VirtUnit to RealUnit improvement]
- if unitId pkg `elementOfUniqSet` closure
- then mkUnit pkg
- else uid
-
--- | Check the database to see if we already have an installed unit that
--- corresponds to the given 'InstantiatedUnit'.
---
--- Return a `UnitId` which either wraps the `InstantiatedUnit` unchanged or
--- references a matching installed unit.
---
--- See Note [VirtUnit to RealUnit improvement]
-instUnitToUnit :: UnitState -> InstantiatedUnit -> Unit
-instUnitToUnit state iuid =
+-- | Return a `UnitId` which either wraps the `InstantiatedUnit` unchanged.
+instUnitToUnit :: InstantiatedUnit -> Unit
+instUnitToUnit iuid =
-- NB: suppose that we want to compare the instantiated
-- unit p[H=impl:H] against p+abcd (where p+abcd
-- happens to be the existing, installed version of
-- p[H=impl:H]. If we *only* wrap in p[H=impl:H]
-- VirtUnit, they won't compare equal; only
-- after improvement will the equality hold.
- improveUnit state $ VirtUnit iuid
+ VirtUnit iuid
-- | Substitution on module variables, mapping module names to module
@@ -2240,30 +2194,30 @@ type ShHoleSubst = ModuleNameEnv Module
-- @p[A=\<A>]:B@ maps to @p[A=q():A]:B@ with @A=q():A@;
-- similarly, @\<A>@ maps to @q():A@.
renameHoleModule :: UnitState -> ShHoleSubst -> Module -> Module
-renameHoleModule state = renameHoleModule' (unitInfoMap state) (preloadClosure state)
+renameHoleModule state = renameHoleModule' (unitInfoMap state)
-- | Substitutes holes in a 'Unit', suitable for renaming when
-- an include occurs; see Note [Representation of module/name variables].
--
-- @p[A=\<A>]@ maps to @p[A=\<B>]@ with @A=\<B>@.
renameHoleUnit :: UnitState -> ShHoleSubst -> Unit -> Unit
-renameHoleUnit state = renameHoleUnit' (unitInfoMap state) (preloadClosure state)
+renameHoleUnit state = renameHoleUnit' (unitInfoMap state)
--- | Like 'renameHoleModule', but requires only 'ClosureUnitInfoMap'
+-- | Like 'renameHoleModule', but requires only 'UnitInfoMap'
-- so it can be used by "GHC.Unit.State".
-renameHoleModule' :: UnitInfoMap -> PreloadUnitClosure -> ShHoleSubst -> Module -> Module
-renameHoleModule' pkg_map closure env m
+renameHoleModule' :: UnitInfoMap -> ShHoleSubst -> Module -> Module
+renameHoleModule' pkg_map env m
| not (isHoleModule m) =
- let uid = renameHoleUnit' pkg_map closure env (moduleUnit m)
+ let uid = renameHoleUnit' pkg_map env (moduleUnit m)
in mkModule uid (moduleName m)
| Just m' <- lookupUFM env (moduleName m) = m'
-- NB m = <Blah>, that's what's in scope.
| otherwise = m
--- | Like 'renameHoleUnit, but requires only 'ClosureUnitInfoMap'
+-- | Like 'renameHoleUnit', but requires only 'UnitInfoMap'
-- so it can be used by "GHC.Unit.State".
-renameHoleUnit' :: UnitInfoMap -> PreloadUnitClosure -> ShHoleSubst -> Unit -> Unit
-renameHoleUnit' pkg_map closure env uid =
+renameHoleUnit' :: UnitInfoMap -> ShHoleSubst -> Unit -> Unit
+renameHoleUnit' pkg_map env uid =
case uid of
(VirtUnit
InstantiatedUnit{ instUnitInstanceOf = cid
@@ -2271,20 +2225,15 @@ renameHoleUnit' pkg_map closure env uid =
, instUnitHoles = fh })
-> if isNullUFM (intersectUFM_C const (udfmToUfm (getUniqDSet fh)) env)
then uid
- -- Functorially apply the substitution to the instantiation,
- -- then check the 'ClosureUnitInfoMap' to see if there is
- -- a compiled version of this 'InstantiatedUnit' we can improve to.
- -- See Note [VirtUnit to RealUnit improvement]
- else improveUnit' pkg_map closure $
- mkVirtUnit cid
- (map (\(k,v) -> (k, renameHoleModule' pkg_map closure env v)) insts)
+ else mkVirtUnit cid
+ (map (\(k,v) -> (k, renameHoleModule' pkg_map env v)) insts)
_ -> uid
-- | Injects an 'InstantiatedModule' to 'Module' (see also
-- 'instUnitToUnit'.
-instModuleToModule :: UnitState -> InstantiatedModule -> Module
-instModuleToModule pkgstate (Module iuid mod_name) =
- mkModule (instUnitToUnit pkgstate iuid) mod_name
+instModuleToModule :: InstantiatedModule -> Module
+instModuleToModule (Module iuid mod_name) =
+ mkModule (instUnitToUnit iuid) mod_name
-- | Print unit-ids with UnitInfo found in the given UnitState
pprWithUnitState :: UnitState -> SDoc -> SDoc
=====================================
compiler/GHC/Unit/Types.hs
=====================================
@@ -250,9 +250,7 @@ data GenUnit uid
--
-- This unit may be indefinite or not (i.e. with remaining holes or not). If it
-- is definite, we don't know if it has already been compiled and installed in a
--- database. Nevertheless, we have a mechanism called "improvement" to try to
--- match a fully instantiated unit with existing compiled and installed units:
--- see Note [VirtUnit to RealUnit improvement].
+-- database.
--
-- An indefinite unit identifier pretty-prints to something like
-- @p[H=<H>,A=aimpl:A>]@ (@p@ is the 'UnitId', and the
=====================================
rts/sm/Evac.h
=====================================
@@ -25,7 +25,9 @@
// registers EAX, EDX, and ECX instead of on the stack. Functions that
// take a variable number of arguments will continue to be passed all of
// their arguments on the stack.
-#if defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH)
+// On x86-64 the attribute has no effect (the first argument is already
+// passed in a register) and GCC 16 warns that it is ignored.
+#if defined(i386_HOST_ARCH)
#define REGPARM1 __attribute__((regparm(1)))
#else
#define REGPARM1
=====================================
testsuite/tests/codeGen/should_run/T16617.hs
=====================================
@@ -1,10 +1,19 @@
import GHC.Float
+{-# OPAQUE noinline #-}
+noinline :: a -> a
+noinline x = x
+
main :: IO ()
main = do
-- As per #16617, Word32s should be non-negative
print $ castFloatToWord32 (-1)
print $ toInteger (castFloatToWord32 (-1)) > 0
+ -- Disable constant folding; see #27300
+ print $ castFloatToWord32 (noinline $ -1)
+ print $ toInteger (castFloatToWord32 (noinline $ -1)) > 0
-- For completeness, so should Word64s
print $ castDoubleToWord64 (-1)
print $ toInteger (castDoubleToWord64 (-1)) > 0
+ print $ castDoubleToWord64 (noinline $ -1)
+ print $ toInteger (castDoubleToWord64 (noinline $ -1)) > 0
=====================================
testsuite/tests/codeGen/should_run/T16617.stdout
=====================================
@@ -1,4 +1,8 @@
3212836864
True
+3212836864
+True
+13830554455654793216
+True
13830554455654793216
True
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7e992dd0b4d71c823a6ce17c3f0e0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7e992dd0b4d71c823a6ce17c3f0e0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0