[Git][ghc/ghc][wip/mp/ghc-9.10.1-determinism] determinism: Use a stable sort in WithHsDocIdentifiers binary instance
by Matthew Pickering (@mpickering) 03 Feb '26
by Matthew Pickering (@mpickering) 03 Feb '26
03 Feb '26
Matthew Pickering pushed to branch wip/mp/ghc-9.10.1-determinism at Glasgow Haskell Compiler / GHC
Commits:
06ea36f3 by Matthew Pickering at 2026-02-02T17:28:42+00:00
determinism: Use a stable sort in WithHsDocIdentifiers binary instance
`WithHsDocIdentifiers` is defined as
```
71 data WithHsDocIdentifiers a pass = WithHsDocIdentifiers
72 { hsDocString :: !a
73 , hsDocIdentifiers :: ![Located (IdP pass)]
74 }
```
This list of names is populated from `rnHsDocIdentifiers`, which calls
`lookupGRE`, which calls `lookupOccEnv_AllNameSpaces`, which calls
`nonDetEltsUFM` and returns the results in an order depending on
uniques.
Sorting the list with a stable sort before returning the interface makes
the output deterministic and follows the approach taken by other fields
in `Docs`.
Fixes #26858
- - - - -
1 changed file:
- compiler/GHC/Hs/Doc.hs
Changes:
=====================================
compiler/GHC/Hs/Doc.hs
=====================================
@@ -50,6 +50,7 @@ import qualified GHC.Utils.Outputable as O
import GHC.Hs.Extension
import GHC.Types.Unique.Map
import Data.List (sortBy)
+import Data.Function
import GHC.Hs.DocString
@@ -88,7 +89,7 @@ instance Outputable a => Outputable (WithHsDocIdentifiers a pass) where
instance Binary a => Binary (WithHsDocIdentifiers a GhcRn) where
put_ bh (WithHsDocIdentifiers s ids) = do
put_ bh s
- put_ bh $ BinLocated <$> ids
+ put_ bh $ BinLocated <$> (sortBy (stableNameCmp `on` getName) ids)
get bh =
liftA2 WithHsDocIdentifiers (get bh) (fmap unBinLocated <$> get bh)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06ea36f3018cf094c3bbbc8bbb6772c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06ea36f3018cf094c3bbbc8bbb6772c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed new branch wip/debug-join-point at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/debug-join-point
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
8d17a905 by sheaf at 2026-02-02T18:13:58+01:00
WIP: debugging
- - - - -
3 changed files:
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Types/Id.hs
- testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
Changes:
=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -1080,23 +1080,36 @@ joinPointBinding_maybe bndr rhs
-- need to demote it to a quasi join-point.
-- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
| Just orig_cat <- joinId_maybe bndr
- , AlwaysTailCalled
- { tailCallArity = _new_arity
- , tailCallJoinPointType = new_cat }
- <- tailCallInfo (idOccInfo bndr)
- = assertPpr (idJoinArity bndr == _new_arity)
- ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
- , text "bndr:" <+> ppr bndr
- , text "rhs:" <+> ppr rhs
- , text "prev arity:" <+> ppr (idJoinArity bndr)
- , text " new arity:" <+> ppr _new_arity
- , text "orig_cat:" <+> ppr orig_cat
- , text " new_cat:" <+> ppr new_cat
- ]
- ) $ Just $
- if orig_cat == new_cat
- then (bndr, rhs)
- else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
+ = case tailCallInfo (idOccInfo bndr) of
+ NoTailCallInfo ->
+ pprTrace "joinPointBinding_maybe: lost join?"
+ (vcat
+ [ text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "arity:" <+> ppr (idJoinArity bndr)
+ , text "cat:" <+> ppr orig_cat
+ , text "occ_info:" <+> ppr (idOccInfo bndr)
+ ]) $
+ -- SLD TODO: I don't understand how this can happen, but apparently
+ -- it can. For now I'm preserving the join, but further investigation
+ -- is needed.
+ Just (bndr, rhs)
+ AlwaysTailCalled
+ { tailCallArity = _new_arity
+ , tailCallJoinPointType = new_cat } ->
+ assertPpr (idJoinArity bndr == _new_arity)
+ ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
+ , text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "prev arity:" <+> ppr (idJoinArity bndr)
+ , text " new arity:" <+> ppr _new_arity
+ , text "orig_cat:" <+> ppr orig_cat
+ , text " new_cat:" <+> ppr new_cat
+ ]
+ ) $ Just $
+ if orig_cat == new_cat
+ then (bndr, rhs)
+ else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
| AlwaysTailCalled
{ tailCallArity = join_arity
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -692,10 +692,16 @@ idJoinArity id =
JoinPoint { joinPointArity = ar } -> ar
NotJoinPoint -> pprPanic "idJoinArity" (ppr id)
-asJoinId :: Id -> JoinPointCategory -> JoinArity -> JoinId
+asJoinId :: HasDebugCallStack => Id -> JoinPointCategory -> JoinArity -> JoinId
asJoinId id cat arity
= warnPprTrace (not (isLocalId id))
"global id being marked as join var" (ppr id) $
+ -- SLD TODO debugging
+ pprTrace "asJoinId"
+ ( vcat [ text "id:" <+> ppr id
+ , text "cat:" <+> ppr cat
+ , text "callstack:" <+> callStackDoc
+ ]) $
id `setIdDetails` JoinId cat arity cbv_info
where
cbv_info = case Var.idDetails id of
=====================================
testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
=====================================
@@ -133,3 +133,50 @@ testQuasiTransitivity b n =
True -> {-# SCC "ticked" #-} j3 10
False -> j3 20
)
+
+--------------------------------------------------------------------------------
+-- Extracted from a GHC bootstrapping bug
+
+data AB = A | B
+
+data Int2 = MkInt2
+
+expt :: Int2 -> Int2
+expt _ = MkInt2
+{-# NOINLINE expt #-}
+
+add :: Int2 -> Int2 -> Int2
+add _ _ = MkInt2
+{-# NOINLINE add #-}
+
+big :: Int2 -> AB
+big _ = A
+{-# NOINLINE big #-}
+
+baz :: Int2
+baz = MkInt2
+{-# NOINLINE baz #-}
+
+no :: a
+no = no
+{-# NOINLINE no #-}
+
+mul :: Int2 -> Int2 -> Int2
+mul !_ !_ = no
+{-# INLINE mul #-}
+
+data T2 a b = MkT2 a b
+
+floatToDigits2 :: T2 Int2 Int2 -> T2 Int2 Int2
+floatToDigits2 ( MkT2 f0 e0 ) =
+ let
+ MkT2 f e =
+ let n = e0
+ in
+ case big n of
+ A -> MkT2 f0 ( add e0 n )
+ B -> MkT2 f0 e0
+ r = let be = expt e in mul f be
+
+ in
+ MkT2 r baz
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d17a90585f186ee1d46776fcfc62a2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d17a90585f186ee1d46776fcfc62a2…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
0bcd1aec by sheaf at 2026-02-02T17:57:59+01:00
WIP: debugging
- - - - -
3 changed files:
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Types/Id.hs
- testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
Changes:
=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -1080,23 +1080,33 @@ joinPointBinding_maybe bndr rhs
-- need to demote it to a quasi join-point.
-- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
| Just orig_cat <- joinId_maybe bndr
- , AlwaysTailCalled
- { tailCallArity = _new_arity
- , tailCallJoinPointType = new_cat }
- <- tailCallInfo (idOccInfo bndr)
- = assertPpr (idJoinArity bndr == _new_arity)
- ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
- , text "bndr:" <+> ppr bndr
- , text "rhs:" <+> ppr rhs
- , text "prev arity:" <+> ppr (idJoinArity bndr)
- , text " new arity:" <+> ppr _new_arity
- , text "orig_cat:" <+> ppr orig_cat
- , text " new_cat:" <+> ppr new_cat
- ]
- ) $ Just $
- if orig_cat == new_cat
- then (bndr, rhs)
- else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
+ = case tailCallInfo (idOccInfo bndr) of
+ NoTailCallInfo ->
+ pprTrace "joinPointBinding_maybe: lost join?"
+ (vcat
+ [ text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "arity:" <+> ppr (idJoinArity bndr)
+ , text "cat:" <+> ppr orig_cat
+ , text "occ_info:" <+> ppr (idOccInfo bndr)
+ ])
+ Nothing
+ AlwaysTailCalled
+ { tailCallArity = _new_arity
+ , tailCallJoinPointType = new_cat } ->
+ assertPpr (idJoinArity bndr == _new_arity)
+ ( vcat [ text "joinPointBinding_maybe: incompatible join arities "
+ , text "bndr:" <+> ppr bndr
+ , text "rhs:" <+> ppr rhs
+ , text "prev arity:" <+> ppr (idJoinArity bndr)
+ , text " new arity:" <+> ppr _new_arity
+ , text "orig_cat:" <+> ppr orig_cat
+ , text " new_cat:" <+> ppr new_cat
+ ]
+ ) $ Just $
+ if orig_cat == new_cat
+ then (bndr, rhs)
+ else (asJoinId bndr new_cat (idJoinArity bndr), rhs)
| AlwaysTailCalled
{ tailCallArity = join_arity
=====================================
compiler/GHC/Types/Id.hs
=====================================
@@ -692,10 +692,16 @@ idJoinArity id =
JoinPoint { joinPointArity = ar } -> ar
NotJoinPoint -> pprPanic "idJoinArity" (ppr id)
-asJoinId :: Id -> JoinPointCategory -> JoinArity -> JoinId
+asJoinId :: HasDebugCallStack => Id -> JoinPointCategory -> JoinArity -> JoinId
asJoinId id cat arity
= warnPprTrace (not (isLocalId id))
"global id being marked as join var" (ppr id) $
+ -- SLD TODO debugging
+ pprTrace "asJoinId"
+ ( vcat [ text "id:" <+> ppr id
+ , text "cat:" <+> ppr cat
+ , text "callstack:" <+> callStackDoc
+ ]) $
id `setIdDetails` JoinId cat arity cbv_info
where
cbv_info = case Var.idDetails id of
=====================================
testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
=====================================
@@ -133,3 +133,50 @@ testQuasiTransitivity b n =
True -> {-# SCC "ticked" #-} j3 10
False -> j3 20
)
+
+--------------------------------------------------------------------------------
+-- Extracted from a GHC bootstrapping bug
+
+data AB = A | B
+
+data Int2 = MkInt2
+
+expt :: Int2 -> Int2
+expt _ = MkInt2
+{-# NOINLINE expt #-}
+
+add :: Int2 -> Int2 -> Int2
+add _ _ = MkInt2
+{-# NOINLINE add #-}
+
+big :: Int2 -> AB
+big _ = A
+{-# NOINLINE big #-}
+
+baz :: Int2
+baz = MkInt2
+{-# NOINLINE baz #-}
+
+no :: a
+no = no
+{-# NOINLINE no #-}
+
+mul :: Int2 -> Int2 -> Int2
+mul !_ !_ = no
+{-# INLINE mul #-}
+
+data T2 a b = MkT2 a b
+
+floatToDigits2 :: T2 Int2 Int2 -> T2 Int2 Int2
+floatToDigits2 ( MkT2 f0 e0 ) =
+ let
+ MkT2 f e =
+ let n = e0
+ in
+ case big n of
+ A -> MkT2 f0 ( add e0 n )
+ B -> MkT2 f0 e0
+ r = let be = expt e in mul f be
+
+ in
+ MkT2 r baz
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bcd1aec81de7f1f227bcd073ca717f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bcd1aec81de7f1f227bcd073ca717f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/cross-windows-wine-iserv] 53 commits: base: don't expose GHC.Num.{BigNat, Integer, Natural}
by Cheng Shao (@TerrorJack) 02 Feb '26
by Cheng Shao (@TerrorJack) 02 Feb '26
02 Feb '26
Cheng Shao pushed to branch wip/cross-windows-wine-iserv at Glasgow Haskell Compiler / GHC
Commits:
30f442a9 by Teo Camarasu at 2026-01-20T13:57:26-05:00
base: don't expose GHC.Num.{BigNat, Integer, Natural}
We no longer expose GHC.Num.{BigNat, Integer, Natural} from base instead users should get these modules from ghc-bignum.
We make this change to insulate end users from changes to GHC's implementation of big numbers.
Implements CLC proposal 359: https://github.com/haskell/core-libraries-committee/issues/359
- - - - -
75a9053d by Teo Camarasu at 2026-01-20T13:58:07-05:00
base: deprecate GHC internals in GHC.Num
Implements CLC proposal: https://github.com/haskell/core-libraries-committee/issues/360
- - - - -
9534b032 by Andreas Klebinger at 2026-01-20T13:58:50-05:00
ghc-experimental: Update Changelog
I tried to reconstruct a high level overview of the changes and when
they were made since we introduced it.
Fixes #26506
Co-authored-by: Teo Camarasu <teofilcamarasu(a)gmail.com>
- - - - -
346f2f5a by Cheng Shao at 2026-01-20T13:59:30-05:00
hadrian: remove RTS options in ghc-in-ghci flavour
This patch removes the RTS options passed to ghc in ghc-in-ghci
flavour, to workaround command line argument handling issue in
hls/hie-boot that results in `-O64M` instead of `+RTS -O64M -RTS`
being passed to ghc. It's not a hadrian bug per se, since ghc's own
ghc-in-ghci multi repl works fine, but we should still make sure HLS
works. Closes #26801.
- - - - -
759fd15a by Andreas Klebinger at 2026-01-21T16:05:28-05:00
Don't build GHC with -Wcompat
Without bumping the boot compiler the warnings it produces are often not
actionable leading to pointless noise.
Fixes #26800
- - - - -
3172db94 by Torsten Schmits at 2026-01-21T16:06:11-05:00
Use the correct field of ModOrigin when formatting error message listing hidden reexports
- - - - -
485c12b2 by Cheng Shao at 2026-01-21T16:06:54-05:00
Revert "hadrian: handle findExecutable "" gracefully"
This reverts commit 1e5752f64a522c4025365856d92f78073a7b3bba. The
underlying issue has been fixed in
https://github.com/haskell/directory/commit/75828696e7145adc09179111a0d631b…
and present since 1.3.9.0, and hadrian directory lower bound is
1.3.9.0, so we can revert our own in house hack now.
- - - - -
5efb58dc by Cheng Shao at 2026-01-21T16:07:36-05:00
rts: fix typo in TICK_ALLOC_RTS
This patch fixes a typo in the `TICK_ALLOC_RTS` macro, the original
`bytes` argument was silently dropped. The Cmm code has its own
version of `TICK_ALLOC_RTS` not affected by this typo, it affected the
C RTS, and went unnoticed because the variable `n` happened to also be
available at its call site. But the number was incorrect. Also fixes
its call site since `WDS()` is not available in C.
- - - - -
c406ea69 by Cheng Shao at 2026-01-21T16:07:36-05:00
rts: remove broken & unused ALLOC_P_TICKY
This patch removes the `ALLOC_P_TICKY` macro from the rts, it's
unused, and its expanded code is already broken.
- - - - -
34a27e20 by Simon Peyton Jones at 2026-01-21T16:08:17-05:00
Make the implicit-parameter class have representational role
This MR addresses #26737, by making the built-in class IP
have a representational role for its second parameter.
See Note [IP: implicit parameter class] in
ghc-internal:GHC.Internal.Classes.IP
In fact, IP is (unfortunately, currently) exposed by
base:GHC.Base, so we ran a quick CLC proposal to
agree the change:
https://github.com/haskell/core-libraries-committee/issues/385
Some (small) compilations get faster because they only need to
load (small) interface file GHC.Internal.Classes.IP.hi,
rather than (large) GHC.Internal.Classes.hi.
Metric Decrease:
T10421
T12150
T12425
T24582
T5837
T5030
- - - - -
ca79475f by Cheng Shao at 2026-01-21T16:09:00-05:00
testsuite: avoid re.sub in favor of simple string replacements
This patch refactors the testsuite driver and avoids the usage of
re.sub in favor of simple string replacements when possible. The
changes are not comprehensive, and there are still a lot of re.sub
usages lingering around the tree, but this already addresses a major
performance bottleneck in the testsuite driver that might has to do
with quadratic or worse slowdown in cpython's regular expression
engine when handling certain regex patterns with large strings.
Especially on i386, and i386 jobs are the bottlenecks of all full-ci
validate pipelines!
Here are the elapsed times of testing x86_64/i386 with -j48 before
this patch:
x86_64: `Build completed in 6m06s`
i386: `Build completed in 1h36m`
And with this patch:
x86_64: `Build completed in 4m55s`
i386: `Build completed in 4m23s`
Fixes #26786.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
88c93796 by Zubin Duggal at 2026-01-21T16:09:42-05:00
ghc-toolchain: Also configure windres on non-windows platforms.
It may be needed for cross compilation.
Fixes #24588
- - - - -
9788c0ec by Cheng Shao at 2026-01-21T16:10:24-05:00
ghci: print external interpreter trace messages to stderr instead of stdout
This patch makes ghci print external interpreter trace messages to
stderr instead of stdout, which is a much saner choice for diagnostic
information. Closes #26807.
- - - - -
0491f08a by Sylvain Henry at 2026-01-22T03:44:26-05:00
GC: don't use CAS without PARALLEL_GC on
If we're not using the parallel GC, there is no reason to do a costly
CAS. This was flagged as taking time in a perf profile.
- - - - -
211a8f56 by Sylvain Henry at 2026-01-22T03:44:26-05:00
GC: suffix parallel GC with "par" instead of "thr"
Avoid some potential confusion (see discussion in !15351).
- - - - -
77a23cbd by fendor at 2026-01-22T03:45:08-05:00
Remove blanket ignore that covers libraries/
- - - - -
18bf7f5c by Léana Jiang at 2026-01-22T08:58:45-05:00
doc: update Flavour type in hadrian user-settings
- - - - -
3d5a1365 by Cheng Shao at 2026-01-22T08:59:28-05:00
hadrian: add missing notCross predicate for stage0 -O0
There are a few hard-coded hadrian args that pass -O0 when compiling
some heavy modules in stage0, which only makes sense when not
cross-compiling and when cross-compiling we need properly optimized
stage0 packages. So this patch adds the missing `notCross` predicate
in those places.
- - - - -
ee937134 by Matthew Pickering at 2026-01-22T09:00:10-05:00
Fix ghc-experimental GHC.Exception.Backtrace.Experimental module
This module wasn't added to the cabal file so it was never compiled or
included in the library.
- - - - -
1b490f5a by Zubin Duggal at 2026-01-22T09:00:53-05:00
hadrian: Add ghc-{experimental,internal}.cabal to the list of dependencies of the doc target
We need these files to detect the version of these libraries
Fixes #26738
- - - - -
cdb74049 by Cheng Shao at 2026-01-22T14:52:36-05:00
rts: avoid Cmm loop to initialize Array#/SmallArray#
Previously, `newArray#`/`newSmallArray#` called an RTS C function to
allocate the `Array#`/`SmallArray#`, then used a Cmm loop to
initialize the elements. Cmm doesn't have native for-loop so the code
is a bit awkward, and it's less efficient than a C loop, since the C
compiler can effectively vectorize the loop with optimizations.
So this patch moves the loop that initializes the elements to the C
side. `allocateMutArrPtrs`/`allocateSmallMutArrPtrs` now takes a new
`init` argument and initializes the elements if `init` is non-NULL.
- - - - -
4c784f00 by Cheng Shao at 2026-01-22T14:53:19-05:00
Fix testsuite run for +ipe flavour transformer
This patch makes the +ipe flavour transformer pass the entire
testsuite:
- An RTS debug option `-DI` is added, the IPE trace information is now
only printed with `-DI`. The test cases that do require IPE trace
are now run with `-DI`.
- The testsuite config option `ghc_with_ipe` is added, enabled when
running the testsuite with `+ipe`, which skips a few tests that are
sensitive to eventlog output, allocation patterns etc that can fail
under `+ipe`.
This is the first step towards #26799.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
be8e5236 by Ben Gamari at 2026-01-23T03:28:45-05:00
hadrian: Bump QuickCheck upper bound
This patch bumps QuickCheck upper bound to 2.18. selftest rule
manually tested to work with current latest QuickCheck-2.17.1.0.
- - - - -
5aa328fb by Zubin Duggal at 2026-01-23T03:29:30-05:00
Add genindex to index.rst. This adds a link to the index in the navigation bar.
Fixes #26437
- - - - -
917ab8ff by Oleg Grenrus at 2026-01-23T10:52:55-05:00
Export labelThread from Control.Concurrent
- - - - -
3f5e8d80 by Cheng Shao at 2026-01-23T10:53:37-05:00
ci: only push perf notes on master/release branches
This patch fixes push_perf_notes logic in ci.sh to only push perf
notes on master/release branches. We used to unconditionally push perf
notes even in MRs, but the perf numbers in the wip branches wouldn't
be used as baseline anyway, plus this is causing a space leak in the
ghc-performance-notes repo. See #25317 for the perf notes repo size
problem.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
414b9593 by Cheng Shao at 2026-01-24T07:11:51-05:00
ci: remove duplicate keys in .gitlab-ci.yml
This patch removes accidentally duplicate keys in `.gitlab-ci.yml`.
The YAML spec doesn't allow duplicate keys in the first place, and
according to GitLab docs
(https://docs.gitlab.com/ci/yaml/yaml_optimization/#anchors) the
latest key overrides the earlier entries.
- - - - -
e5cb5491 by Cheng Shao at 2026-01-24T07:12:34-05:00
hadrian: drop obsolete configure/make builder logic for libffi
This patch drops obsolete hadrian logic around `Configure
libffiPath`/`Make libffiPath` builders, they are no longer needed
after libffi-clib has landed. Closes #26815.
- - - - -
2d160222 by Simon Hengel at 2026-01-24T07:13:17-05:00
Fix typo in roles.rst
- - - - -
56db94f7 by Peter Trommler at 2026-01-26T11:26:18+01:00
PPC NCG: Generate clear right insn at arch width
The clear right immediate (clrrxi) is only available in word and
doubleword width. Generate clrrxi instructions at architecture
width for all MachOp widths.
Fixes #24145
- - - - -
5957a8ad by Wolfgang Jeltsch at 2026-01-27T06:11:40-05:00
Add operations for obtaining operating-system handles
This contribution implements CLC proposal #369. It adds operations for
obtaining POSIX file descriptors and Windows handles that underlie
Haskell handles. Those operating system handles can also be obtained
without such additional operations, but this is more involved and, more
importantly, requires using internals.
- - - - -
86a0510c by Greg Steuck at 2026-01-27T06:12:34-05:00
Move flags to precede patterns for grep and read files directly
This makes the tests pass with non-GNU (i.e. POSIX-complicant) tools.
There's no reason to use cat and pipe where direct file argument works.
- - - - -
50761451 by Cheng Shao at 2026-01-27T21:51:23-05:00
ci: update darwin boot ghc to 9.10.3
This patch updates darwin boot ghc to 9.10.3, along with other related
updates, and pays off some technical debt here:
- Update `nixpkgs` and use the `nixpkgs-25.05-darwin` channel.
- Update the `niv` template.
- Update LLVM to 21 and update `llvm-targets` to reflect LLVM 21
layout changes for arm64/x86_64 darwin targets.
- Use `stdenvNoCC` to prevent nix packaged apple sdk from being used
by boot ghc, and manually set `DEVELOPER_DIR`/`SDKROOT` to enforce
the usage of system-wide command line sdk for macos.
- When building nix derivation for boot ghc, run `configure` via the
`arch` command so that `configure` and its subprocesses pick up the
manually specified architecture.
- Remove the previous horrible hack that obliterates `configure` to
make autoconf test result in true. `configure` now properly does its
job.
- Remove the now obsolete configure args and post install settings
file patching logic.
- Use `scheme-small` for texlive to avoid build failures in certain
unused texlive packages, especially on x86_64-darwin.
- - - - -
94dcd15e by Matthew Pickering at 2026-01-27T21:52:05-05:00
Evaluate backtraces for "error" exceptions at the moment they are thrown
See Note [Capturing the backtrace in throw] and
Note [Hiding precise exception signature in throw] which explain the
implementation.
This commit makes `error` and `throw` behave the same with regard to
backtraces. Previously, exceptions raised by `error` would not contain
useful IPE backtraces.
I did try and implement `error` in terms of `throw` but it started to
involve putting diverging functions into hs-boot files, which seemed to
risky if the compiler wouldn't be able to see if applying a function
would diverge.
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/383
Fixes #26751
- - - - -
ef35e3ea by Teo Camarasu at 2026-01-27T21:52:46-05:00
ghc-internal: move all Data instances to Data.Data
Most instances of Data are defined in GHC.Internal.Data.Data.
Let's move all remaining instance there.
This moves other modules down in the dependency hierarchy allowing for
more parallelism, and it decreases the likelihood that we would need to
load this heavy .hi file if we don't actually need it.
Resolves #26830
Metric Decrease:
T12227
T16875
- - - - -
5e0ec555 by sheaf at 2026-01-28T06:56:38-05:00
Add test case for #25679
This commit adds the T25679 test case. The test now passes, thanks to
commit 1e53277af36d3f0b6ad5491f70ffc5593a49dcfd.
Fixes #25679
- - - - -
f1cd1611 by sheaf at 2026-01-28T06:56:38-05:00
Improve defaulting of representational equalities
This commit makes the defaulting of representational equalities, introduced
in 1e53277a, a little bit more robust. Now, instead of calling the eager
unifier, it calls the full-blown constraint solver, which means that it can
handle some subtle situations, e.g. involving functional dependencies and
type-family injectivity annotations, such as:
type family F a = r | r -> a
type instance F Int = Bool
[W] F beta ~R Bool
- - - - -
25edf516 by sheaf at 2026-01-28T06:56:38-05:00
Improve errors for unsolved representational equalities
This commit adds a new field of CtLoc, CtExplanations, which allows the
typechecker to leave some information about what it has done. For the moment,
it is only used to improve error messages for unsolved representational
equalities. The typechecker will now accumulate, when unifying at
representational role:
- out-of-scope newtype constructors,
- type constructors that have nominal role in a certain argument,
- over-saturated type constructors,
- AppTys, e.g. `c a ~R# c b`, to report that we must assume that 'c' has
nominal role in its parameters,
- data family applications that do not reduce, potentially preventing
newtype unwrapping.
Now, instead of having to re-construct the possible errors after the fact,
we simply consult the CtExplanations field.
Additionally, this commit modifies the typechecker error messages that
concern out-of-scope newtype constructors. The error message now depends
on whether we have an import suggestion to provide to the user:
- If we have an import suggestion for the newtype constructor,
the message will be of the form:
The data constructor MkN of the newtype N is out of scope
Suggested fix: add 'MkN' to the import list in the import of 'M'
- If we don't have any import suggestions, the message will be
of the form:
NB: The type 'N' is an opaque newtype, whose constructor is hidden
Fixes #15850, #20289, #20468, #23731, #25949, #26137
- - - - -
4d0e6da1 by Simon Peyton Jones at 2026-01-28T06:57:19-05:00
Fix two bugs in short-cut constraint solving
There are two main changes here:
* Use `isSolvedWC` rather than `isEmptyWC` in `tryShortCutSolver`
The residual constraint may have some fully-solved, but
still-there implications, and we don't want them to abort short
cut solving! That bug caused #26805.
* In the short-cut solver, we abandon the fully-solved residual
constraint; but we may thereby lose track of Givens that are
needed, and either report them as redundant or prune evidence
bindings that are in fact needed.
This bug stopped the `constraints` package from compiling;
see the trail in !15389.
The second bug led me to (another) significant refactoring
of the mechanism for tracking needed EvIds. See the new
Note [Tracking needed EvIds] in GHC.Tc.Solver.Solve
It's simpler and much less head-scratchy now.
Some particulars:
* An EvBindsVar now tracks NeededEvIds
* We deal with NeededEvIds for an implication only when it is
fully solved. Much simpler!
* `tryShortCutTcS` now takes a `TcM WantedConstraints` rather than
`TcM Bool`, so that is can plumb the needed EvIds correctly.
* Remove `ic_need` and `ic_need_implic` from Implication (hooray),
and add `ics_dm` and `ics_non_dm` to `IC_Solved`.
Pure refactor
* Shorten data constructor `CoercionHole` to `CH`, following
general practice in GHC.
* Rename `EvBindMap` to `EvBindsMap` for consistency
- - - - -
662480b7 by Cheng Shao at 2026-01-28T06:58:00-05:00
ci: use debian validate bindists instead of fedora release bindists in testing stage
This patch changes the `abi-test`, `hadrian-multi` and `perf` jobs in
the full-ci pipeline testing stage to use debian validate bindists
instead of fedora release bindists, to increase pipeline level
parallelism and allow full-ci pipelines to complete earlier. Closes #26818.
- - - - -
39581ec6 by Cheng Shao at 2026-01-28T06:58:40-05:00
ci: run perf test with -j$cores
This patch makes the perf ci job compile Cabal with -j$cores to speed
up the job.
- - - - -
607b287b by Wolfgang Jeltsch at 2026-01-28T15:41:53+02:00
Remove `GHC.Desugar` from `base`
`GHC.Desugar` was deprecated and should have been removed in GHC 9.14.
However, the removal was forgotten, although there was a code block that
was intended to trigger a compilation error when the GHC version in use
was 9.14 or later. This code sadly didn’t work, because the
`__GLASGOW_HASKELL__` macro was misspelled as `__GLASGOW_HASKELL`.
- - - - -
e8f5a45d by sterni at 2026-01-29T04:19:18-05:00
users_guide: fix runtime error during build with Sphinx 9.1.0
Appears that pathto is stricter about what it accepts now.
Tested Sphinx 8.2.3 and 9.1.0 on the ghc-9.10 branch.
Resolves #26810.
Co-authored-by: Martin Weinelt <hexa(a)darmstadt.ccc.de>
- - - - -
ce2d62fb by Jessica Clarke at 2026-01-29T19:48:51-05:00
PPC NCG: Use libcall for 64-bit cmpxchg on 32-bit PowerPC
There is no native instruction for this, and even if there were a
register pair version we could use, the implementation here is assuming
the values fit in a single register, and we end up only using / defining
the low halves of the registers.
Fixes: b4d39adbb5 ("PrimOps: Add CAS op for all int sizes")
Fixes: #23969
- - - - -
43d97761 by Michael Karcher at 2026-01-29T19:49:43-05:00
NCG for PPC: add pattern for CmmRegOff to iselExpr64
Closes #26828
- - - - -
aeeb4a20 by Matthew Pickering at 2026-01-30T11:42:47-05:00
determinism: Use deterministic map for Strings in TyLitMap
When generating typeable evidence the types we need evidence for all
cached in a TypeMap, the order terms are retrieved from a type map
determines the order the bindings appear in the program.
A TypeMap is quite diligent to use deterministic maps, apart from in the
TyLitMap, which uses a UniqFM for storing strings, whose ordering
depends on the Unique of the FastString.
This can cause non-deterministic .hi and .o files.
An unexpected side-effect is the error message but RecordDotSyntaxFail8
changing. I looked into this with Sam and this change caused the
constraints to be solved in a different order which results in a
slightly different error message. I have accepted the new test, since
the output before was non-deterministic and the new output is consistent
with the other messages in that file.
Fixes #26846
- - - - -
9e4d70c2 by Andrew Lelechenko at 2026-01-30T11:43:29-05:00
Upgrade text submodule to 2.1.4
- - - - -
631fa5ae by Recursion Ninja at 2026-01-31T22:30:11+00:00
Decouple `L.S.H.Decls` from importing `GHC.Types.Basic`
Data-types within `GHC.Types.Basic` which describe components of
the AST are migrated to `Language.Haskell.Syntax.Basic`. Related
function definitions are also moved.
Types moved to L.H.S. because they are part of the AST:
* TopLevelFlag
* RuleName
Types moved from L.H.S. to GHC.Hs. because they are not needed in the AST:
* TyConFlavour
* TypeOrData
* NewOrData
Migrated instances:
* `Outputable` instances moved to in `GHC.Utils.Outputable`
* `Binary` instance of `Boxity` moved to to `GHC.Utils.Binary`
* Other `Binary` instances are orphans to be migrated later.
The `OverlapMode` data-type is given a TTG extension point.
The `OverlapFlag` data-type, which depends on `OverlapMode`,
is updated to support `OverlapMode` with a GHC "pass" type paramerter.
In order to avoid module import cycles, `OverlapMode` and `OverlapFlag`
are migrated to new modules (no way around this).
* Migrated `OverlapMode` to new module `Language.Haskell.Syntax.Overlap`
* Migrated `OverlapFlag` to new module `GHC.Hs.Decls.Overlap`
- - - - -
9769cc03 by Simon Hengel at 2026-02-01T04:21:03-05:00
Update the documentation for MultiWayIf (fixes #25376)
(so that it matches the implementation)
- - - - -
5fc9442a by Peter Trommler at 2026-02-01T04:21:44-05:00
hadrian: Fix dependency generation for assembler
Assembler files allow # for comments unless in column 1. A modern
cpp for C treats those a preprocessor directives. We tell gcc that
a .S file is assembler with cpp and not C.
Fixes #26819
- - - - -
269c4087 by Simon Peyton Jones at 2026-02-01T19:38:10-05:00
Include current phase in the range for rule/unfoldings
This MR fixes a bad loop in the compiler: #26826.
The fix is to add (WAR2) to
Note [What is active in the RHS of a RULE or unfolding?]
in GHC.Core.Opt.Simplify.Utils
- - - - -
ddf1434f by Vladislav Zavialov at 2026-02-01T19:38:52-05:00
Refactor: merge HsMultilineString into HsString (#26860)
Before this patch, HsLit defined two separate constructors to represent
single-line and multi-line strings:
data HsLit x
...
| HsString (XHsString x) FastString
| HsMultilineString (XHsMultilineString x) FastString
I found this to be an unnecessary complication and an obstacle to unifying
HsLit with HsTyLit. Now we use HsString for both kinds of literals.
One user-facing change here is `ppr (HsString st s)` behaving differently for
single-line strings containing newlines:
x = "first line \
\asdf\n\
\second line"
Previously, the literal was fed to `ftext` with its newlines, producing an
ill-formed SDoc. This issue is now addressed by using `split` for both
single-line and multi-line strings:
vcat $ map text $ split '\n' (unpackFS src)
See the parser/should_fail/T26860ppr test.
In addition (and unrelatedly to the main payload of this patch),
drop the unused pmPprHsLit helper.
- - - - -
b28e31b8 by Cheng Shao at 2026-02-02T14:58:10+01:00
WIP
- - - - -
272 changed files:
- .gitignore
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/darwin/nix/sources.json
- .gitlab/darwin/toolchain.nix
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/TyCo/Tidy.hs
- compiler/GHC/Core/TyCon/RecWalk.hs
- compiler/GHC/Data/Maybe.hs
- compiler/GHC/Hs/Decls.hs
- + compiler/GHC/Hs/Decls/Overlap.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/String.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Utils.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Monad.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Trace.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- + compiler/Language/Haskell/Syntax/Decls/Overlap.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/exts/multiway_if.rst
- docs/users_guide/exts/roles.rst
- docs/users_guide/index.rst
- docs/users_guide/rtd-theme/layout.html
- docs/users_guide/runtime_control.rst
- hadrian/doc/user-settings.md
- hadrian/hadrian.cabal
- hadrian/src/Builder.hs
- hadrian/src/Context.hs
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Docspec.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Lint.hs
- hadrian/src/Settings/Builders/Cc.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Make.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Concurrent.hs
- libraries/base/src/Data/Array/Byte.hs
- − libraries/base/src/GHC/Desugar.hs
- libraries/base/src/GHC/Num.hs
- − libraries/base/src/GHC/Num/BigNat.hs
- − libraries/base/src/GHC/Num/Integer.hs
- − libraries/base/src/GHC/Num/Natural.hs
- libraries/base/src/System/CPUTime/Utils.hs
- + libraries/base/src/System/IO/OS.hs
- libraries/base/src/System/Timeout.hs
- libraries/base/tests/IO/all.T
- + libraries/base/tests/IO/osHandles001FileDescriptors.hs
- + libraries/base/tests/IO/osHandles001FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles001WindowsHandles.hs
- + libraries/base/tests/IO/osHandles001WindowsHandles.stdout
- + libraries/base/tests/IO/osHandles002FileDescriptors.hs
- + libraries/base/tests/IO/osHandles002FileDescriptors.stderr
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdin
- + libraries/base/tests/IO/osHandles002FileDescriptors.stdout
- + libraries/base/tests/IO/osHandles002WindowsHandles.hs
- + libraries/base/tests/IO/osHandles002WindowsHandles.stderr
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdin
- + libraries/base/tests/IO/osHandles002WindowsHandles.stdout
- libraries/base/tests/T23454.stderr
- libraries/base/tests/perf/Makefile
- libraries/ghc-bignum/ghc-bignum.cabal
- libraries/ghc-compact/tests/all.T
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-experimental/ghc-experimental.cabal.in
- libraries/ghc-experimental/src/GHC/Exception/Backtrace/Experimental.hs
- libraries/ghc-experimental/src/GHC/TypeNats/Experimental.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Classes.hs
- + libraries/ghc-internal/src/GHC/Internal/Classes/IP.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Err.hs
- libraries/ghc-internal/src/GHC/Internal/Exts.hs
- libraries/ghc-internal/src/GHC/Internal/Functor/ZipList.hs
- + libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/all.T
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.hs
- + libraries/ghc-internal/tests/stack-annotation/ann_frame005.stdout
- libraries/ghci/GHCi/Run.hs
- libraries/ghci/GHCi/Server.hs
- libraries/ghci/GHCi/Utils.hsc
- + libraries/ghci/cbits/ghci_msvcrt_assert_shim.c
- libraries/ghci/ghci.cabal.in
- libraries/text
- llvm-targets
- rts/AllocArray.c
- rts/AllocArray.h
- rts/ClosureTable.c
- rts/Heap.c
- rts/PrimOps.cmm
- rts/RtsFlags.c
- rts/Threads.c
- rts/Trace.c
- rts/Weak.c
- rts/include/Cmm.h
- rts/include/rts/Flags.h
- rts/include/stg/Ticky.h
- rts/rts.cabal
- rts/sm/Evac.c
- rts/sm/Evac_thr.c → rts/sm/Evac_par.c
- rts/sm/Scav_thr.c → rts/sm/Scav_par.c
- rts/sm/Storage.c
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/default/T25825.hs
- testsuite/tests/default/all.T
- testsuite/tests/deriving/should_fail/T1496.stderr
- testsuite/tests/deriving/should_fail/T4846.stderr
- testsuite/tests/deriving/should_fail/T5498.stderr
- testsuite/tests/deriving/should_fail/T6147.stderr
- testsuite/tests/deriving/should_fail/T7148.stderr
- testsuite/tests/deriving/should_fail/T7148a.stderr
- testsuite/tests/deriving/should_fail/T8984.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail4.stderr
- testsuite/tests/deriving/should_fail/deriving-via-fail5.stderr
- testsuite/tests/driver/T16318/Makefile
- testsuite/tests/driver/T18125/Makefile
- testsuite/tests/gadt/CasePrune.stderr
- + testsuite/tests/ghc-api/TypeMapStringLiteral.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghci.debugger/scripts/T8487.stdout
- testsuite/tests/ghci.debugger/scripts/break011.stdout
- testsuite/tests/ghci.debugger/scripts/break017.stdout
- testsuite/tests/ghci.debugger/scripts/break025.stdout
- testsuite/tests/indexed-types/should_fail/T9580.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/linear/should_fail/LinearRole.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T26860ppr.hs
- + testsuite/tests/parser/should_fail/T26860ppr.stderr
- testsuite/tests/parser/should_fail/all.T
- testsuite/tests/roles/should_fail/RolesIArray.stderr
- testsuite/tests/rts/Makefile
- testsuite/tests/rts/all.T
- testsuite/tests/rts/ipe/all.T
- + testsuite/tests/simplCore/should_compile/T26805.hs
- + testsuite/tests/simplCore/should_compile/T26805.stderr
- + testsuite/tests/simplCore/should_compile/T26826.hs
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/th/TH_implicitParams.stdout
- + testsuite/tests/typecheck/should_compile/T26737.hs
- + testsuite/tests/typecheck/should_compile/T26805a.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T10285.stderr
- testsuite/tests/typecheck/should_fail/T10534.stderr
- testsuite/tests/typecheck/should_fail/T10715b.stderr
- testsuite/tests/typecheck/should_fail/T11347.stderr
- testsuite/tests/typecheck/should_fail/T15801.stderr
- + testsuite/tests/typecheck/should_fail/T15850.hs
- + testsuite/tests/typecheck/should_fail/T15850.stderr
- + testsuite/tests/typecheck/should_fail/T15850_Lib.hs
- + testsuite/tests/typecheck/should_fail/T20289.hs
- + testsuite/tests/typecheck/should_fail/T20289.stderr
- + testsuite/tests/typecheck/should_fail/T20289_A.hs
- testsuite/tests/typecheck/should_fail/T22645.stderr
- testsuite/tests/typecheck/should_fail/T22924a.stderr
- + testsuite/tests/typecheck/should_fail/T23731.hs
- + testsuite/tests/typecheck/should_fail/T23731.stderr
- + testsuite/tests/typecheck/should_fail/T23731b.hs
- + testsuite/tests/typecheck/should_fail/T23731b.stderr
- + testsuite/tests/typecheck/should_fail/T23731b_aux.hs
- + testsuite/tests/typecheck/should_fail/T25679.hs
- + testsuite/tests/typecheck/should_fail/T25679.stderr
- + testsuite/tests/typecheck/should_fail/T25949.hs
- + testsuite/tests/typecheck/should_fail/T25949.stderr
- + testsuite/tests/typecheck/should_fail/T25949_aux.hs
- + testsuite/tests/typecheck/should_fail/T26137.hs
- + testsuite/tests/typecheck/should_fail/T26137.stderr
- testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr
- testsuite/tests/typecheck/should_fail/TcCoercibleFail3.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/check-exact/ExactPrint.hs
- utils/ghc-toolchain/exe/Main.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/22304cd248af6b61f198a055653603…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/22304cd248af6b61f198a055653603…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/ticked_joins] Allow join point Ids to occur below ticks & casts
by sheaf (@sheaf) 02 Feb '26
by sheaf (@sheaf) 02 Feb '26
02 Feb '26
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
d72882fd by sheaf at 2026-02-02T15:15:12+01:00
Allow join point Ids to occur below ticks & casts
This commit classifies all join points into two categories:
- true join points
- quasi join points
A quasi join point is a join point for which a jump is enclosed within
a profiling tick or a cast.
The only operational difference is that, for quasi join points, we
cannot perform the case-of-case transformation described in
Note [Join points and case-of-case] in GHC.Core.Opt.Simplify.Iteration.
All of this is explained in detail in Note [Quasi join points].
Fixes #26693 and #26642
Improves on #14610, #26157 and #26422, as it means casts/profiling ticks
don't prevent join points, but it doesn't entirely fix these issues
because we are still inhibiting optimisations (lack of case-of-case).
- - - - -
33 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- testsuite/tests/profiling/should_run/T2552.prof.sample
- testsuite/tests/profiling/should_run/ioprof.prof.sample
- testsuite/tests/profiling/should_run/scc001.prof.sample
- + testsuite/tests/simplCore/should_compile/QuasiJoinPoints.hs
- testsuite/tests/simplCore/should_compile/all.T
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d72882fd67646e4cb17885ddd0515f7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d72882fd67646e4cb17885ddd0515f7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26865] ghc-internal: Move GHC.Internal.Data.Bool to base
by Teo Camarasu (@teo) 02 Feb '26
by Teo Camarasu (@teo) 02 Feb '26
02 Feb '26
Teo Camarasu pushed to branch wip/T26865 at Glasgow Haskell Compiler / GHC
Commits:
4d75c77b by Teo Camarasu at 2026-02-02T12:40:15+00:00
ghc-internal: Move GHC.Internal.Data.Bool to base
This is a tiny module that only defines bool :: Bool -> a -> a -> a. We can just move this to base and delete it from ghc-internal. If we want this functionality there we can just use a case statement or if-then expression.
Resolves 26865
- - - - -
19 changed files:
- libraries/base/src/Data/Bool.hs
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NubOrdSet.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- − libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
- libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TypeError.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
Changes:
=====================================
libraries/base/src/Data/Bool.hs
=====================================
@@ -1,4 +1,4 @@
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
-- |
--
@@ -24,4 +24,39 @@ module Data.Bool
bool
) where
-import GHC.Internal.Data.Bool
\ No newline at end of file
+import GHC.Internal.Base
+
+-- $setup
+-- >>> import Prelude
+
+-- | Case analysis for the 'Bool' type. @'bool' f t p@ evaluates to @f@
+-- when @p@ is 'False', and evaluates to @t@ when @p@ is 'True'.
+--
+-- This is equivalent to @if p then t else f@; that is, one can
+-- think of it as an if-then-else construct with its arguments
+-- reordered.
+--
+-- @since base-4.7.0.0
+--
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> bool "foo" "bar" True
+-- "bar"
+-- >>> bool "foo" "bar" False
+-- "foo"
+--
+-- Confirm that @'bool' f t p@ and @if p then t else f@ are
+-- equivalent:
+--
+-- >>> let p = True; f = "bar"; t = "foo"
+-- >>> bool f t p == if p then t else f
+-- True
+-- >>> let p = False
+-- >>> bool f t p == if p then t else f
+-- True
+--
+bool :: a -> a -> Bool -> a
+bool f _ False = f
+bool _ t True = t
=====================================
libraries/base/src/Data/List.hs
=====================================
@@ -1,4 +1,4 @@
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
-- |
--
@@ -184,7 +184,7 @@ module Data.List
genericReplicate
) where
-import GHC.Internal.Data.Bool (otherwise)
+import GHC.Internal.Base (otherwise)
import GHC.Internal.Data.Function (const)
import GHC.Internal.Data.List
import GHC.Internal.Data.List.NonEmpty (NonEmpty(..))
=====================================
libraries/base/src/Data/List/NubOrdSet.hs
=====================================
@@ -11,7 +11,7 @@ module Data.List.NubOrdSet (
insert,
) where
-import GHC.Internal.Data.Bool (Bool(..))
+import GHC.Internal.Base (Bool(..))
import GHC.Internal.Data.Function ((.))
import GHC.Internal.Data.Ord (Ordering(..))
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -140,7 +140,6 @@ Library
GHC.Internal.Control.Monad.ST.Imp
GHC.Internal.Control.Monad.ST.Lazy.Imp
GHC.Internal.Data.Bits
- GHC.Internal.Data.Bool
GHC.Internal.Data.Coerce
GHC.Internal.Data.Data
GHC.Internal.Data.Dynamic
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Bool.hs deleted
=====================================
@@ -1,64 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-
------------------------------------------------------------------------------
--- |
--- Module : GHC.Internal.Data.Bool
--- Copyright : (c) The University of Glasgow 2001
--- License : BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer : libraries(a)haskell.org
--- Stability : stable
--- Portability : portable
---
--- The 'Bool' type and related functions.
---
------------------------------------------------------------------------------
-
-module GHC.Internal.Data.Bool (
- -- * Booleans
- Bool(..),
- -- ** Operations
- (&&),
- (||),
- not,
- otherwise,
- bool,
- ) where
-
-import GHC.Internal.Base
-
--- $setup
--- >>> import Prelude
-
--- | Case analysis for the 'Bool' type. @'bool' f t p@ evaluates to @f@
--- when @p@ is 'False', and evaluates to @t@ when @p@ is 'True'.
---
--- This is equivalent to @if p then t else f@; that is, one can
--- think of it as an if-then-else construct with its arguments
--- reordered.
---
--- @since base-4.7.0.0
---
--- ==== __Examples__
---
--- Basic usage:
---
--- >>> bool "foo" "bar" True
--- "bar"
--- >>> bool "foo" "bar" False
--- "foo"
---
--- Confirm that @'bool' f t p@ and @if p then t else f@ are
--- equivalent:
---
--- >>> let p = True; f = "bar"; t = "foo"
--- >>> bool f t p == if p then t else f
--- True
--- >>> let p = False
--- >>> bool f t p == if p then t else f
--- True
---
-bool :: a -> a -> Bool -> a
-bool f _ False = f
-bool _ t True = t
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs
=====================================
@@ -50,7 +50,6 @@ module GHC.Internal.Data.Foldable (
find
) where
-import GHC.Internal.Data.Bool
import GHC.Internal.Data.Either
import GHC.Internal.Data.Eq
import GHC.Internal.Data.Functor.Utils (Max(..), Min(..), (#.))
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Function.hs
=====================================
@@ -30,8 +30,7 @@ module GHC.Internal.Data.Function
, applyWhen
) where
-import GHC.Internal.Base ( TYPE, ($), (.), id, const, flip )
-import GHC.Internal.Data.Bool ( Bool(..) )
+import GHC.Internal.Base ( TYPE, Bool(..), ($), (.), id, const, flip )
infixl 0 `on`
infixl 1 &
@@ -171,7 +170,7 @@ x & f = f x
-- | 'applyWhen' applies a function to a value if a condition is true,
-- otherwise, it returns the value unchanged.
--
--- It is equivalent to @'flip' ('GHC.Internal.Data.Bool.bool' 'id')@.
+-- It is equivalent to @'flip' ('Data.Bool.bool' 'id')@.
--
-- ==== __Examples__
--
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Type/Bool.hs
=====================================
@@ -1,7 +1,7 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE PolyKinds #-}
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators #-}
@@ -23,7 +23,7 @@ module GHC.Internal.Data.Type.Bool (
If, type (&&), type (||), Not
) where
-import GHC.Internal.Data.Bool
+import GHC.Internal.Base
-- This needs to be in base because (&&) is used in Data.Type.Equality.
-- The other functions do not need to be in base, but seemed to be appropriate
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Type/Ord.hs
=====================================
@@ -34,14 +34,11 @@ module GHC.Internal.Data.Type.Ord (
, OrdCond
) where
-import GHC.Internal.Show(Show(..))
+import GHC.Internal.Base
+import GHC.Internal.Show (Show(..))
import GHC.Internal.TypeError
import GHC.Internal.TypeLits.Internal
import GHC.Internal.TypeNats.Internal
-import GHC.Internal.Types (type (~), Char)
-import GHC.Internal.Data.Bool
-import GHC.Internal.Data.Eq
-import GHC.Internal.Data.Ord
-- | 'Compare' branches on the kind of its arguments to either compare by
-- 'Symbol' or 'Nat'.
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
=====================================
@@ -37,13 +37,12 @@ module GHC.Internal.Data.Version (
) where
import GHC.Internal.Data.Functor ( Functor(..) )
-import GHC.Internal.Data.Bool ( (&&) )
import GHC.Internal.Data.Eq
import GHC.Internal.Int ( Int )
import GHC.Internal.Data.List ( map, sort, concat, concatMap, intersperse, (++) )
import GHC.Internal.Data.Ord
import GHC.Internal.Data.String ( String )
-import GHC.Internal.Base ( Applicative(..) )
+import GHC.Internal.Base ( Applicative(..), (&&) )
import GHC.Internal.Generics
import GHC.Internal.Unicode ( isDigit, isAlphaNum )
import GHC.Internal.Read
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/FD.hs
=====================================
@@ -49,7 +49,6 @@ import GHC.Internal.Conc.IO
import GHC.Internal.IO.Exception
#if defined(mingw32_HOST_OS)
import GHC.Internal.Windows
-import GHC.Internal.Data.Bool
import GHC.Internal.IO.SubSystem ((<!>))
import GHC.Internal.Foreign.Storable
#endif
@@ -717,7 +716,7 @@ asyncReadRawBufferPtr loc !fd !buf !off !len = do
if l == (-1)
then let sock_errno = c_maperrno_func (fromIntegral rc)
non_sock_errno = Errno (fromIntegral rc)
- errno = bool non_sock_errno sock_errno (fdIsSocket fd)
+ errno = if fdIsSocket fd then sock_errno else non_sock_errno
in ioError (errnoToIOError loc errno Nothing Nothing)
else return (fromIntegral l)
@@ -728,7 +727,7 @@ asyncWriteRawBufferPtr loc !fd !buf !off !len = do
if l == (-1)
then let sock_errno = c_maperrno_func (fromIntegral rc)
non_sock_errno = Errno (fromIntegral rc)
- errno = bool non_sock_errno sock_errno (fdIsSocket fd)
+ errno = if fdIsSocket fd then sock_errno else non_sock_errno
in ioError (errnoToIOError loc errno Nothing Nothing)
else return (fromIntegral l)
@@ -740,7 +739,7 @@ blockingReadRawBufferPtr loc !fd !buf !off !len
let start_ptr = buf `plusPtr` off
recv_ret = c_safe_recv (fdFD fd) start_ptr (fromIntegral len) 0
read_ret = c_safe_read (fdFD fd) start_ptr (fromIntegral len)
- r <- bool read_ret recv_ret (fdIsSocket fd)
+ r <- if fdIsSocket fd then recv_ret else read_ret
when ((fdIsSocket fd) && (r == -1)) c_maperrno
return r
-- We trust read() to give us the correct errno but recv(), as a
@@ -753,7 +752,7 @@ blockingWriteRawBufferPtr loc !fd !buf !off !len
let start_ptr = buf `plusPtr` off
send_ret = c_safe_send (fdFD fd) start_ptr (fromIntegral len) 0
write_ret = c_safe_write (fdFD fd) start_ptr (fromIntegral len)
- r <- bool write_ret send_ret (fdIsSocket fd)
+ r <- if fdIsSocket fd then send_ret else write_ret
when (r == -1) c_maperrno
return r
-- We don't trust write() to give us the correct errno, and
=====================================
libraries/ghc-internal/src/GHC/Internal/JS/Prim.hs
=====================================
@@ -46,7 +46,6 @@ import qualified GHC.Internal.Exception as Ex
import qualified GHC.Internal.Exts as Exts
import qualified GHC.Internal.CString as GHC
import GHC.Internal.IO
-import GHC.Internal.Data.Bool
import GHC.Internal.Base
import GHC.Internal.Show
=====================================
libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
=====================================
@@ -29,7 +29,7 @@ import GHC.Internal.Control.Exception (mask)
import GHC.Internal.Data.Function (const, (.), ($))
import GHC.Internal.Data.Functor (fmap)
#if defined(mingw32_HOST_OS)
-import GHC.Internal.Data.Bool (otherwise)
+import GHC.Internal.Base (otherwise)
#endif
import GHC.Internal.Data.Maybe (Maybe (Nothing), maybe)
#if defined(mingw32_HOST_OS)
=====================================
libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
=====================================
@@ -34,7 +34,6 @@ import GHC.Internal.TH.Monad
import qualified GHC.Internal.TH.Lib as Lib (litE) -- See wrinkle (W4) of Note [Tracking dependencies on primitives]
import GHC.Internal.Data.Either
-import GHC.Internal.Data.Bool
import GHC.Internal.Base hiding (NonEmpty(..), Type, Module, inline)
import GHC.Internal.Data.NonEmpty (NonEmpty(..))
import GHC.Internal.Integer
=====================================
libraries/ghc-internal/src/GHC/Internal/TypeError.hs
=====================================
@@ -31,8 +31,7 @@ module GHC.Internal.TypeError
, Unsatisfiable, unsatisfiable
) where
-import GHC.Internal.Data.Bool
-import GHC.Internal.Types (TYPE, Constraint, Symbol)
+import GHC.Internal.Types (TYPE, Bool(True), Constraint, Symbol)
{- Note [Custom type errors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -746,7 +746,7 @@ module Data.Bits where
toIntegralSized :: forall a b. (GHC.Internal.Real.Integral a, GHC.Internal.Real.Integral b, Bits a, Bits b) => a -> GHC.Internal.Maybe.Maybe b
module Data.Bool where
- -- Safety: Safe
+ -- Safety: Trustworthy
(&&) :: Bool -> Bool -> Bool
type Bool :: *
data Bool = False | True
@@ -1308,7 +1308,7 @@ module Data.Kind where
type Type = TYPE GHC.Internal.Types.LiftedRep
module Data.List where
- -- Safety: Safe
+ -- Safety: Trustworthy
(!!) :: forall a. GHC.Internal.Stack.Types.HasCallStack => [a] -> GHC.Internal.Types.Int -> a
(!?) :: forall a. [a] -> GHC.Internal.Types.Int -> GHC.Internal.Maybe.Maybe a
(++) :: forall a. [a] -> [a] -> [a]
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -746,7 +746,7 @@ module Data.Bits where
toIntegralSized :: forall a b. (GHC.Internal.Real.Integral a, GHC.Internal.Real.Integral b, Bits a, Bits b) => a -> GHC.Internal.Maybe.Maybe b
module Data.Bool where
- -- Safety: Safe
+ -- Safety: Trustworthy
(&&) :: Bool -> Bool -> Bool
type Bool :: *
data Bool = False | True
@@ -1308,7 +1308,7 @@ module Data.Kind where
type Type = TYPE GHC.Internal.Types.LiftedRep
module Data.List where
- -- Safety: Safe
+ -- Safety: Trustworthy
(!!) :: forall a. GHC.Internal.Stack.Types.HasCallStack => [a] -> GHC.Internal.Types.Int -> a
(!?) :: forall a. [a] -> GHC.Internal.Types.Int -> GHC.Internal.Maybe.Maybe a
(++) :: forall a. [a] -> [a] -> [a]
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -746,7 +746,7 @@ module Data.Bits where
toIntegralSized :: forall a b. (GHC.Internal.Real.Integral a, GHC.Internal.Real.Integral b, Bits a, Bits b) => a -> GHC.Internal.Maybe.Maybe b
module Data.Bool where
- -- Safety: Safe
+ -- Safety: Trustworthy
(&&) :: Bool -> Bool -> Bool
type Bool :: *
data Bool = False | True
@@ -1308,7 +1308,7 @@ module Data.Kind where
type Type = TYPE GHC.Internal.Types.LiftedRep
module Data.List where
- -- Safety: Safe
+ -- Safety: Trustworthy
(!!) :: forall a. GHC.Internal.Stack.Types.HasCallStack => [a] -> GHC.Internal.Types.Int -> a
(!?) :: forall a. [a] -> GHC.Internal.Types.Int -> GHC.Internal.Maybe.Maybe a
(++) :: forall a. [a] -> [a] -> [a]
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -746,7 +746,7 @@ module Data.Bits where
toIntegralSized :: forall a b. (GHC.Internal.Real.Integral a, GHC.Internal.Real.Integral b, Bits a, Bits b) => a -> GHC.Internal.Maybe.Maybe b
module Data.Bool where
- -- Safety: Safe
+ -- Safety: Trustworthy
(&&) :: Bool -> Bool -> Bool
type Bool :: *
data Bool = False | True
@@ -1308,7 +1308,7 @@ module Data.Kind where
type Type = TYPE GHC.Internal.Types.LiftedRep
module Data.List where
- -- Safety: Safe
+ -- Safety: Trustworthy
(!!) :: forall a. GHC.Internal.Stack.Types.HasCallStack => [a] -> GHC.Internal.Types.Int -> a
(!?) :: forall a. [a] -> GHC.Internal.Types.Int -> GHC.Internal.Maybe.Maybe a
(++) :: forall a. [a] -> [a] -> [a]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d75c77bb51367d9c2ea05e5bed57fd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d75c77bb51367d9c2ea05e5bed57fd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/ticked_joins] Allow join point Ids to occur below ticks & casts
by sheaf (@sheaf) 02 Feb '26
by sheaf (@sheaf) 02 Feb '26
02 Feb '26
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
63687228 by sheaf at 2026-02-02T11:22:19+01:00
Allow join point Ids to occur below ticks & casts
This commit classifies all join points into two categories:
- true join points
- quasi join points
A quasi join point is a join point for which a jump is enclosed within
a profiling tick or a cast.
The only operational difference is that, for quasi join points, we
cannot perform the case-of-case transformation described in
Note [Join points and case-of-case] in GHC.Core.Opt.Simplify.Iteration.
All of this is explained in detail in Note [Quasi join points].
Fixes #26693 and #26642
Improves on #14610, #26157 and #26422, as it means casts/profiling ticks
don't prevent join points, but it doesn't entirely fix these issues
because we are still inhibiting optimisations (lack of case-of-case).
- - - - -
31 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- testsuite/tests/profiling/should_run/T2552.prof.sample
- testsuite/tests/profiling/should_run/ioprof.prof.sample
- testsuite/tests/profiling/should_run/scc001.prof.sample
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/636872281a8faa2ec9e6b141ae29ddd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/636872281a8faa2ec9e6b141ae29ddd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/dcoutts/windows-dlls] 4 commits: Try using response files for hadrian linking with ghc.
by Duncan Coutts (@dcoutts) 02 Feb '26
by Duncan Coutts (@dcoutts) 02 Feb '26
02 Feb '26
Duncan Coutts pushed to branch wip/dcoutts/windows-dlls at Glasgow Haskell Compiler / GHC
Commits:
8f9918c5 by Duncan Coutts at 2026-02-02T10:05:41+00:00
Try using response files for hadrian linking with ghc.
On windows, the link command line for ghc-internal is well over 32kb.
We did not encounter this before for static libs, since we already use
ar's @file feature (if available, which it is for the llvm toolchain).
We encounter this now on windows for linking dll files (which uses ghc
calling (l)ld rather than ar).
- - - - -
0d53e47b by Duncan Coutts at 2026-02-02T10:05:42+00:00
Use __attribute__(dllimport)) for external RTS symbol declarations
This is needed to be hygenic about DLL symbol imports and exports.
The attribute is ignored on platforms other than Windows.
Use of the attribute however means that external data symbols do not
have a compile-time constant address (they are loaded using an
indirection). This means we have to adjust the rtsSyms initial linker
table so that it is a local constant in a function, rather than a global
constant. We now define it within a function that pre-populates the
symbol table with the RTS symbols.
- - - - -
c07584ba by Duncan Coutts at 2026-02-02T10:05:42+00:00
Experiment with listing RTS symbols
- - - - -
48f4736b by Duncan Coutts at 2026-02-02T10:14:56+00:00
Experimental mingw .refptr mechanism support
- - - - -
8 changed files:
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/CmmToAsm/PIC.hs
- compiler/GHC/StgToCmm/Lit.hs
- hadrian/src/Builder.hs
- rts/Linker.c
- rts/RtsSymbols.c
- rts/RtsSymbols.h
- + utils/rts-syms/rts-syms.c
Changes:
=====================================
compiler/GHC/Cmm/CLabel.hs
=====================================
@@ -117,6 +117,7 @@ module GHC.Cmm.CLabel (
hasIdLabelInfo,
isBytesLabel,
isForeignLabel,
+ isForeignLabelUnknownPackage,
isSomeRODataLabel,
isStaticClosureLabel,
@@ -448,8 +449,33 @@ data ForeignLabelSource
-- contain compiled Haskell code, and is not associated with any .hi files.
-- We don't have to worry about Haskell code being inlined from
-- external packages. It is safe to treat the RTS package as "external".
+ --
+ -- On Windows in particular, we assume the label is definately in an
+ -- external DLL and expect to link it against a __imp_* symbol. Thus it
+ -- will /not/ link correctly if the symbol is actually in the same DLL.
| ForeignLabelInExternalPackage
+ -- | The label is somewhere, but we do not know if it is in this package or
+ -- an external package. This is the case we end up with for Haskell FFI
+ -- declarations like @foreign import ccall@. There is not enough
+ -- information to tell us if the label is from the same package (e.g. in
+ -- a local @cbits/blah.c@ file) or is from an external foreign library.
+ --
+ -- On ELF, this is not a problem and the symbol can be resolved without
+ -- knowing if its local or external.
+ --
+ -- On Windows/PE, this is a bit of a problem. On Windows one normally
+ -- needs to know if it's local or external since the symbol names and
+ -- ABI differ. However, GCC & LLVM have extensions to help porting Unix
+ -- software (that is used to not making these distinctions). There are a
+ -- number of useful mechanisms including \"auto import\" (to import
+ -- symbols found in DLLs automatically), a @.refptr@ mechanism to load
+ -- data via an indirection (which the linker can relocate) and
+ -- \"pseudo relocations\" which is a runtime feature to do additional
+ -- relocations beyond what the Win32 native linker does.
+ -- See Note [Mingw .refptr mechanism]
+ | ForeignLabelInUnknownPackage
+
-- | Label is in the package currently being compiled.
-- This is only used for creating hacky tmp labels during code generation.
-- Don't use it in any code that might be inlined across a package boundary
@@ -600,6 +626,8 @@ data CmmLabelInfo
data DynamicLinkerLabelInfo
= CodeStub -- MachO: Lfoo$stub, ELF: foo@plt
| SymbolPtr -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
+ | DataRefPtr -- Windows: .refptr.foo
+ -- see Note [Mingw .refptr mechanism]
| GotSymbolPtr -- ELF: foo@got
| GotSymbolOffset -- ELF: foo@gotoff
@@ -778,6 +806,10 @@ isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _) = True
isForeignLabel _lbl = False
+isForeignLabelUnknownPackage :: CLabel -> Bool
+isForeignLabelUnknownPackage (ForeignLabel _ ForeignLabelInUnknownPackage _) = True
+isForeignLabelUnknownPackage _lbl = False
+
-- | Whether label is a static closure label (can come from haskell or cmm)
isStaticClosureLabel :: CLabel -> Bool
-- Closure defined in haskell (.hs)
@@ -1308,9 +1340,9 @@ labelDynamic this_mod platform external_dynamic_refs lbl =
LocalBlockLabel _ -> False
- ForeignLabel _ source _ ->
- if os == OSMinGW32
- then case source of
+ ForeignLabel _ source _
+ | os == OSMinGW32 ->
+ case source of
-- Foreign label is in some un-named foreign package (or DLL).
ForeignLabelInExternalPackage -> True
@@ -1318,16 +1350,23 @@ labelDynamic this_mod platform external_dynamic_refs lbl =
-- source file currently being compiled.
ForeignLabelInThisPackage -> False
+ -- Foreign label is either in the same package or is in some
+ -- foreign package/DLL/DSO. Neither yes nor no is the correct
+ -- answer here, because on Windows these are a distinct case
+ -- that need special treatment in the code generator.
+ -- See Note [Mingw .refptr mechanism]
+ ForeignLabelInUnknownPackage -> True
+
-- Foreign label is in some named package.
-- When compiling in the "dyn" way, each package is to be
-- linked into its own DLL.
ForeignLabelInPackage pkgId ->
external_dynamic_refs && (this_unit /= pkgId)
- else -- On Mac OS X and on ELF platforms, false positives are OK,
- -- so we claim that all foreign imports come from dynamic
- -- libraries
- True
+ -- On Mac OS X and on ELF platforms, false positives are OK,
+ -- so we claim that all foreign imports come from dynamic
+ -- libraries
+ | otherwise -> True
CC_Label cc ->
external_dynamic_refs && not (ccFromThisModule cc this_mod)
@@ -1678,6 +1717,7 @@ instance Outputable ForeignLabelSource where
ForeignLabelInPackage pkgId -> parens $ text "package: " <> ppr pkgId
ForeignLabelInThisPackage -> parens $ text "this package"
ForeignLabelInExternalPackage -> parens $ text "external package"
+ ForeignLabelInUnknownPackage -> parens $ text "unknown package"
-- -----------------------------------------------------------------------------
-- Machine-dependent knowledge about labels.
@@ -1698,6 +1738,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
SymbolPtr -> char 'L' <> ppLbl <> text "$non_lazy_ptr"
GotSymbolPtr -> ppLbl <> text "@GOTPCREL"
GotSymbolOffset -> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
| platformArch platform == ArchAArch64 -> ppLbl
| otherwise -> panic "pprDynamicLinkerAsmLabel"
@@ -1710,8 +1751,9 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
OSMinGW32 ->
case dllInfo of
- SymbolPtr -> text "__imp_" <> ppLbl
- _ -> panic "pprDynamicLinkerAsmLabel"
+ SymbolPtr -> text "__imp_" <> ppLbl
+ DataRefPtr -> text ".refptr." <> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
_ -> panic "pprDynamicLinkerAsmLabel"
where
@@ -1738,6 +1780,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
GotSymbolPtr -> ppLbl <> text "@gotpcrel"
GotSymbolOffset -> ppLbl
SymbolPtr -> text ".LC_" <> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
| platformArch platform == ArchPPC_64 ELF_V1
|| platformArch platform == ArchPPC_64 ELF_V2
@@ -1753,6 +1796,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
SymbolPtr -> text ".LC_" <> ppLbl
GotSymbolPtr -> ppLbl <> text "@got"
GotSymbolOffset -> ppLbl <> text "@gotoff"
+ _ -> panic "pprDynamicLinkerAsmLabel"
-- Figure out whether `symbol` may serve as an alias
-- to `target` within one compilation unit.
=====================================
compiler/GHC/CmmToAsm/PIC.hs
=====================================
@@ -152,6 +152,12 @@ cmmMakeDynamicReference config referenceKind lbl
AccessDirectly | ArchWasm32 <- platformArch platform ->
pure $ CmmLit $ CmmLabel lbl
+ -- See Note [Mingw .refptr mechanism]
+ AccessViaRefPtr -> do
+ let refPtr = mkDynamicLinkerLabel DataRefPtr lbl
+ addImport refPtr
+ return $ cmmLoadBWord platform (cmmMakePicReference config refPtr)
+
AccessDirectly -> case referenceKind of
-- for data, we might have to make some calculations:
DataReference -> return $ cmmMakePicReference config lbl
@@ -244,6 +250,7 @@ ncgLabelDynamic config = labelDynamic (ncgThisModule config)
data LabelAccessStyle
= AccessViaStub
| AccessViaSymbolPtr
+ | AccessViaRefPtr -- See Note [Mingw .refptr mechanism]
| AccessDirectly
howToAccessLabel :: NCGConfig -> Arch -> OS -> ReferenceKind -> CLabel -> LabelAccessStyle
@@ -271,6 +278,18 @@ howToAccessLabel :: NCGConfig -> Arch -> OS -> ReferenceKind -> CLabel -> LabelA
--
howToAccessLabel config _arch OSMinGW32 _kind lbl
+ -- If we have a data symbol where it is not known if it is in the same
+ -- PE or another PE, then we resort to the .refptr mechanism.
+ -- See Note [Mingw .refptr mechanism]
+ --
+ -- Note that we do this _even when_ not ncgExternalDynamicRefs, because
+ -- -fexternal-dynamic-refs is about Haskell code being built as DLLs.
+ -- But ForeignLabelInUnknownPackage is about where foreign/C symbols
+ -- come from, which can always be from external DLLs (or static libs).
+ | isForeignLabelUnknownPackage lbl
+ , not (isCFunctionLabel lbl)
+ = AccessViaRefPtr
+
-- Assume all symbols will be in the same PE, so just access them directly.
| not (ncgExternalDynamicRefs config)
= AccessDirectly
@@ -627,6 +646,18 @@ pprImportedSymbol config importedLbl = case (arch,os) of
text "\t.long" <+> ppr_lbl lbl ]
_ -> empty
+ -- See Note [Mingw .refptr mechanism]
+ (_, OSMinGW32) -> case dynamicLinkerLabelInfo importedLbl of
+ Just (DataRefPtr, lbl)
+ -> lines_ [
+ text "\t.section\t.rdata$.refptr." <> ppr_lbl lbl
+ <> text ",\"dr\",discard,.refptr." <> ppr_lbl lbl,
+ text "\t.p2align\t3",
+ text ".globl\t" <> text ".refptr." <> ppr_lbl lbl,
+ text ".refptr." <> ppr_lbl lbl <> char ':',
+ text "\t.quad" <+> ppr_lbl lbl ]
+ _ -> empty
+
-- ELF / Linux
--
-- In theory, we don't need to generate any stubs or symbol pointers
=====================================
compiler/GHC/StgToCmm/Lit.hs
=====================================
@@ -97,8 +97,7 @@ mkSimpleLit platform = \case
(LitNumber LitNumWord64 i) -> CmmInt i W64
(LitFloat r) -> CmmFloat r W32
(LitDouble r) -> CmmFloat r W64
- (LitLabel fs fod)
- -> let -- TODO: Literal labels might not actually be in the current package...
- labelSrc = ForeignLabelInThisPackage
- in CmmLabel (mkForeignLabel fs labelSrc fod)
- other -> pprPanic "mkSimpleLit" (ppr other)
+ (LitLabel fs fod) -> CmmLabel (mkForeignLabel fs labelSrc fod)
+ -- See Note [Mingw .refptr mechanism]
+ where labelSrc = ForeignLabelInUnknownPackage
+ other -> pprPanic "mkSimpleLit" (ppr other)
=====================================
hadrian/src/Builder.hs
=====================================
@@ -356,6 +356,10 @@ instance H.Builder Builder where
Ghc FindHsDependencies _ -> do
runGhcWithResponse path buildArgs buildInputs
+ Ghc LinkHs _ -> do
+ runGhcWithResponse path [ "-v" | verbosity >= Diagnostic ]
+ buildArgs
+
HsCpp -> captureStdout
Make dir -> cmd' buildOptions path ["-C", dir] buildArgs
=====================================
rts/Linker.c
=====================================
@@ -232,7 +232,7 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key,
static const char *
symbolTypeString (SymType type)
{
- switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN)) {
+ switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN | SYM_TYPE_RTS_DEF)) {
case SYM_TYPE_CODE: return "code";
case SYM_TYPE_DATA: return "data";
case SYM_TYPE_INDIRECT_DATA: return "indirect-data";
@@ -270,6 +270,9 @@ int ghciInsertSymbolTable(
SymType type,
ObjectCode *owner)
{
+ /* mask out SYM_TYPE_RTS_DEF, see Note [RTS symbol exports] */
+ type &= ~SYM_TYPE_RTS_DEF;
+
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
if (!pinfo) /* new entry */
{
@@ -472,16 +475,7 @@ initLinker_ (int retain_cafs)
symhash = allocStrHashTable();
/* populate the symbol table with stuff from the RTS */
- IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
- for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
- IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
- if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
- symhash, sym->lbl, sym->addr,
- sym->strength, sym->type, NULL)) {
- barf("ghciInsertSymbolTable failed");
- }
- }
- IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+ initLinkerRtsSyms(symhash);
/* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
* that can be overrided by linking in an object with a corresponding
=====================================
rts/RtsSymbols.c
=====================================
@@ -9,6 +9,7 @@
#include "ghcplatform.h"
#include "Rts.h"
#include "RtsSymbols.h"
+#include "LinkerInternals.h"
#include "TopHandler.h"
#include "HsFFI.h"
@@ -50,6 +51,18 @@ extern char **environ;
/* -----------------------------------------------------------------------------
* Symbols to be inserted into the RTS symbol table.
+ *
+ * Note [Naming Scheme for Symbol Macros]
+ *
+ * SymI_*: symbol is internal to the RTS. It resides in an object
+ * file/library that is statically.
+ * SymE_*: symbol is external to the RTS library. It might be linked
+ * dynamically.
+ *
+ * Sym*_HasProto : the symbol prototype is imported in an include file
+ * or defined explicitly
+ * Sym*_NeedsProto: the symbol is undefined and we add a dummy
+ * default proto extern void sym(void);
*/
#define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
@@ -1127,12 +1140,21 @@ extern char **environ;
SymI_HasProto(hs_word2float64)
-/* entirely bogus claims about types of these symbols */
-#define SymI_NeedsProto(vvv) extern void vvv(void);
-#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
-#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
-#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
-#define SymE_HasProto(vvv) SymI_HasProto(vvv);
+/* Declare prototypes for the symbols that need it, so we can refer
+ * to them in the rtsSyms table below.
+ *
+ * In particular, for the external ones (SymE_*) we use the dllimport attribute
+ * to indicate that (on Windows) they come from external DLLs. This attribute
+ * is ignored on other platforms.
+ *
+ * The claims about the types of these symbols are entirely bogus.
+ */
+#define SymI_NeedsProto(vvv) extern void vvv(void);
+#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
+#define SymE_NeedsProto(vvv) extern __attribute__((dllimport)) void vvv(void);
+#define SymE_NeedsDataProto(vvv) extern __attribute__((dllimport)) StgWord vvv[];
+
+#define SymE_HasProto(vvv) /**/
#define SymI_HasProto(vvv) /**/
#define SymI_HasDataProto(vvv) /**/
#define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
@@ -1161,17 +1183,23 @@ RTS_SYMBOLS_PRIM
#undef SymE_NeedsProto
#undef SymE_NeedsDataProto
+/* See Note [Naming Scheme for Symbol Macros] */
+
#define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
+ (void*)(&(vvv)), STRENGTH_NORMAL, \
+ SYM_TYPE_CODE | SYM_TYPE_RTS_DEF },
#define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
+ (void*)(&(vvv)), STRENGTH_NORMAL, \
+ SYM_TYPE_DATA | SYM_TYPE_RTS_DEF },
#define SymE_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
#define SymE_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
-#define SymI_NeedsProto(vvv) SymI_HasProto(vvv)
-#define SymI_NeedsDataProto(vvv) SymI_HasDataProto(vvv)
+#define SymI_NeedsProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+ (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
+#define SymI_NeedsDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+ (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
#define SymE_NeedsProto(vvv) SymE_HasProto(vvv)
#define SymE_NeedsDataProto(vvv) SymE_HasDataProto(vvv)
@@ -1181,7 +1209,16 @@ RTS_SYMBOLS_PRIM
{ MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(xxx)), strength, ty },
-RtsSymbolVal rtsSyms[] = {
+
+/* Populate the symbol table with stuff from the RTS. */
+void initLinkerRtsSyms (StrHashTable *symhash) {
+
+ /* The address of data symbols with the dllimport attribute are not
+ * compile-time constants and so cannot be used in constant initialisers.
+ * For this reason, rtsSyms is a local variable within this function
+ * rather than a global constant (as it was historically).
+ */
+ const RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS
RTS_RET_SYMBOLS
RTS_POSIX_ONLY_SYMBOLS
@@ -1196,7 +1233,19 @@ RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS_PRIM
SymI_HasDataProto(nonmoving_write_barrier_enabled)
{ 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
-};
+ };
+
+ IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
+ for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
+ IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
+ if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
+ symhash, sym->lbl, sym->addr,
+ sym->strength, sym->type, NULL)) {
+ barf("ghciInsertSymbolTable failed");
+ }
+ }
+ IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+}
// Note [Extra RTS symbols]
=====================================
rts/RtsSymbols.h
=====================================
@@ -9,6 +9,7 @@
#pragma once
#include "ghcautoconf.h"
+#include "Hash.h"
#if defined(LEADING_UNDERSCORE)
#define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
@@ -21,8 +22,8 @@ typedef char SymbolName;
/* What kind of thing a symbol identifies. We need to know this to determine how
* to process overflowing relocations. See Note [Processing overflowed relocations].
- * This is bitfield however only the option SYM_TYPE_DUP_DISCARD can be combined
- * with the other values. */
+ * This is bitfield however only the option SYM_TYPE_DUP_DISCARD and
+ * SYM_TYPE_RTS_DEF can be combined with the other values. */
typedef enum _SymType {
SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */
SYM_TYPE_DATA = 1 << 1, /* the symbol is data */
@@ -31,8 +32,34 @@ typedef enum _SymType {
however if a duplicate is found with a mismatching
SymType then discard this one. */
SYM_TYPE_HIDDEN = 1 << 4, /* the symbol is hidden and should not be exported */
+ SYM_TYPE_RTS_DEF = 1 << 5, /* the symbol is defined in the RTS DSO */
} SymType;
+/* Note [RTS symbol exports]
+ * SymType and SymStrength are used by the RTS's internal (aka GHCi) linker.
+ * They're also used by the rtsSyms array, which is used to pre-populate the
+ * GHCi linker symbol table (see ghciInsertSymbolTable calls in initLinker_).
+ * The rtsSyms array has a secondary purpose: to be the source of truth for
+ * which symbols are supposed to be exported from the RTS, when the RTS is
+ * built as a shared object (i.e. .so, .dll), which is handled by the native
+ * system linker.
+ *
+ * This is related but different to the GHCi linker. The GHCi linker's symbol
+ * table is pre-populated with RTS exported symbols but also additional symbols
+ * from dependent libraries and a few platform specific symbols and hacks (see
+ * for example Note [Strong symbols], and Note [Symbols for MinGW's printf],
+ * Note [Extra RTS symbols]). The GHCi linker does not need to distinguish
+ * known symbols that are defined within the RTS from known symbols from other
+ * libs. All of them are available to resolve against.
+ *
+ * So to serve the secondary purpose, we use the SYM_TYPE_RTS_DEF flag, which
+ * we combine with the other flags (CODE, DATA etc). We arrange to ignore this
+ * flag when pre-populating the GHCi linker symbol table. But we make use of it
+ * to dump the symbols that are intended to be exported from the RTS. This can
+ * be used by the build system and native linker to limit the symbols exported
+ * from the RTS shared object. See utils/rts-sym/rts-sym.c
+ */
+
typedef enum _SymStrength {
STRENGTH_NORMAL,
STRENGTH_WEAK,
@@ -46,7 +73,7 @@ typedef struct _RtsSymbolVal {
SymType type;
} RtsSymbolVal;
-extern RtsSymbolVal rtsSyms[];
+void initLinkerRtsSyms (StrHashTable *symhash);
extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
=====================================
utils/rts-syms/rts-syms.c
=====================================
@@ -0,0 +1,97 @@
+/* A utility to export the symbol table of the RTS. The RTS has a built-in
+ * linker, and has a pre-populated table of known RTS symbols.
+ *
+ * This is used primarily to generate input files for linkers, to limit the
+ * symbols exported from the RTS to those we want to export.
+ *
+ * This utility can generate Windows .def files (for making DLLs), or GNU ld
+ * linker scripts (used by GNU ld and LLVM ld for .so libs). We also support
+ * a raw dump format for curiosity or debugging.
+ */
+
+#include "RtsSymbols.h"
+
+/* RtsSymbols.h is an internal header file.
+ * It defines a symbol table (reordered and simplified for clarity):
+
+extern RtsSymbolVal rtsSyms;
+
+typedef struct _RtsSymbolVal {
+ const SymbolName* lbl;
+ SymbolAddr* addr;
+ SymStrength strength;
+ SymType type;
+ } RtsSymbolVal;
+
+typedef enum _SymType {
+ SYM_TYPE_CODE,
+ SYM_TYPE_DATA,
+ SYM_TYPE_INDIRECT_DATA,
+ SYM_TYPE_DUP_DISCARD,
+ SYM_TYPE_HIDDEN,
+ } SymType;
+
+ typedef enum _SymStrength {
+ STRENGTH_NORMAL,
+ STRENGTH_WEAK,
+ STRENGTH_STRONG,
+ } SymStrength;
+
+ */
+
+#include <stdio.h>
+
+void dump_nm_bsd(void);
+void dump_nm_posix(void);
+void init_ghc_hs_iface(void);
+
+int main (int argc, char *argv[]) {
+ //TODO: formats: raw, map and def
+ dump_nm_posix();
+}
+
+char *format_sym_type(SymType type);
+char *format_sym_strength(SymStrength strength);
+
+void dump_nm_bsd() {
+ for (int i = 0; rtsSyms[i].addr != 0; i++) {
+ RtsSymbolVal *sym = &rtsSyms[i];
+ printf("%.16lx %s%s %s\n", (unsigned long)(sym->addr),
+ format_sym_strength(sym->strength),
+ format_sym_type(sym->type),
+ sym->lbl);
+ }
+}
+
+void dump_nm_posix() {
+ for (int i = 0; rtsSyms[i].addr != 0; i++) {
+ RtsSymbolVal *sym = &rtsSyms[i];
+ printf("%s %s\n", sym->lbl, format_sym_type(sym->type));
+ }
+}
+
+char *format_sym_type(SymType type) {
+ /* Ignore SYM_TYPE_DUP_DISCARD, SYM_TYPE_HIDDEN as they do not occur in
+ * the RTS built-in symbol table. (They can occur in other loaded libraries).
+ */
+ switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN | SYM_TYPE_RTS_DEF)) {
+ case SYM_TYPE_CODE: return "T";
+ case SYM_TYPE_DATA: return "D";
+ case SYM_TYPE_INDIRECT_DATA: return "I";
+ default: return " ";
+ }
+}
+
+char *format_sym_strength(SymStrength strength) {
+ switch (strength) {
+ case STRENGTH_NORMAL: return " ";
+ case STRENGTH_WEAK: return "W";
+ case STRENGTH_STRONG: return "S";
+ default: return " ";
+ }
+}
+
+void init_ghc_hs_iface(void) {
+ return;
+};
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a1ed49b90a53e7299294ee4c60d81…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9a1ed49b90a53e7299294ee4c60d81…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/andreask/ticked_joins] Allow join point Ids to occur below ticks & casts
by sheaf (@sheaf) 02 Feb '26
by sheaf (@sheaf) 02 Feb '26
02 Feb '26
sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC
Commits:
d48c2efa by sheaf at 2026-02-02T11:10:23+01:00
Allow join point Ids to occur below ticks & casts
This commit classifies all join points into two categories:
- true join points
- quasi join points
A quasi join point is a join point for which a jump is enclosed within
a profiling tick or a cast.
The only operational difference is that, for quasi join points, we
cannot perform the case-of-case transformation described in
Note [Join points and case-of-case] in GHC.Core.Opt.Simplify.Iteration.
All of this is explained in detail in Note [Quasi join points].
Fixes #26693 and #26642
Improves on #14610, #26157 and #26422, as it means casts/profiling ticks
don't prevent join points, but it doesn't entirely fix these issues
because we are still inhibiting optimisations (lack of case-of-case).
- - - - -
31 changed files:
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CSE.hs
- compiler/GHC/Core/Opt/Exitify.hs
- compiler/GHC/Core/Opt/FloatIn.hs
- compiler/GHC/Core/Opt/FloatOut.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Rules.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- testsuite/tests/profiling/should_run/T2552.prof.sample
- testsuite/tests/profiling/should_run/ioprof.prof.sample
- testsuite/tests/profiling/should_run/scc001.prof.sample
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d48c2efaab0830a15e0ff46e138e95d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d48c2efaab0830a15e0ff46e138e95d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0