[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] 47 commits: Add 'backendInfoTableMapValidity' backend predicate
by Duncan Coutts (@dcoutts) 16 Jul '26
by Duncan Coutts (@dcoutts) 16 Jul '26
16 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC
Commits:
66d1a5d5 by fendor at 2026-07-07T16:57:56-04:00
Add 'backendInfoTableMapValidity' backend predicate
Check whether the backend supports the `-finfo-table-map` flag and
ignore it otherwise.
Improve by-design documentation of `backendCodeOutput`.
`Backend` is **abstract by design**. Make this clearer in
`backendCodeOutput` which is incorrectly being used as a proxy for
`Backend`.
Instead, define the desired property predicates in GHC.Driver.Backend
In the process, make `backendCodeOutput` total.
- - - - -
74f1071d by fendor at 2026-07-07T16:57:56-04:00
Add failing test for `-finfo-table-map` and bytecode backend
If you compile a module using the bytecode backend, with
-finfo-table-map, then the info table map doesn't get populated for the
module.
This is because the -finfo-table-map code path is implemented mostly in
the StgToCmm phase which isn't run when creating bytecode.
Ticket #27039
- - - - -
28d63bca by mangoiv at 2026-07-07T16:59:16-04:00
ci: don't fail nightly if there have been no changes that night
Fixes #27127
- - - - -
4ebfc478 by Rodrigo Mesquita at 2026-07-08T04:47:53-04:00
ttg: Using ShortText over FastString in the AST
To make the AST independent of GHC, this commit replaces usages of
`FastString` with `HText` in the AST, killing the last edge from
Language.Haskell.* to GHC.* modules.
Even though we /do/ want to use FastStrings in general -- critically in
Names or Ids -- there is no particular reason for the FastStrings that
occur in the AST proper to be FastStrings. Strings in the AST are
typically unique and don't benefit particularly from being interned
FastStrings with Uniques for fast comparison.
`HText` is a type synonym for `ShortText` which uses GHC's Modified
UTF-8 encoding exclusively.
Modified UTF-8 must be used to represent the Haskell AST because the
Haskell Report allows surrogate code points. `Data.Text.Text` functions
use Standard UTF-8 which replace surrogates with a placeholder value,
thus `Data.Text.Text` is unsuitable for AST strings. See the
`Language.Haskell.Syntax.Text` module header for more details.
Final progress towards #21592
Closes #21628
- - - - -
d910b353 by Simon Peyton Jones at 2026-07-08T04:48:36-04:00
Update equality-type documenation in GHC.Builtin.Types.Prim
Fix #27466
- - - - -
b2530542 by Simon Peyton Jones at 2026-07-08T04:48:36-04:00
Honour -dsuppress-coercions in GHC.Core.TyCo.pprCo
Fixes #27467
- - - - -
9a73179a by Facundo Domínguez at 2026-07-08T04:49:26-04:00
Add item to MR checklist asking to squash fixup commits after approval
The checklist has an item that reads
All commits are either individually buildable or squashed.
This item could be checked immediately after sending the merge request
though. If reviewers ask for amends later on, and the author amends
the merge request, there was no item that would remind the contributors
to squash the fixup commits before landing.
This commit adds a new item
After all approvals and before landing: all fixup commits are squashed with their originating commits.
which should be harder to mark as done before approvals have been given.
- - - - -
ed09895d by Andreas Klebinger at 2026-07-08T16:53:27-04:00
Fix a profiling race condition resulting in segfaults.
StgToCmm: Don't assume tagged FUN closures in closureCodeBody.
When entering a closure the self/node pointer might not be tagged in
some situations when a thunk is evaluated by multiple threads.
So we most AND away the tag bits rather than subtracting an expected tag.
Apply.cmm: Fix a race condition occuring when a thunk is mutated during GC.
In stg_ap_0_fast when might need to run GC before entering a thunk. If this happens
another thread or the GC itself might mutate the closure making entering it no longer
valid. We now check for this.
Add test and changelog for #27123 fixes.
- - - - -
67c03eb2 by Cheng Shao at 2026-07-08T16:54:09-04:00
ghc-heap: fix invalid srtlen returned by peekItbl when no-TNTC
This patch fixes the no-TNTC code path of `peekItbl` so that it looks
at the right memory address when reading the `srt` field from the
`StgInfoTable_` struct. Also adds a `T27465` regression test that
reproduces the bug on no-TNTC builds before the fix. Fixes #27465.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
2ecabb4f by Zubin Duggal at 2026-07-09T09:23:25-04:00
hadrian: binary-dist-dir should not be the default target
Revert behaviour to pre 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
In 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2, we applied the following behaviour change:
```
hadrian: Build stage 2 cross compilers
...
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
```
This is a major regression to development experience, a plain hadrian/build
--freeze1 now takes ages because we rebuild all docs (which need to go in the
binary dist dir).
`binary-dist-dir` is the wrong default target for regular GHC development work
Fixes #27445
- - - - -
e16388e3 by Zubin Duggal at 2026-07-09T09:23:25-04:00
.gitignore: Add the hadrian system.config introduced by commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Since
commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Author: Matthew Pickering <matthewtpickering(a)gmail.com>
Date: Thu Dec 21 16:17:41 2023 +0000
hadrian: Build stage 2 cross compilers
./configure produces /hadrian/cfg/system.config.{host,target}
Add these to .gitignore
- - - - -
7e8abf41 by Alan Zimmerman at 2026-07-09T09:24:12-04:00
EPA: Replace AnnListItem with simply [TrailingAnn]
Remove the unnecessary wrapper around a single field.
- - - - -
29032f17 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Keep real reason for fragile test failures
- - - - -
c34e03a7 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Fall back to the failure reason for empty JUnit bodies
- - - - -
409d40f0 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Show output diffs in JUnit output
Also refactor compare_outputs to return essentially a `Maybe Diff`
(`CompareOutput`) instead of a bool, but more pythonic. This
allows us to pass the diff through nice.
- - - - -
06fee1ab by Zubin Duggal at 2026-07-09T09:24:58-04:00
perf notes: include stat deviation and acceptance window in notes so they show up in gitlab
- - - - -
57c0f32c by mangoiv at 2026-07-10T11:08:38-04:00
driver: enable -finter-module-far-jumps by default
this fixes a compatibility bug with certain binutils/gcc versions where
we were seeing jump offset overflow errors.
This commit can probably reverted if we stop supporting the problematic
binutils/gcc verions (2.44 and 14.2, respectively)
Reolves #26994
- - - - -
4396a6f2 by Andrea Vezzosi at 2026-07-10T11:09:25-04:00
[Fix #27287] preserve ModBreaks in ModIface
- - - - -
ed261a7e by Cheng Shao at 2026-07-14T17:59:38-04:00
hadrian: fix HLS support
This patch fixes hadrian's HLS support so one can rely on HLS when
working on the hadrian codebase. Fixes #27480.
Not building/linking shared libraries for hadrian is a severely
premature optimization; this top-level setting in `cabal.project` only
affects home packages while the dependencies in the cabal store are
built with vanilla/dynamic anyway, and even adding dynamic builds to
home packages would not be costly due to cabal's usage of
`-dynamic-too`.
- - - - -
eee8ec5b by Cheng Shao at 2026-07-14T18:00:20-04:00
compiler: fix miscompiled %load_relaxed, add missing %store_relaxed
This patch fixes the %load_relaxed cmm primop compilation logic to
correctly use relaxed memory ordering, and adds the missing
%store_relaxed primop. Parsing logic of %load/%store with explicit
ordering is covered in the AtomicFetch test case. Fixes #27483.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
1718230f by Alan Zimmerman at 2026-07-14T18:01:06-04:00
EPA: Keep binds and sigs together in HsValBindsLR
We combine them into a single list for GhcPs, wrapped in the
ValBind data type, which is the bind equivalent of ValD, having
constructors for binds and sigs.
This simplifies exact print processing, especially when using it to
update the contents of local binds, as we no longer need AnnSortKey
BindTag
- - - - -
6bd1ad2a by Andreas Klebinger at 2026-07-14T18:01:49-04:00
Bump nofib submodule to account for MonoLocalBinds.
New versions of GHC enable MonoLocalBinds by default.
This breaks some of the benchmarks. I've fixed this and
this bump pulls in that fix.
- - - - -
7eb0f1c9 by Cheng Shao at 2026-07-14T18:02:31-04:00
testsuite: fix bytecodeIPE test under +ipe flavours
This patch fixes the bytecodeIPE test under +ipe flavours. It used to
fail under +ipe because the RTS is built with IPE info, then
stg_AP_info in RTS carries IPE info, so whereFrom wouldn't return
Nothing. Now the test checks IPE info of a datacon in the ghci-loaded
module which is not affected by whether the RTS is built with IPE info
or not. Fixes #27498.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ef038aae by cydparser at 2026-07-15T04:35:41-04:00
Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
In rts/Capability.c, `capabilities` is an array of pointers, but it was allocated as if it were an
array of Capability's.
- - - - -
d377e83e by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_readTVarIOzh
This patch fixes missing UNTAG on the current value closure read from
StgTVar. UNTAG is a no-op when it's stg_TREC_HEADER_info which is word
aligned; it may be a tagged closure, and reading info table from the
tagged address is an unaligned load which may cause issues on
platforms with strict alignment requirements.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
8ed03842 by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_control0zh_ll
This patch fixes missing UNTAG on the cont closure returned by
captureContinuationAndAbort. In case it's not NULL,
captureContinuationAndAbort returns a tagged StgContinuation closure,
in which case it must be untagged before accessing the
apply_mask_frame field.
In the past it worked out of luck: when apply_mask_frame was NULL then
mask_frame_offset is also 0 so the control flow didn't diverge to a
wrong path. Still, this is horribly wrong and will crash once
StgContinuation struct is refactored and fields are shuffled around.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
5aa7000a by Cheng Shao at 2026-07-15T04:37:08-04:00
compiler: fix redundant AP thunk codegen when not using -ticky-ap-thunk
This patch fixes a double negation confusion in !7525 that results in
some redundant AP thunk code generation when not using
-ticky-ap-thunk. Now, we use `stgToCmmUseStdApThunk` to indicate
whether precomputed AP thunks in the RTS should be used, which
defaults to `True`, unless `-ticky-ap-thunk` is passed.
`-finfo-table-map` now also implies `-ticky-ap-thunk`, since when
doing IPE profiling we want the generated AP thunks to be unique.
Fixes #27502.
-------------------------
Metric Decrease:
T3064
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
d43a7b7a by Brian McKenna at 2026-07-15T20:10:04+02:00
Strip ticks when desugaring bool guards
The special `considerAccessible` pattern was broken when compiling
with debug info. Compiling with debug info wraps expressions with
`SourceNote` ticks, which broke the internals of the
`desugarBoolGuard` function. Ticks are now ignored within this
function.
Fixes #27360
- - - - -
ede4b17b by Ben Gamari at 2026-07-15T22:59:53-04:00
base: Display ExceptionContext in WhileHandling's textual description
As originally-implemented the implementation for
`WhileHandling(displayExceptionAnnotation)` would display the
`ExceptionContext` of the exception which it carries (as this was the
behavior of `displayException`, in terms of which
`displayExceptionAnnotation` was implemented).
However, in 284ffab3 the definition of `SomeException(displayException)`
was changed to exclude the `ExceptionContext`. This means that
`WhileHandling(displayExceptionAnnotation)` fails to describe the
provenance of the exception which it captures, greatly limiting its
utility.
Return the implementation to its originally-specified behavior by
implementing `WhileHandling(displayExceptionAnnotation)` in terms of
`displayExceptionWithInfo`.
Fixes #27456.
- - - - -
4f54bcc1 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Move THREADED_RTS-conditional struct members to end of Capability
Accessing members of the Capability struct from CMM code rely on
accessor macros. (The macros are generated by deriveConstants).
These macros have a single definition. This means that the offsets of
all struct members must *not* vary based on THREADED_RTS vs
!THREADED_RTS. This requires that any struct members that are
conditional on THREADED_RTS must occur after the unconditional struct
members. Hence we move all the ones that are conditional on
THREADED_RTS to the end.
Add a deriveConstants entry for the iomgr member of the Capability
struct, which was the motivation for this change.
Add warning messages to help our future selves. Debugging this took me
a couple hours in gdb!
- - - - -
74adf094 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Make the IOManager API use CapIOManager rather than Capability
This makes the API somewhat more self-contained and more consistent.
Now the IOManager API and each of the backends takes just the I/O
manager structure. Previously we had a bit of a mixture, depending on
whether the function needed access to the Capability or just the
CapIOManager.
We still need access to the cap, so we introduce a back reference to
reach the capability, via iomgr->cap.
Convert all uses in select and poll backends, but not win32 ones.
Convert callers in the scheduler and elsewhere.
Also convert the three CMM primops that call IOManager APIs. They just
need to use Capability_iomgr(MyCapability()).
- - - - -
7ef31daf by Duncan Coutts at 2026-07-16T09:14:38+01:00
Split posix/MIO.c out of posix/Signals.c
The MIO I/O manager was secretly living inside the Signals file.
Now it gets its own file, like any other self-respecting I/O manager.
- - - - -
12382f85 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Rationalise some scheduler run queue utilities
Move them all to the same place in the file.
Make some static that were used only internally.
Also remove a redundant assignment after calling truncateRunQueue that
is already done within truncateRunQueue.
- - - - -
87367a1d by Duncan Coutts at 2026-07-16T09:14:38+01:00
Rename initIOManager{AfterFork} to {re}startIOManager
These are more accurate names, since these actions happen after
initialisation and are really about starting (or restarting) background
threads.
- - - - -
e7326bb0 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Free per-cap I/O managers during shutdown and forkProcess
Historically this was not strictly necessary. The select and win32
legacy I/O managers did not maintain any dynamically allocated
resources. The new poll one does (an auxillary table), and so this
should be freed.
After forkProcess, all threads get deleted. This includes threads
waiting on I/O or timers. So as of this patch, resetting the I/O
manager is just about tidying things up. For example, for the poll
I/O manager this will reset the size of the AIOP table (which
otherwise grows but never shrinks).
In future however the re-initialising will become neeecessary for
functionality, since some I/O managers will need to re-initialise
wakeup fds that are set CLOEXEC.
- - - - -
76125f45 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Add a TODO to the MIO I/O manager
The direction of travel is to make I/O managers per-capability and have
all their state live in the struct CapIOManager. The MIO I/O manager
however still has a number of global variables.
It's not obvious how handle these globals however.
- - - - -
73ddbe67 by Duncan Coutts at 2026-07-16T09:14:38+01:00
Add a FIXME note in the Poll I/O manager
- - - - -
3feb9efe by Duncan Coutts at 2026-07-16T09:14:39+01:00
Add missing updateRemembSetPushClosure in poll I/O manager
For the non-moving GC.
- - - - -
d4932eb6 by Duncan Coutts at 2026-07-16T09:14:39+01:00
Minor doc improvement to struct StgAsyncIOOp member outcome
Mention the enumeration names, as well as their numeric values. The rest
of the code uses the enum names.
- - - - -
a9bff207 by Duncan Coutts at 2026-07-16T09:14:39+01:00
Minor doc improvements for StgTSOBlockInfo
Clarify that certain union members are used only by certain legacy
I/O managers. Hopefully we will be able to remove these at some point.
- - - - -
06e132fd by Duncan Coutts at 2026-07-16T09:14:39+01:00
Avoid exporting various win32-specific rts symbols
The BeginPrivate.h / EndPrivate.h scheme works perfectly well on
Windows, but all of the rts/win32/*.h files were not using it.
- - - - -
bc110400 by Duncan Coutts at 2026-07-16T09:14:39+01:00
Remove wakeupIOManager, ioManagerWakeup and setIOManagerWakeupFd
We no longer need wakeupIOManager for the threaded RTS case, so we can
remove it and the bits only needed to support it. This includes the
pipe/eventfd fd shared between the RTS and the in-library I/O manager
used for waking up the I/O manager thread. The pipe/eventfd still
exists, but it no longer has to be communicated to the RTS, since the
RTS no longer needs to use it.
So we remove the RTS API export setIOManagerWakeupFd, and remove uses of
it within the I/O managers in ghc-internal.
- - - - -
d41446b8 by Duncan Coutts at 2026-07-16T09:14:39+01:00
Add a new interruptIOManager API for the I/O managers
It will be used to interrupt awaitCompletedTimeoutsOrIO. Also update the
return type and docs for awaitCompletedTimeoutsOrIO to have it return
false when it gets interrupted, and have no useful post condition in
that case.
- - - - -
991324b1 by Duncan Coutts at 2026-07-16T09:14:39+01:00
Add interruptIOManager support for select I/O manager
Uses the FdWakup mechanism.
- - - - -
ba470b5a by Duncan Coutts at 2026-07-16T09:14:39+01:00
Add interruptIOManager support for poll I/O manager
Uses the FdWakup mechanism.
A quirk we have to cope with is that we now need to poll one more fd --
the wakeup_fd_r -- but this fd has no corresponding entry in the
aiop_table. This is awkward since we have set up our aiop_poll_table to
be an auxilliary table with matching indicies.
The solution this patch uses (and described in the comments) is to have
two tables: struct pollfd *aiop_poll_table, *full_poll_table;
and to have the aiop_poll_table alias the tail of the full_poll_table.
The head entry in the full_poll_table is the extra fd. So we poll the
full_poll_table, while the aiop_poll_table still has matching indicies
with the aiop_table.
Hurrah for C aliasing rules.
- - - - -
6197fecf by Duncan Coutts at 2026-07-16T09:14:39+01:00
Add interruptIOManager support for win32 legacy I/O manager
And remove unused related helper resetAbandonRequestWait. It is not
called because the event is created in auto-reset mode, so never needs
to be reset manually.
- - - - -
c0393a7c by Duncan Coutts at 2026-07-16T09:14:39+01:00
Note lack of interruptIOManager support for WinIO I/O manager
Though there's a plausible design, we can't sanely test it at the moment
due to related WinIO bugs. Filed as issue #27403.
- - - - -
260 changed files:
- .gitignore
- .gitlab-ci.yml
- .gitlab/merge_request_templates/Default.md
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- + changelog.d/T21628
- + changelog.d/T27123.md
- + changelog.d/T27360
- + changelog.d/T27456
- + changelog.d/fix-cmm-atomic-load-store
- + changelog.d/fix-peekitbl-no-tntc
- + changelog.d/fix-use-std-ap-thunk
- + changelog.d/inter-module-far-jumps-aarch64-default
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Data/StringBuffer.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Main/Hsc.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- + compiler/GHC/HsToCore/Breakpoints/Types.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/HaddockLex.x
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Platform/Ways.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Foreign.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/FieldLabel.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Unit/Module/ModGuts.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Decls/Foreign.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Module/Name.hs
- + compiler/Language/Haskell/Syntax/Text.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- docs/users_guide/using-optimisation.rst
- ghc/GHCi/UI.hs
- hadrian/cabal.project
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/base/changelog.md
- libraries/base/tests/T15349.stderr
- libraries/ghc-boot/GHC/Data/ShortText.hs
- + libraries/ghc-heap/tests/T27465.hs
- + libraries/ghc-heap/tests/T27465.stdout
- libraries/ghc-heap/tests/all.T
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Manager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/TimerManager.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- nofib
- rts/Apply.cmm
- rts/Capability.c
- rts/Capability.h
- rts/ContinuationOps.cmm
- rts/IOManager.c
- rts/IOManager.h
- rts/IOManagerInternals.h
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/Schedule.c
- rts/Schedule.h
- rts/include/rts/IOInterface.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/TSO.h
- rts/posix/FdWakeup.h
- + rts/posix/MIO.c
- + rts/posix/MIO.h
- rts/posix/Poll.c
- rts/posix/Poll.h
- rts/posix/Select.c
- rts/posix/Select.h
- rts/posix/Signals.c
- rts/posix/Signals.h
- rts/posix/Timeout.c
- rts/posix/Timeout.h
- rts/rts.cabal
- rts/win32/AsyncMIO.c
- rts/win32/AsyncMIO.h
- rts/win32/AsyncWinIO.h
- rts/win32/AwaitEvent.c
- rts/win32/AwaitEvent.h
- rts/win32/ConsoleHandler.h
- rts/win32/MIOManager.h
- rts/win32/ThrIOManager.h
- rts/win32/WorkQueue.h
- rts/win32/veh_excn.h
- testsuite/driver/junit.py
- testsuite/driver/perf_notes.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/tests/cmm/should_run/AtomicFetch.hs
- testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm
- testsuite/tests/codeGen/should_compile/T25177.stderr
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/deSugar/should_fail/all.T
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/ghc-api/T25121_status.stdout
- testsuite/tests/ghc-api/annotations-literals/parsed.hs
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/ghci/scripts/all.T
- + testsuite/tests/ghci/scripts/bytecodeIPE.hs
- + testsuite/tests/ghci/scripts/bytecodeIPE.script
- + testsuite/tests/ghci/scripts/bytecodeIPE.stdout
- testsuite/tests/ghci/should_run/Makefile
- + testsuite/tests/ghci/should_run/T27287.hs
- + testsuite/tests/ghci/should_run/T27287.stdout
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- testsuite/tests/module/mod185.stderr
- testsuite/tests/numeric/should_compile/T15547.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- + testsuite/tests/parser/should_run/StringStartsWithNull.hs
- + testsuite/tests/parser/should_run/StringStartsWithNull.stdout
- testsuite/tests/parser/should_run/all.T
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- + testsuite/tests/rts/T27123.hs
- testsuite/tests/rts/all.T
- testsuite/tests/runghc/T7859.stderr-mingw32
- testsuite/tests/simplCore/should_compile/DataToTagFamilyScrut.stderr
- testsuite/tests/simplCore/should_compile/T14978.stdout
- testsuite/tests/simplCore/should_compile/T18013.stderr
- testsuite/tests/simplCore/should_compile/T24229a.stderr
- testsuite/tests/simplCore/should_compile/T24229b.stderr
- testsuite/tests/typecheck/should_compile/T15242.stderr
- testsuite/tests/typecheck/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/check-exact/check-exact.cabal
- utils/deriveConstants/Main.hs
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe8915f1f71844bbca95d6fa89b3c7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe8915f1f71844bbca95d6fa89b3c7…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] 3 commits: Add interruptIOManager support for poll I/O manager
by Duncan Coutts (@dcoutts) 16 Jul '26
by Duncan Coutts (@dcoutts) 16 Jul '26
16 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC
Commits:
8b83a7e2 by Duncan Coutts at 2026-07-16T09:02:50+01:00
Add interruptIOManager support for poll I/O manager
Uses the FdWakup mechanism.
A quirk we have to cope with is that we now need to poll one more fd --
the wakeup_fd_r -- but this fd has no corresponding entry in the
aiop_table. This is awkward since we have set up our aiop_poll_table to
be an auxilliary table with matching indicies.
The solution this patch uses (and described in the comments) is to have
two tables: struct pollfd *aiop_poll_table, *full_poll_table;
and to have the aiop_poll_table alias the tail of the full_poll_table.
The head entry in the full_poll_table is the extra fd. So we poll the
full_poll_table, while the aiop_poll_table still has matching indicies
with the aiop_table.
Hurrah for C aliasing rules.
- - - - -
26a76dbb by Duncan Coutts at 2026-07-16T09:02:50+01:00
Add interruptIOManager support for win32 legacy I/O manager
And remove unused related helper resetAbandonRequestWait. It is not
called because the event is created in auto-reset mode, so never needs
to be reset manually.
- - - - -
fe8915f1 by Duncan Coutts at 2026-07-16T09:02:50+01:00
Note lack of interruptIOManager support for WinIO I/O manager
Though there's a plausible design, we can't sanely test it at the moment
due to related WinIO bugs. Filed as issue #27403.
- - - - -
9 changed files:
- rts/IOManager.c
- rts/IOManagerInternals.h
- rts/posix/FdWakeup.h
- rts/posix/Poll.c
- rts/posix/Poll.h
- rts/win32/AsyncMIO.c
- rts/win32/AsyncMIO.h
- rts/win32/AwaitEvent.c
- rts/win32/AwaitEvent.h
Changes:
=====================================
rts/IOManager.c
=====================================
@@ -745,7 +745,7 @@ bool awaitCompletedTimeoutsOrIO(CapIOManager *iomgr)
#if defined(IOMGR_ENABLED_POLL)
case IO_MANAGER_POLL:
- awaitCompletedTimeoutsOrIOPoll(iomgr);
+ completed = awaitCompletedTimeoutsOrIOPoll(iomgr);
break;
#endif
@@ -757,7 +757,7 @@ bool awaitCompletedTimeoutsOrIO(CapIOManager *iomgr)
#if defined(IOMGR_ENABLED_WINIO)
case IO_MANAGER_WINIO:
#endif
- awaitCompletedTimeoutsOrIOWin32(iomgr->cap, true);
+ completed = awaitCompletedTimeoutsOrIOWin32(iomgr->cap, true);
break;
#endif
default:
@@ -784,6 +784,26 @@ void interruptIOManager(CapIOManager *iomgr)
break;
#endif
+#if defined(IOMGR_ENABLED_POLL)
+ case IO_MANAGER_POLL:
+ interruptIOManagerPoll(iomgr);
+ break;
+#endif
+
+#if defined(IOMGR_ENABLED_WIN32_LEGACY)
+ case IO_MANAGER_WIN32_LEGACY:
+ abandonRequestWait();
+ break;
+#endif
+
+#if defined(IOMGR_ENABLED_WINIO)
+ case IO_MANAGER_WINIO:
+ /* FIXME: no support yet for interrupting in WinIO I/O manager
+ * See issue #27403
+ */
+ break;
+#endif
+
default:
break;
}
=====================================
rts/IOManagerInternals.h
=====================================
@@ -46,10 +46,12 @@ struct _CapIOManager {
StgTSO *sleeping_queue;
#endif
-#if defined(IOMGR_ENABLED_SELECT)
- /* FDs for interrupting up the I/O manager when it is blocked waiting */
+#if defined(IOMGR_ENABLED_SELECT) || defined(IOMGR_ENABLED_POLL)
+#if defined(HAVE_PREEMPTION)
+ /* FDs for waking up the I/O manager when it is blocked waiting */
int interrupt_fd_r, interrupt_fd_w;
#endif
+#endif
#if defined(IOMGR_ENABLED_POLL)
/* AIOP and timeout collections shared by several I/O manager impls */
@@ -58,8 +60,11 @@ struct _CapIOManager {
#endif
#if defined(IOMGR_ENABLED_POLL)
- /* Auxiliary table with size and indexes matching the aiop_table */
- struct pollfd *aiop_poll_table;
+ /* Auxiliary table with size and indexes matching the aiop_table. This is
+ * aliased to the tail of the full poll table, which has a head entry for
+ * the wakeup_fd_r above, so we can also poll that fd.
+ */
+ struct pollfd *aiop_poll_table, *full_poll_table;
#endif
#if defined(IOMGR_ENABLED_WIN32_LEGACY)
=====================================
rts/posix/FdWakeup.h
=====================================
@@ -29,12 +29,14 @@
#include "BeginPrivate.h"
+#if defined(HAVE_PREEMPTION)
void newFdWakeup(int *fd_r, int *fd_w);
void closeFdWakeup(int fd_r, int fd_w);
/* This is safe to use from a signal handler */
void sendFdWakeup(int fd_w);
void collectFdWakeup(int fd_r);
+#endif
#include "EndPrivate.h"
=====================================
rts/posix/Poll.c
=====================================
@@ -41,6 +41,7 @@
#include "IOManagerInternals.h"
#include "Timeout.h"
+#include "FdWakeup.h"
/******************************************************************************
@@ -107,8 +108,9 @@ timeout (if any) as the poll() timeout parameter.
The CapIOManager structure for this I/O manager contains:
ClosureTable aiop_table;
- struct pollfd *aiop_poll_table;
+ struct pollfd *aiop_poll_table, *full_poll_table;
StgTimeoutQueue *timeout_queue;
+ int interrupt_fd_r, interrupt_fd_w;
We also support the Linux-specific ppoll API which supports higher resolution
time delays -- nanoseconds rather than milliseconds as in classic poll(). It
@@ -117,6 +119,15 @@ also allows the signal mask to be adjusted, but we do not make use of this.
int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *tmo_p, const sigset_t *sigmask);
+We have both aiop_poll_table and full_poll_table. This is to cope with needing
+to wait on the special extra file descriptor interrupt_fd_r. This fd is used to
+support waking the I/O manager when we are blocked in a poll call. This
+requires waiting on an extra fd that has no corresponding entry in the
+aiop_table. To manage this quirk, we alias the aiop_poll_table to be the tail
+of the full_poll_table and have the first entry of the full_poll_table be the
+interrupt_fd_r. This means the aiop_poll_table indicies match up exactly with
+the aiop_table, but still allows the full_poll_table to have an extra entry.
+
******************************************************************************/
/* Forward declarations */
@@ -129,16 +140,34 @@ static void reportPollError(int res, nfds_t nfds) STG_NORETURN;
void initCapabilityIOManagerPoll(CapIOManager *iomgr)
{
initClosureTable(&iomgr->aiop_table, ClosureTableCompact);
- iomgr->aiop_poll_table = NULL;
iomgr->timeout_queue = emptyTimeoutQueue();
+
+#if defined(HAVE_PREEMPTION)
+ newFdWakeup(&iomgr->interrupt_fd_r, &iomgr->interrupt_fd_w);
+#endif
+
+ iomgr->full_poll_table = stgMallocBytes(sizeof(struct pollfd) /* size 1 */,
+ "initCapabilityIOManagerPoll");
+ iomgr->full_poll_table[0] = (struct pollfd) {
+#if defined(HAVE_PREEMPTION)
+ .fd = iomgr->interrupt_fd_r,
+ .events = POLLIN,
+#else
+ .fd = -1, // unused
+ .events = 0, // unused
+#endif
+ .revents = 0
+ };
+ iomgr->aiop_poll_table = iomgr->full_poll_table+1; /* hence empty */
}
void freeCapabilityIOManagerPoll(CapIOManager *iomgr)
{
- if (iomgr->aiop_poll_table) {
- stgFree(iomgr->aiop_poll_table);
- }
+ stgFree(iomgr->full_poll_table);
+#if defined(HAVE_PREEMPTION)
+ closeFdWakeup(iomgr->interrupt_fd_r, iomgr->interrupt_fd_w);
+#endif
}
@@ -295,7 +324,7 @@ static void notifyIOCompletion(CapIOManager *iomgr, StgAsyncIOOp *aiop)
}
-static void processIOCompletions(CapIOManager *iomgr, int ncompletions)
+static bool processIOCompletions(CapIOManager *iomgr, int ncompletions)
{
/* The scheme we use with poll is that we have a dense poll table, and a
* corresponding table that maps to the closure table index. The poll
@@ -305,6 +334,19 @@ static void processIOCompletions(CapIOManager *iomgr, int ncompletions)
*/
debugTrace(DEBUG_iomanager, "processIOCompletions(ncompletions = %d)",
ncompletions);
+
+ bool interrupt = false;
+#if defined(HAVE_PREEMPTION)
+ /* If the interrupt_fd_r is ready, collect it */
+ if (iomgr->full_poll_table[0].revents) {
+ ASSERT(iomgr->full_poll_table[0].fd == iomgr->interrupt_fd_r);
+ collectFdWakeup(iomgr->interrupt_fd_r);
+ ncompletions--;
+ interrupt = true;
+ debugTrace(DEBUG_iomanager, "Received interrupt in poll I/O manager");
+ }
+#endif
+
struct pollfd *aiop_poll_table = iomgr->aiop_poll_table;
int n = ncompletions;
int i = 0;
@@ -357,11 +399,14 @@ static void processIOCompletions(CapIOManager *iomgr, int ncompletions)
i++;
}
}
+ return interrupt;
}
void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
{
+ ASSERT(iomgr->aiop_poll_table == iomgr->full_poll_table+1);
+
if (!isEmptyTimeoutQueue(iomgr->timeout_queue)) {
Time now = getProcessElapsedTime();
processTimeoutCompletions(iomgr, now);
@@ -369,20 +414,28 @@ void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
if (!isEmptyClosureTable(&iomgr->aiop_table)) {
- nfds_t nfds = sizeClosureTable(&iomgr->aiop_table);
+#if defined(HAVE_PREEMPTION)
+ /* the full_poll_table includes interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
+ struct pollfd *poll_table = iomgr->full_poll_table;
+#else
+ /* the aiop_poll_table does not include interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 0;
+ struct pollfd *poll_table = iomgr->aiop_poll_table;
+#endif
/* Poll for I/O readiness, without waiting. */
#if defined(HAVE_DECL_PPOLL) && HAVE_DECL_PPOLL == 1
/* We could use poll here, since we use no timeout, but for
consistency we use the same syscall as at the other call site. */
struct timespec tv = (struct timespec) { .tv_sec = 0, .tv_nsec = 0 };
- int res = ppoll(iomgr->aiop_poll_table, nfds, &tv, NULL);
+ int res = ppoll(poll_table, nfds, &tv, NULL);
debugTrace(DEBUG_iomanager,
"ppoll(nfds = %d, timeout.sec = 0, timeout.nsec = 0) = %d",
nfds, res);
#else
- int res = poll(iomgr->aiop_poll_table, nfds, 0);
+ int res = poll(poll_table, nfds, 0);
debugTrace(DEBUG_iomanager,
"poll(nfds = %d, timeout_ms = 0) = %d",
@@ -408,8 +461,12 @@ void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
}
-void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
+bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
{
+ bool interrupt = false; /* got woken up via interruptIOManager */
+
+ ASSERT(iomgr->aiop_poll_table == iomgr->full_poll_table+1);
+
/* Loop until we've woken up some threads. This loop is needed because the
* poll() timing isn't accurate, we sometimes sleep for a while but not
* long enough to wake up a thread in a threadDelay. Or we may need to
@@ -431,6 +488,16 @@ void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
*/
bool wait = emptyRunQueue(iomgr->cap);
+#if defined(HAVE_PREEMPTION)
+ /* the full_poll_table includes interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
+ struct pollfd *poll_table = iomgr->full_poll_table;
+#else
+ /* the aiop_poll_table does not include interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 0;
+ struct pollfd *poll_table = iomgr->aiop_poll_table;
+#endif
+
/* Decide if we are going to wait if no I/O is ready, either:
* poll only, wait indefinitely, or wait until a timeout.
*/
@@ -442,9 +509,8 @@ void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
#endif
/* Check for I/O readiness, possibly waiting. */
- nfds_t nfds = sizeClosureTable(&iomgr->aiop_table);
#if defined(HAVE_DECL_PPOLL) && HAVE_DECL_PPOLL == 1
- int res = ppoll(iomgr->aiop_poll_table, nfds, timeout_ns, NULL);
+ int res = ppoll(poll_table, nfds, timeout_ns, NULL);
debugTrace(DEBUG_iomanager,
"ppoll(nfds = %d, timeout.sec = %d, timeout.nsec = %d) = %d",
@@ -452,7 +518,7 @@ void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
timeout_ns == NULL ? 0 : timeout_ns->tv_nsec,
res);
#else
- int res = poll(iomgr->aiop_poll_table, nfds, timeout_ms);
+ int res = poll(poll_table, nfds, timeout_ms);
debugTrace(DEBUG_iomanager,
"poll(nfds = %d, timeout_ms = %d) = %d",
@@ -474,7 +540,7 @@ void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
} else if (res > 0) {
int ncompletions = res;
ASSERT(ncompletions <= (int)nfds);
- processIOCompletions(iomgr, ncompletions);
+ interrupt = processIOCompletions(iomgr, ncompletions);
// FIXME: do we also need to check for timeout completions now?
// we have a non-empty queue, but if !wait then we have also moved
// on and so we sould check for timeouts.
@@ -502,7 +568,9 @@ void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
}
} while (emptyRunQueue(iomgr->cap)
+ && !interrupt
&& (getSchedState() == SCHED_RUNNING));
+ return !interrupt;
}
static void reportPollError(int res, nfds_t nfds)
@@ -521,6 +589,14 @@ static void reportPollError(int res, nfds_t nfds)
}
+void interruptIOManagerPoll(CapIOManager *iomgr)
+{
+#if defined(HAVE_PREEMPTION)
+ sendFdWakeup(iomgr->interrupt_fd_w);
+#endif
+}
+
+
/* Helper function to double the size of the aiop_table and aiop_poll_table.
*/
static bool enlargeTables(CapIOManager *iomgr)
@@ -531,13 +607,17 @@ static bool enlargeTables(CapIOManager *iomgr)
bool ok = enlargeClosureTable(iomgr->cap, &iomgr->aiop_table, newcapacity);
if (RTS_UNLIKELY(!ok)) return false;
- /* Update the auxiliary aiop_poll_table to match */
- struct pollfd *aiop_poll_table;
- aiop_poll_table = stgReallocBytes(iomgr->aiop_poll_table,
- sizeof(struct pollfd) * newcapacity,
- "Poll.c: enlargeTables");
- iomgr->aiop_poll_table = aiop_poll_table;
+ /* Update the auxiliary aiop_poll_table to match. The full_poll_table is
+ * one bigger than the aiop_poll_table, since it has an extra entry at the
+ * front for interrupt_fd_r, with no corresponding aiop. */
+ iomgr->full_poll_table =
+ stgReallocBytes(iomgr->full_poll_table,
+ sizeof(struct pollfd) * (newcapacity+1),
+ "Poll.c: enlargeTables");
+ iomgr->aiop_poll_table = iomgr->full_poll_table+1;
+
/* Initialise the new part of the aiop_poll_table */
+ struct pollfd *aiop_poll_table = iomgr->aiop_poll_table;
for (int i = oldcapacity; i < newcapacity; i++) {
aiop_poll_table[i] = (struct pollfd) {
.fd = -1,
=====================================
rts/posix/Poll.h
=====================================
@@ -32,7 +32,8 @@ void asyncIOCancelPoll(CapIOManager *iomgr, StgAsyncIOOp *aiop);
/* Scheduler operations */
bool anyPendingTimeoutsOrIOPoll(CapIOManager *iomgr);
void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr);
-void awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr);
+bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr);
+void interruptIOManagerPoll(CapIOManager *iomgr);
#endif /* IOMGR_ENABLED_POLL */
=====================================
rts/win32/AsyncMIO.c
=====================================
@@ -221,8 +221,12 @@ shutdownAsyncIO(bool wait_threads)
* requests to make further progress. In the latter scenario,
* awaitRequests() will simply block waiting for worker threads
* to complete if the 'completedTable' is empty.
+ *
+ * The result reports if the wait completed successfully (typically with some
+ * work available), or was interrupted by abandonRequestWait(), with true
+ * meaning completed, and false meaning interrupted.
*/
-int
+bool
awaitRequests(bool wait)
{
#if !defined(THREADED_RTS)
@@ -246,7 +250,7 @@ start:
#endif
) {
OS_RELEASE_LOCK(&queue_lock);
- return 0;
+ return true;
}
if (completed_hw == 0) {
// empty table, drop lock and wait
@@ -259,22 +263,24 @@ start:
// a request was completed
break;
case WAIT_OBJECT_0 + 1:
+ // abandon_req_wait signaled, by abandonRequestWait()
+ return false;
case WAIT_TIMEOUT:
// timeout (unlikely) or told to abandon waiting
- return 0;
+ return true;
case WAIT_FAILED: {
DWORD dw = GetLastError();
fprintf(stderr, "awaitRequests: wait failed -- "
"error code: %lu\n", dw); fflush(stderr);
- return 0;
+ return true;
}
default:
fprintf(stderr, "awaitRequests: unexpected wait return "
"code %lu\n", dwRes); fflush(stderr);
- return 0;
+ return true;
}
} else {
- return 0;
+ return true;
}
goto start;
} else {
@@ -352,7 +358,7 @@ start:
completed_hw = 0;
ResetEvent(completed_req_event);
OS_RELEASE_LOCK(&queue_lock);
- return 1;
+ return true;
}
#endif /* !THREADED_RTS */
}
@@ -383,12 +389,6 @@ abandonRequestWait( void )
interruptIOManagerEvent ();
}
-void
-resetAbandonRequestWait( void )
-{
- ResetEvent(abandon_req_wait);
-}
-
#endif /* !defined(THREADED_RTS) */
HsInt rts_EINTR(void)
=====================================
rts/win32/AsyncMIO.h
=====================================
@@ -25,7 +25,7 @@ extern unsigned int addDoProcRequest(void* proc, void* param);
extern int startupAsyncIO(void);
extern void shutdownAsyncIO(bool wait_threads);
-extern int awaitRequests(bool wait);
+extern bool awaitRequests(bool wait);
extern void abandonRequestWait(void);
extern void resetAbandonRequestWait(void);
=====================================
rts/win32/AwaitEvent.c
=====================================
@@ -28,17 +28,21 @@
// Protected by sched_mutex.
static bool workerWaitingForRequests = false;
-void
+bool
awaitCompletedTimeoutsOrIOWin32(Capability *cap, bool wait)
{
+ bool interrupt = false;
do {
/* Try to de-queue completed IO requests
*/
workerWaitingForRequests = true;
if (is_io_mng_native_p())
awaitAsyncRequests(wait);
+ /* FIXME: no support yet for interrupting in WinIO I/O manager
+ * See issue #27403
+ */
else
- awaitRequests(wait);
+ interrupt = !awaitRequests(wait);
workerWaitingForRequests = false;
// If a signal was raised, we need to service it
@@ -47,11 +51,12 @@ awaitCompletedTimeoutsOrIOWin32(Capability *cap, bool wait)
// does it and I'm feeling too paranoid to refactor it today --SDM
if (stg_pending_events != 0) {
startSignalHandlers(cap);
- return;
+ // This will normally cause emptyRunQueue to become false and
+ // thus we will drop out of the loop.
}
- // The return value from awaitRequests() is a red herring: ignore
- // it. Return to the scheduler if !wait, or
+ // The return value from awaitRequests() reports if it was interrupted by
+ // abandonRequestWait(). Return to the scheduler if !wait, or
//
// - we were interrupted
// - the run-queue is now non- empty
@@ -59,6 +64,8 @@ awaitCompletedTimeoutsOrIOWin32(Capability *cap, bool wait)
} while (wait
&& getSchedState() == SCHED_RUNNING
&& emptyRunQueue(cap)
+ && !interrupt
);
+ return !interrupt;
}
#endif
=====================================
rts/win32/AwaitEvent.h
=====================================
@@ -2,6 +2,6 @@
#include "BeginPrivate.h"
-void awaitCompletedTimeoutsOrIOWin32(Capability *cap, bool wait);
+bool awaitCompletedTimeoutsOrIOWin32(Capability *cap, bool wait);
#include "EndPrivate.h"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e9acc5068cb01cb7a80be6de143ee6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e9acc5068cb01cb7a80be6de143ee6…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc] Pushed new branch wip/spj-reinstallable-base5
by Simon Peyton Jones (@simonpj) 16 Jul '26
by Simon Peyton Jones (@simonpj) 16 Jul '26
16 Jul '26
Simon Peyton Jones pushed new branch wip/spj-reinstallable-base5 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/spj-reinstallable-base5
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][master] base: Display ExceptionContext in WhileHandling's textual description
by Marge Bot (@marge-bot) 16 Jul '26
by Marge Bot (@marge-bot) 16 Jul '26
16 Jul '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
ede4b17b by Ben Gamari at 2026-07-15T22:59:53-04:00
base: Display ExceptionContext in WhileHandling's textual description
As originally-implemented the implementation for
`WhileHandling(displayExceptionAnnotation)` would display the
`ExceptionContext` of the exception which it carries (as this was the
behavior of `displayException`, in terms of which
`displayExceptionAnnotation` was implemented).
However, in 284ffab3 the definition of `SomeException(displayException)`
was changed to exclude the `ExceptionContext`. This means that
`WhileHandling(displayExceptionAnnotation)` fails to describe the
provenance of the exception which it captures, greatly limiting its
utility.
Return the implementation to its originally-specified behavior by
implementing `WhileHandling(displayExceptionAnnotation)` in terms of
`displayExceptionWithInfo`.
Fixes #27456.
- - - - -
10 changed files:
- + changelog.d/T27456
- libraries/base/changelog.md
- libraries/base/tests/T15349.stderr
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- testsuite/tests/runghc/T7859.stderr-mingw32
Changes:
=====================================
changelog.d/T27456
=====================================
@@ -0,0 +1,8 @@
+section: base
+issues: #27456
+mrs: !16275
+synopsis:
+ Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling`
+description:
+ In the past ``displayException`` (in terms of which ``WhileHandling``\'s ``displayExceptionAnnotation` is implemented) was changed to hide ``ExceptionContext``. This regressed the behavior of ``displayExceptionAnnotation`` from that which was originally specified. Restore the intended behavior of showing the ``ExceptionContext`` of the carried exception.
+
=====================================
libraries/base/changelog.md
=====================================
@@ -33,6 +33,7 @@
* Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
* Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles). ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
* Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
+ * Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling` ([GHC #27456](https://gitlab.haskell.org/ghc/ghc/-/issues/27456))
* Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
* Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
* Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
=====================================
libraries/base/tests/T15349.stderr
=====================================
@@ -1,9 +1,11 @@
-T15349: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
+T15349.exe: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
<<loop>>
-While handling thread blocked indefinitely in an MVar operation
+While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
+ |
+ | thread blocked indefinitely in an MVar operation
HasCallStack backtrace:
- throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Imp.hs:58:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
+ throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\ST\Imp.hs:59:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
=====================================
libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
=====================================
@@ -84,7 +84,7 @@ data WhileHandling = WhileHandling SomeException deriving Show
instance ExceptionAnnotation WhileHandling where
displayExceptionAnnotation (WhileHandling e) =
- "While handling " ++ case lines $ displayException e of
+ "While handling " ++ case lines $ displayExceptionWithInfo e of
[] -> ""
(l1:ls) ->
-- Indent lines forward.
=====================================
libraries/ghc-internal/tests/backtraces/T14532b.stdout
=====================================
@@ -2,7 +2,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall:
Error in Exception Handler
-While handling Main Error
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | Main Error
+ |
+ | My custom Backtraces:
+ | HasCallStack backtrace:
+ | throwIO, called at T14532b.hs:32:6 in main:Main
+ |
My custom Backtraces:
HasCallStack backtrace:
@@ -13,7 +20,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall:
Error in Exception Handler
-While handling Main Error
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | Main Error
+ |
+ | My custom Backtraces:
+ | HasCallStack backtrace:
+ | error, called at T14532b.hs:41:6 in main:Main
+ |
My custom Backtraces:
HasCallStack backtrace:
=====================================
testsuite/tests/codeGen/should_run/cgrun025.stderr
=====================================
@@ -1,4 +1,4 @@
-"cgrun025"
+"cgrun025.exe"
["cgrun025.hs"]
GOT PATH
{-# LANGUAGE ScopedTypeVariables #-}
@@ -27,11 +27,16 @@ main = do
trace "hello, trace" $
catch (getEnv "__WURBLE__" >> return ()) (\ (e :: SomeException) -> error "hello, error")
hello, trace
-cgrun025: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+cgrun025.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
hello, error
-While handling __WURBLE__: getEnv: does not exist (no environment variable)
+While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
+ |
+ | __WURBLE__: getEnv: does not exist (no environment variable)
+ |
+ | HasCallStack backtrace:
+ | ioException, called at libraries\ghc-internal\src\GHC\Internal\System\Environment.hs:204:26 in ghc-internal:GHC.Internal.System.Environment
HasCallStack backtrace:
error, called at cgrun025.hs:25:75 in main:Main
=====================================
testsuite/tests/exceptions/T26759.stderr
=====================================
@@ -1,8 +1,13 @@
-T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+T26759.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
-While handling outer failure
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | outer failure
+ |
+ | HasCallStack backtrace:
+ | throwIO, called at T26759.hs:6:21 in main:Main
HasCallStack backtrace:
throwIO, called at T26759.hs:7:22 in main:Main
=====================================
testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
=====================================
@@ -1,10 +1,12 @@
-<interactive>: Uncaught exception ghc-9.13-inplace:GHC.Utils.Panic.GhcException:
+<interactive>: Uncaught exception ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
IO error: "Abcde" does not exist
-While handling IO error: "Abcde" does not exist
+While handling ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
+ |
+ | IO error: "Abcde" does not exist
HasCallStack backtrace:
- throwIO, called at compiler/GHC/Utils/Error.hs:512:19 in ghc-9.13-inplace:GHC.Utils.Error
+ throwIO, called at compiler\GHC\Utils\Error.hs:499:19 in ghc-10.1-inplace:GHC.Utils.Error
1
=====================================
testsuite/tests/mdo/should_fail/mdofail006.stderr
=====================================
@@ -1,9 +1,11 @@
-mdofail006: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
+mdofail006.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
cyclic evaluation in fixIO
-While handling thread blocked indefinitely in an MVar operation
+While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
+ |
+ | thread blocked indefinitely in an MVar operation
HasCallStack backtrace:
- throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs:167:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
+ throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\Fix.hs:169:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
=====================================
testsuite/tests/runghc/T7859.stderr-mingw32
=====================================
@@ -2,7 +2,12 @@ runghc-9.13.20241015.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Except
defer-type-errors: rawSystem: does not exist (No such file or directory)
-While handling rawSystem: does not exist (No such file or directory)
+While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
+ |
+ | rawSystem: does not exist (No such file or directory)
+ |
+ | HasCallStack backtrace:
+ | ioError, called at libraries/ghc-internal/src/GHC/Internal/Foreign/C/Error.hs:<line>:<column> in <package-id>:GHC.Internal.Foreign.C.Error
HasCallStack backtrace:
ioError, called at libraries\process\System\Process\Common.hs:239:16 in process-1.6.25.0-inplace:System.Process.Common
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ede4b17bdc54c055e44ad95711409c7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ede4b17bdc54c055e44ad95711409c7…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
16 Jul '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
d43a7b7a by Brian McKenna at 2026-07-15T20:10:04+02:00
Strip ticks when desugaring bool guards
The special `considerAccessible` pattern was broken when compiling
with debug info. Compiling with debug info wraps expressions with
`SourceNote` ticks, which broke the internals of the
`desugarBoolGuard` function. Ticks are now ignored within this
function.
Fixes #27360
- - - - -
4 changed files:
- + changelog.d/T27360
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
Changes:
=====================================
changelog.d/T27360
=====================================
@@ -0,0 +1,10 @@
+section: compiler
+issues: #27360
+mrs: !16161
+synopsis:
+ Recognise ``considerAccessible`` under ticks (``-g``, ``-finfo-table-map``, ``-fhpc`` etc)
+description:
+ The pattern-match checker now properly recognises ``considerAccessible`` even
+ when it is surrounded by ticks (e.g. debug info ticks with ``-g``, with
+ ``-finfo-table-map``, etc). This ensures it works as advertised, suppressing
+ redundant pattern-match warnings, even when it occurs under a tick.
=====================================
compiler/GHC/HsToCore/Pmc/Desugar.hs
=====================================
@@ -12,7 +12,8 @@ import GHC.Prelude
import GHC.HsToCore.Pmc.Types
import GHC.HsToCore.Pmc.Utils
-import GHC.Core (Expr(Var,App))
+import GHC.Core (CoreExpr, Expr(Var,App))
+import GHC.Core.Utils (stripTicksTopE)
import GHC.Data.FastString (unpackFS, lengthFS, mkFastStringShortText)
import GHC.Driver.DynFlags
import GHC.Hs
@@ -474,24 +475,28 @@ desugarLocalBinds _binds = return GdEnd
-- | Desugar a pattern guard
-- @pat <- e ==> let x = e; <guards for pat <- x>@
desugarBind :: LPat GhcTc -> LHsExpr GhcTc -> DsM GrdDag
-desugarBind p e = dsLExpr e >>= \case
- Var y
- | Nothing <- isDataConId_maybe y
- -- RHS is a variable, so that will allow us to omit the let
- -> desugarLPat y p
- rhs -> do
- (x, grds) <- desugarLPatV p
- pure (PmLet x rhs `consGrdDag` grds)
+desugarBind p e =
+ dsLExpr_stripTicks e >>= \case
+ Var y
+ | Nothing <- isDataConId_maybe y
+ -- RHS is a variable, so that will allow us to omit the let
+ -> desugarLPat y p
+ rhs -> do
+ (x, grds) <- desugarLPatV p
+ pure (PmLet x rhs `consGrdDag` grds)
-- | Desugar a boolean guard
-- @e ==> let x = e; True <- x@
desugarBoolGuard :: LHsExpr GhcTc -> DsM GrdDag
desugarBoolGuard e
- | isJust (isTrueLHsExpr e) = return GdEnd
+ | isJust (isTrueLHsExpr e) -- NB: looks through ticks
-- The formal thing to do would be to generate (True <- True)
-- but it is trivial to solve so instead we give back an empty
-- GrdDag for efficiency
- | otherwise = dsLExpr e >>= \case
+ = return GdEnd
+
+ | otherwise
+ = dsLExpr_stripTicks e >>= \case
Var y
| Nothing <- isDataConId_maybe y
-- Omit the let by matching on y
@@ -500,6 +505,19 @@ desugarBoolGuard e
x <- mkPmId boolTy
pure $ sequencePmGrds [PmLet x rhs, vanillaConGrd x trueDataCon []]
+-- | Desugar an expression, stripping off top-level ticks from the resulting
+-- Core expression.
+--
+-- This function is used instead of 'dsLExpr' when we are immediately going to
+-- inspect the Core (as we do in e.g. 'desugarBoolGuard' or 'desugarBind') to
+-- make sure we properly look through intervening ticks (fixing #27360).
+--
+-- It's not needed when all we do is stash the resulting 'CoreExpr' into a
+-- 'GrdDag', as the rest of the machinery (such as 'GHC.HsToCore.Pmc.Solver.addCoreCt')
+-- looks through ticks.
+dsLExpr_stripTicks :: LHsExpr GhcTc -> DsM CoreExpr
+dsLExpr_stripTicks e = stripTicksTopE (const True) <$> dsLExpr e
+
{- Note [Field match order for RecCon]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The order for RecCon field patterns actually determines evaluation order of
=====================================
testsuite/tests/pmcheck/should_compile/T27360.hs
=====================================
@@ -0,0 +1,11 @@
+module T27360 where
+
+import GHC.Exts
+
+f :: ()
+f | False, considerAccessible = ()
+ | otherwise = ()
+
+g :: ()
+g | False, True <- considerAccessible = ()
+ | otherwise = ()
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -182,3 +182,4 @@ test('T24845', [], compile, [overlapping_incomplete])
test('T22652', [], compile, [overlapping_incomplete])
test('T22652a', [], compile, [overlapping_incomplete])
test('T24867', [], compile_fail, [overlapping_incomplete])
+test('T27360', normal, compile, [overlapping_incomplete + '-g3'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d43a7b7ad90047f1445c88d796ee7b1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d43a7b7ad90047f1445c88d796ee7b1…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] Potential fix for !HAVE_PREEMPTION case
by Duncan Coutts (@dcoutts) 16 Jul '26
by Duncan Coutts (@dcoutts) 16 Jul '26
16 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC
Commits:
e9acc506 by Duncan Coutts at 2026-07-15T23:58:35+01:00
Potential fix for !HAVE_PREEMPTION case
hopefully fixes the wasm build.
If so, squash into previous patch.
- - - - -
1 changed file:
- rts/posix/Poll.c
Changes:
=====================================
rts/posix/Poll.c
=====================================
@@ -414,13 +414,13 @@ void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
if (!isEmptyClosureTable(&iomgr->aiop_table)) {
- nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
-
#if defined(HAVE_PREEMPTION)
/* the full_poll_table includes interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
struct pollfd *poll_table = iomgr->full_poll_table;
#else
/* the aiop_poll_table does not include interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 0;
struct pollfd *poll_table = iomgr->aiop_poll_table;
#endif
@@ -490,9 +490,11 @@ bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
#if defined(HAVE_PREEMPTION)
/* the full_poll_table includes interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
struct pollfd *poll_table = iomgr->full_poll_table;
#else
/* the aiop_poll_table does not include interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 0;
struct pollfd *poll_table = iomgr->aiop_poll_table;
#endif
@@ -507,7 +509,6 @@ bool awaitCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
#endif
/* Check for I/O readiness, possibly waiting. */
- nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
#if defined(HAVE_DECL_PPOLL) && HAVE_DECL_PPOLL == 1
int res = ppoll(poll_table, nfds, timeout_ns, NULL);
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9acc5068cb01cb7a80be6de143ee63…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9acc5068cb01cb7a80be6de143ee63…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/dcoutts/io-manager-tidy] Potential fix for !HAVE_PREEMPTION case
by Duncan Coutts (@dcoutts) 16 Jul '26
by Duncan Coutts (@dcoutts) 16 Jul '26
16 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/io-manager-tidy at Glasgow Haskell Compiler / GHC
Commits:
1fa73d6e by Duncan Coutts at 2026-07-15T23:55:47+01:00
Potential fix for !HAVE_PREEMPTION case
hopefully fixes the wasm build.
If so, squash into previous patch.
- - - - -
1 changed file:
- rts/posix/Poll.c
Changes:
=====================================
rts/posix/Poll.c
=====================================
@@ -414,13 +414,13 @@ void pollCompletedTimeoutsOrIOPoll(CapIOManager *iomgr)
if (!isEmptyClosureTable(&iomgr->aiop_table)) {
- nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
-
#if defined(HAVE_PREEMPTION)
/* the full_poll_table includes interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 1;
struct pollfd *poll_table = iomgr->full_poll_table;
#else
/* the aiop_poll_table does not include interrupt_fd_r */
+ nfds_t nfds = sizeClosureTable(&iomgr->aiop_table) + 0;
struct pollfd *poll_table = iomgr->aiop_poll_table;
#endif
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1fa73d6e11b86a0634f8eaef95f9bf0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1fa73d6e11b86a0634f8eaef95f9bf0…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
by Marge Bot (@marge-bot) 16 Jul '26
by Marge Bot (@marge-bot) 16 Jul '26
16 Jul '26
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
ef038aae by cydparser at 2026-07-15T04:35:41-04:00
Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
In rts/Capability.c, `capabilities` is an array of pointers, but it was allocated as if it were an
array of Capability's.
- - - - -
d377e83e by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_readTVarIOzh
This patch fixes missing UNTAG on the current value closure read from
StgTVar. UNTAG is a no-op when it's stg_TREC_HEADER_info which is word
aligned; it may be a tagged closure, and reading info table from the
tagged address is an unaligned load which may cause issues on
platforms with strict alignment requirements.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
8ed03842 by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_control0zh_ll
This patch fixes missing UNTAG on the cont closure returned by
captureContinuationAndAbort. In case it's not NULL,
captureContinuationAndAbort returns a tagged StgContinuation closure,
in which case it must be untagged before accessing the
apply_mask_frame field.
In the past it worked out of luck: when apply_mask_frame was NULL then
mask_frame_offset is also 0 so the control flow didn't diverge to a
wrong path. Still, this is horribly wrong and will crash once
StgContinuation struct is refactored and fields are shuffled around.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
5aa7000a by Cheng Shao at 2026-07-15T04:37:08-04:00
compiler: fix redundant AP thunk codegen when not using -ticky-ap-thunk
This patch fixes a double negation confusion in !7525 that results in
some redundant AP thunk code generation when not using
-ticky-ap-thunk. Now, we use `stgToCmmUseStdApThunk` to indicate
whether precomputed AP thunks in the RTS should be used, which
defaults to `True`, unless `-ticky-ap-thunk` is passed.
`-finfo-table-map` now also implies `-ticky-ap-thunk`, since when
doing IPE profiling we want the generated AP thunks to be unique.
Fixes #27502.
-------------------------
Metric Decrease:
T3064
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
d43a7b7a by Brian McKenna at 2026-07-15T20:10:04+02:00
Strip ticks when desugaring bool guards
The special `considerAccessible` pattern was broken when compiling
with debug info. Compiling with debug info wraps expressions with
`SourceNote` ticks, which broke the internals of the
`desugarBoolGuard` function. Ticks are now ignored within this
function.
Fixes #27360
- - - - -
19e4b630 by Ben Gamari at 2026-07-15T18:28:04-04:00
base: Display ExceptionContext in WhileHandling's textual description
As originally-implemented the implementation for
`WhileHandling(displayExceptionAnnotation)` would display the
`ExceptionContext` of the exception which it carries (as this was the
behavior of `displayException`, in terms of which
`displayExceptionAnnotation` was implemented).
However, in 284ffab3 the definition of `SomeException(displayException)`
was changed to exclude the `ExceptionContext`. This means that
`WhileHandling(displayExceptionAnnotation)` fails to describe the
provenance of the exception which it captures, greatly limiting its
utility.
Return the implementation to its originally-specified behavior by
implementing `WhileHandling(displayExceptionAnnotation)` in terms of
`displayExceptionWithInfo`.
Fixes #27456.
- - - - -
22 changed files:
- + changelog.d/T27360
- + changelog.d/T27456
- + changelog.d/fix-use-std-ap-thunk
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Config.hs
- libraries/base/changelog.md
- libraries/base/tests/T15349.stderr
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- rts/Capability.c
- rts/ContinuationOps.cmm
- rts/PrimOps.cmm
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/runghc/T7859.stderr-mingw32
Changes:
=====================================
changelog.d/T27360
=====================================
@@ -0,0 +1,10 @@
+section: compiler
+issues: #27360
+mrs: !16161
+synopsis:
+ Recognise ``considerAccessible`` under ticks (``-g``, ``-finfo-table-map``, ``-fhpc`` etc)
+description:
+ The pattern-match checker now properly recognises ``considerAccessible`` even
+ when it is surrounded by ticks (e.g. debug info ticks with ``-g``, with
+ ``-finfo-table-map``, etc). This ensures it works as advertised, suppressing
+ redundant pattern-match warnings, even when it occurs under a tick.
=====================================
changelog.d/T27456
=====================================
@@ -0,0 +1,8 @@
+section: base
+issues: #27456
+mrs: !16275
+synopsis:
+ Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling`
+description:
+ In the past ``displayException`` (in terms of which ``WhileHandling``\'s ``displayExceptionAnnotation` is implemented) was changed to hide ``ExceptionContext``. This regressed the behavior of ``displayExceptionAnnotation`` from that which was originally specified. Restore the intended behavior of showing the ``ExceptionContext`` of the carried exception.
+
=====================================
changelog.d/fix-use-std-ap-thunk
=====================================
@@ -0,0 +1,4 @@
+section: codegen
+synopsis: Fix redundant AP thunk codegen when not using -ticky-ap-thunk
+issues: #27502
+mrs: !16340
=====================================
compiler/GHC/Driver/Config/StgToCmm.hs
=====================================
@@ -87,7 +87,7 @@ initStgToCmmConfig dflags mod = StgToCmmConfig
, stgToCmmAvx = isAvxEnabled dflags
, stgToCmmAvx2 = isAvx2Enabled dflags
, stgToCmmAvx512f = isAvx512fEnabled dflags
- , stgToCmmTickyAP = gopt Opt_Ticky_AP dflags
+ , stgToCmmUseStdApThunk = not $ gopt Opt_Ticky_AP dflags
-- See Note [Saving foreign call target to local]
, stgToCmmSaveFCallTargetToLocal = any (callerSaves platform) $ activeStgRegs platform
} where profile = targetProfile dflags
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -379,6 +379,7 @@ impliedGFlags = [(Opt_DeferTypeErrors, turnOn, Opt_DeferTypedHoles)
,(Opt_ByteCodeAndObjectCode, turnOn, Opt_WriteByteCode)
,(Opt_InfoTableMap, turnOn, Opt_InfoTableMapWithStack)
,(Opt_InfoTableMap, turnOn, Opt_InfoTableMapWithFallback)
+ ,(Opt_InfoTableMap, turnOn, Opt_Ticky_AP)
] ++ validHoleFitsImpliedGFlags
-- | General flags that are switched on/off when other general flags are switched
=====================================
compiler/GHC/HsToCore/Pmc/Desugar.hs
=====================================
@@ -12,7 +12,8 @@ import GHC.Prelude
import GHC.HsToCore.Pmc.Types
import GHC.HsToCore.Pmc.Utils
-import GHC.Core (Expr(Var,App))
+import GHC.Core (CoreExpr, Expr(Var,App))
+import GHC.Core.Utils (stripTicksTopE)
import GHC.Data.FastString (unpackFS, lengthFS, mkFastStringShortText)
import GHC.Driver.DynFlags
import GHC.Hs
@@ -474,24 +475,28 @@ desugarLocalBinds _binds = return GdEnd
-- | Desugar a pattern guard
-- @pat <- e ==> let x = e; <guards for pat <- x>@
desugarBind :: LPat GhcTc -> LHsExpr GhcTc -> DsM GrdDag
-desugarBind p e = dsLExpr e >>= \case
- Var y
- | Nothing <- isDataConId_maybe y
- -- RHS is a variable, so that will allow us to omit the let
- -> desugarLPat y p
- rhs -> do
- (x, grds) <- desugarLPatV p
- pure (PmLet x rhs `consGrdDag` grds)
+desugarBind p e =
+ dsLExpr_stripTicks e >>= \case
+ Var y
+ | Nothing <- isDataConId_maybe y
+ -- RHS is a variable, so that will allow us to omit the let
+ -> desugarLPat y p
+ rhs -> do
+ (x, grds) <- desugarLPatV p
+ pure (PmLet x rhs `consGrdDag` grds)
-- | Desugar a boolean guard
-- @e ==> let x = e; True <- x@
desugarBoolGuard :: LHsExpr GhcTc -> DsM GrdDag
desugarBoolGuard e
- | isJust (isTrueLHsExpr e) = return GdEnd
+ | isJust (isTrueLHsExpr e) -- NB: looks through ticks
-- The formal thing to do would be to generate (True <- True)
-- but it is trivial to solve so instead we give back an empty
-- GrdDag for efficiency
- | otherwise = dsLExpr e >>= \case
+ = return GdEnd
+
+ | otherwise
+ = dsLExpr_stripTicks e >>= \case
Var y
| Nothing <- isDataConId_maybe y
-- Omit the let by matching on y
@@ -500,6 +505,19 @@ desugarBoolGuard e
x <- mkPmId boolTy
pure $ sequencePmGrds [PmLet x rhs, vanillaConGrd x trueDataCon []]
+-- | Desugar an expression, stripping off top-level ticks from the resulting
+-- Core expression.
+--
+-- This function is used instead of 'dsLExpr' when we are immediately going to
+-- inspect the Core (as we do in e.g. 'desugarBoolGuard' or 'desugarBind') to
+-- make sure we properly look through intervening ticks (fixing #27360).
+--
+-- It's not needed when all we do is stash the resulting 'CoreExpr' into a
+-- 'GrdDag', as the rest of the machinery (such as 'GHC.HsToCore.Pmc.Solver.addCoreCt')
+-- looks through ticks.
+dsLExpr_stripTicks :: LHsExpr GhcTc -> DsM CoreExpr
+dsLExpr_stripTicks e = stripTicksTopE (const True) <$> dsLExpr e
+
{- Note [Field match order for RecCon]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The order for RecCon field patterns actually determines evaluation order of
=====================================
compiler/GHC/StgToCmm/Bind.hs
=====================================
@@ -280,7 +280,7 @@ cgRhs id (StgRhsClosure fvs cc upd_flag args body _typ)
= do
profile <- getProfile
check_tags <- stgToCmmDoTagCheck <$> getStgToCmmConfig
- use_std_ap_thunk <- stgToCmmTickyAP <$> getStgToCmmConfig
+ use_std_ap_thunk <- stgToCmmUseStdApThunk <$> getStgToCmmConfig
mkRhsClosure profile use_std_ap_thunk check_tags id cc (nonVoidIds (dVarSetElems fvs)) upd_flag args body
------------------------------------------------------------------------
=====================================
compiler/GHC/StgToCmm/Config.hs
=====================================
@@ -73,7 +73,7 @@ data StgToCmmConfig = StgToCmmConfig
, stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction
, stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction
, stgToCmmAllowIntWord64X2MinMax :: !Bool -- ^ Allowed to generate min/max instructions for Int64X2/Word64X2
- , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks.
+ , stgToCmmUseStdApThunk :: !Bool -- ^ Use precomputed standard AP thunks in the RTS.
, stgToCmmSaveFCallTargetToLocal :: !Bool -- ^ Save a foreign call target to a Cmm local, see
-- Note [Saving foreign call target to local] for details
------------------------------ SIMD flags ------------------------------------
=====================================
libraries/base/changelog.md
=====================================
@@ -33,6 +33,7 @@
* Export `labelThread` from `Control.Concurrent`.([CLC proposal #376](https://github.com/haskell/core-libraries-committee/issues/376))
* Add a new module `System.IO.OS` with operations for obtaining operating-system handles (file descriptors, Windows handles). ([CLC proposal #369](https://github.com/haskell/core-libraries-committee/issues/369))
* Evaluate backtraces for "error" exceptions at the moment they are thrown. ([CLC proposal #383](https://github.com/haskell/core-libraries-committee/issues/383))
+ * Show `ExceptionContext` in `displayExceptionAnnotation` implementation of `WhileHandling` ([GHC #27456](https://gitlab.haskell.org/ghc/ghc/-/issues/27456))
* Hide implementation details when throwing exceptions in throw and throwSTM. ([CLC proposal #387](https://github.com/haskell/core-libraries-committee/issues/387))
* Change `hIsReadable` and `hIsWritable` such that they always throw a respective exception when encountering a closed or semi-closed handle, not just in the case of a file handle. ([CLC proposal #371](github.com/haskell/core-libraries-committee/issues/371))
* Annotate `onException` continuation with `WhileHandling`. ([CLC Proposal #397](https://github.com/haskell/core-libraries-committee/issues/397))
=====================================
libraries/base/tests/T15349.stderr
=====================================
@@ -1,9 +1,11 @@
-T15349: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
+T15349.exe: Uncaught exception ghc-internal:GHC.Internal.Control.Exception.Base.NonTermination:
<<loop>>
-While handling thread blocked indefinitely in an MVar operation
+While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
+ |
+ | thread blocked indefinitely in an MVar operation
HasCallStack backtrace:
- throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Imp.hs:58:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
+ throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\ST\Imp.hs:59:37 in ghc-internal:GHC.Internal.Control.Monad.ST.Imp
=====================================
libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
=====================================
@@ -84,7 +84,7 @@ data WhileHandling = WhileHandling SomeException deriving Show
instance ExceptionAnnotation WhileHandling where
displayExceptionAnnotation (WhileHandling e) =
- "While handling " ++ case lines $ displayException e of
+ "While handling " ++ case lines $ displayExceptionWithInfo e of
[] -> ""
(l1:ls) ->
-- Indent lines forward.
=====================================
libraries/ghc-internal/tests/backtraces/T14532b.stdout
=====================================
@@ -2,7 +2,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall:
Error in Exception Handler
-While handling Main Error
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | Main Error
+ |
+ | My custom Backtraces:
+ | HasCallStack backtrace:
+ | throwIO, called at T14532b.hs:32:6 in main:Main
+ |
My custom Backtraces:
HasCallStack backtrace:
@@ -13,7 +20,14 @@ ghc-internal:GHC.Internal.Exception.ErrorCall:
Error in Exception Handler
-While handling Main Error
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | Main Error
+ |
+ | My custom Backtraces:
+ | HasCallStack backtrace:
+ | error, called at T14532b.hs:41:6 in main:Main
+ |
My custom Backtraces:
HasCallStack backtrace:
=====================================
rts/Capability.c
=====================================
@@ -413,7 +413,7 @@ void initCapabilities (void)
max_n_capabilities = RtsFlags.ParFlags.nCapabilities;
}
- capabilities = stgMallocBytes(sizeof(Capability) * max_n_capabilities, "initCapabilities");
+ capabilities = stgMallocBytes(sizeof(Capability *) * max_n_capabilities, "initCapabilities");
n_capabilities = 0;
moreCapabilities(0, RtsFlags.ParFlags.nCapabilities);
@@ -422,7 +422,7 @@ void initCapabilities (void)
#else /* !THREADED_RTS */
n_capabilities = 1;
- capabilities = stgMallocBytes(sizeof(Capability), "initCapabilities");
+ capabilities = stgMallocBytes(sizeof(Capability *), "initCapabilities");
capabilities[0] = &MainCapability;
initCapability(&MainCapability, 0);
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -108,7 +108,7 @@ stg_control0zh_ll // explicit stack
}
W_ apply_mask_frame;
- apply_mask_frame = StgContinuation_apply_mask_frame(cont);
+ apply_mask_frame = StgContinuation_apply_mask_frame(UNTAG(cont));
// The stack has been updated, so it’s time to apply the input function,
// passing the captured continuation and a RealWorld token as arguments.
=====================================
rts/PrimOps.cmm
=====================================
@@ -1565,7 +1565,10 @@ stg_readTVarIOzh ( P_ tvar /* :: TVar a */ )
again:
result = %acquire StgTVar_current_value(tvar);
- resultinfo = %INFO_PTR(result);
+ // when result is stg_TREC_HEADER_info, it's word aligned so UNTAG
+ // is no-op; if it's a tagged closure we must UNTAG it to avoid an
+ // unaligned memory access
+ resultinfo = %INFO_PTR(UNTAG(result));
if (resultinfo == stg_TREC_HEADER_info) {
goto again;
}
=====================================
testsuite/tests/codeGen/should_run/cgrun025.stderr
=====================================
@@ -1,4 +1,4 @@
-"cgrun025"
+"cgrun025.exe"
["cgrun025.hs"]
GOT PATH
{-# LANGUAGE ScopedTypeVariables #-}
@@ -27,11 +27,16 @@ main = do
trace "hello, trace" $
catch (getEnv "__WURBLE__" >> return ()) (\ (e :: SomeException) -> error "hello, error")
hello, trace
-cgrun025: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+cgrun025.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
hello, error
-While handling __WURBLE__: getEnv: does not exist (no environment variable)
+While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
+ |
+ | __WURBLE__: getEnv: does not exist (no environment variable)
+ |
+ | HasCallStack backtrace:
+ | ioException, called at libraries\ghc-internal\src\GHC\Internal\System\Environment.hs:204:26 in ghc-internal:GHC.Internal.System.Environment
HasCallStack backtrace:
error, called at cgrun025.hs:25:75 in main:Main
=====================================
testsuite/tests/exceptions/T26759.stderr
=====================================
@@ -1,8 +1,13 @@
-T26759: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
+T26759.exe: Uncaught exception ghc-internal:GHC.Internal.Exception.ErrorCall:
cleanup failure
-While handling outer failure
+While handling ghc-internal:GHC.Internal.Exception.ErrorCall:
+ |
+ | outer failure
+ |
+ | HasCallStack backtrace:
+ | throwIO, called at T26759.hs:6:21 in main:Main
HasCallStack backtrace:
throwIO, called at T26759.hs:7:22 in main:Main
=====================================
testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
=====================================
@@ -1,10 +1,12 @@
-<interactive>: Uncaught exception ghc-9.13-inplace:GHC.Utils.Panic.GhcException:
+<interactive>: Uncaught exception ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
IO error: "Abcde" does not exist
-While handling IO error: "Abcde" does not exist
+While handling ghc-10.1-inplace:GHC.Utils.Panic.GhcException:
+ |
+ | IO error: "Abcde" does not exist
HasCallStack backtrace:
- throwIO, called at compiler/GHC/Utils/Error.hs:512:19 in ghc-9.13-inplace:GHC.Utils.Error
+ throwIO, called at compiler\GHC\Utils\Error.hs:499:19 in ghc-10.1-inplace:GHC.Utils.Error
1
=====================================
testsuite/tests/mdo/should_fail/mdofail006.stderr
=====================================
@@ -1,9 +1,11 @@
-mdofail006: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
+mdofail006.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Exception.FixIOException:
cyclic evaluation in fixIO
-While handling thread blocked indefinitely in an MVar operation
+While handling ghc-internal:GHC.Internal.IO.Exception.BlockedIndefinitelyOnMVar:
+ |
+ | thread blocked indefinitely in an MVar operation
HasCallStack backtrace:
- throwIO, called at libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs:167:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
+ throwIO, called at libraries\ghc-internal\src\GHC\Internal\Control\Monad\Fix.hs:169:37 in ghc-internal:GHC.Internal.Control.Monad.Fix
=====================================
testsuite/tests/pmcheck/should_compile/T27360.hs
=====================================
@@ -0,0 +1,11 @@
+module T27360 where
+
+import GHC.Exts
+
+f :: ()
+f | False, considerAccessible = ()
+ | otherwise = ()
+
+g :: ()
+g | False, True <- considerAccessible = ()
+ | otherwise = ()
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -182,3 +182,4 @@ test('T24845', [], compile, [overlapping_incomplete])
test('T22652', [], compile, [overlapping_incomplete])
test('T22652a', [], compile, [overlapping_incomplete])
test('T24867', [], compile_fail, [overlapping_incomplete])
+test('T27360', normal, compile, [overlapping_incomplete + '-g3'])
=====================================
testsuite/tests/runghc/T7859.stderr-mingw32
=====================================
@@ -2,7 +2,12 @@ runghc-9.13.20241015.exe: Uncaught exception ghc-internal:GHC.Internal.IO.Except
defer-type-errors: rawSystem: does not exist (No such file or directory)
-While handling rawSystem: does not exist (No such file or directory)
+While handling ghc-internal:GHC.Internal.IO.Exception.IOException:
+ |
+ | rawSystem: does not exist (No such file or directory)
+ |
+ | HasCallStack backtrace:
+ | ioError, called at libraries/ghc-internal/src/GHC/Internal/Foreign/C/Error.hs:<line>:<column> in <package-id>:GHC.Internal.Foreign.C.Error
HasCallStack backtrace:
ioError, called at libraries\process\System\Process\Common.hs:239:16 in process-1.6.25.0-inplace:System.Process.Common
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a9f1ff9164358d29de72a5b9f8af5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a9f1ff9164358d29de72a5b9f8af5…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/az/exactprint-annotation-rationalisation] 25 commits: hadrian: fix HLS support
by Alan Zimmerman (@alanz) 16 Jul '26
by Alan Zimmerman (@alanz) 16 Jul '26
16 Jul '26
Alan Zimmerman pushed to branch wip/az/exactprint-annotation-rationalisation at Glasgow Haskell Compiler / GHC
Commits:
ed261a7e by Cheng Shao at 2026-07-14T17:59:38-04:00
hadrian: fix HLS support
This patch fixes hadrian's HLS support so one can rely on HLS when
working on the hadrian codebase. Fixes #27480.
Not building/linking shared libraries for hadrian is a severely
premature optimization; this top-level setting in `cabal.project` only
affects home packages while the dependencies in the cabal store are
built with vanilla/dynamic anyway, and even adding dynamic builds to
home packages would not be costly due to cabal's usage of
`-dynamic-too`.
- - - - -
eee8ec5b by Cheng Shao at 2026-07-14T18:00:20-04:00
compiler: fix miscompiled %load_relaxed, add missing %store_relaxed
This patch fixes the %load_relaxed cmm primop compilation logic to
correctly use relaxed memory ordering, and adds the missing
%store_relaxed primop. Parsing logic of %load/%store with explicit
ordering is covered in the AtomicFetch test case. Fixes #27483.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
1718230f by Alan Zimmerman at 2026-07-14T18:01:06-04:00
EPA: Keep binds and sigs together in HsValBindsLR
We combine them into a single list for GhcPs, wrapped in the
ValBind data type, which is the bind equivalent of ValD, having
constructors for binds and sigs.
This simplifies exact print processing, especially when using it to
update the contents of local binds, as we no longer need AnnSortKey
BindTag
- - - - -
6bd1ad2a by Andreas Klebinger at 2026-07-14T18:01:49-04:00
Bump nofib submodule to account for MonoLocalBinds.
New versions of GHC enable MonoLocalBinds by default.
This breaks some of the benchmarks. I've fixed this and
this bump pulls in that fix.
- - - - -
7eb0f1c9 by Cheng Shao at 2026-07-14T18:02:31-04:00
testsuite: fix bytecodeIPE test under +ipe flavours
This patch fixes the bytecodeIPE test under +ipe flavours. It used to
fail under +ipe because the RTS is built with IPE info, then
stg_AP_info in RTS carries IPE info, so whereFrom wouldn't return
Nothing. Now the test checks IPE info of a datacon in the ghci-loaded
module which is not affected by whether the RTS is built with IPE info
or not. Fixes #27498.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ef038aae by cydparser at 2026-07-15T04:35:41-04:00
Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
In rts/Capability.c, `capabilities` is an array of pointers, but it was allocated as if it were an
array of Capability's.
- - - - -
d377e83e by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_readTVarIOzh
This patch fixes missing UNTAG on the current value closure read from
StgTVar. UNTAG is a no-op when it's stg_TREC_HEADER_info which is word
aligned; it may be a tagged closure, and reading info table from the
tagged address is an unaligned load which may cause issues on
platforms with strict alignment requirements.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
8ed03842 by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_control0zh_ll
This patch fixes missing UNTAG on the cont closure returned by
captureContinuationAndAbort. In case it's not NULL,
captureContinuationAndAbort returns a tagged StgContinuation closure,
in which case it must be untagged before accessing the
apply_mask_frame field.
In the past it worked out of luck: when apply_mask_frame was NULL then
mask_frame_offset is also 0 so the control flow didn't diverge to a
wrong path. Still, this is horribly wrong and will crash once
StgContinuation struct is refactored and fields are shuffled around.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
5aa7000a by Cheng Shao at 2026-07-15T04:37:08-04:00
compiler: fix redundant AP thunk codegen when not using -ticky-ap-thunk
This patch fixes a double negation confusion in !7525 that results in
some redundant AP thunk code generation when not using
-ticky-ap-thunk. Now, we use `stgToCmmUseStdApThunk` to indicate
whether precomputed AP thunks in the RTS should be used, which
defaults to `True`, unless `-ticky-ap-thunk` is passed.
`-finfo-table-map` now also implies `-ticky-ap-thunk`, since when
doing IPE profiling we want the generated AP thunks to be unique.
Fixes #27502.
-------------------------
Metric Decrease:
T3064
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
467d0ceb by Alan Zimmerman at 2026-07-15T22:35:01+01:00
Keep decls together in ClassDecl
- - - - -
cada6f37 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: ClsInstDecl as list in GhcPs
- - - - -
b46e6c0c by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedP from OverlapMode
- - - - -
3b628fb1 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedP from CType
- - - - -
f08a71f1 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedP, last use in WarningTxt
- - - - -
83b8e2b9 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedE from WarningCategory
- - - - -
bae80ae7 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocateE from XCImport and XCExport
- - - - -
d567cc4f by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedE from HsRecFields dot
- - - - -
df6c8d24 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedE completely, last usage for pats
- - - - -
6c60a0e6 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove AnnList (EpToken "where") usages
This is moving toward removing the parameter from AnnList completely
- - - - -
8a6ee358 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA remove AnnList (EpToken "rec") usages
- - - - -
62201dcf by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove last parameterised AnnList usage (EpaLocation)
Also remove the parameter
- - - - -
02dffd1f by Alan Zimmerman at 2026-07-15T22:38:50+01:00
TTG: Add extension points to BooleanFormula
They are currently unused, but will be used for exact print annotations next
- - - - -
02bca385 by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: Remove LocatedBC / SrcSpanBF
- - - - -
9991537d by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPA: remove unused addTrailingAnnToL. Squash appropriately
- - - - -
72da7aff by Alan Zimmerman at 2026-07-15T22:38:50+01:00
EPS: Remove NoEpTok/NoEpUniTok, using an unhelpful SrcSpan instead
Also introduce helper functions noEpTok and noEpUniTok to serve
as simple replacements in code inserting an token annotation without
location information.
- - - - -
101 changed files:
- + changelog.d/fix-cmm-atomic-load-store
- + changelog.d/fix-use-std-ap-thunk
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Core/Class.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/BooleanFormula.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Decls/Overlap.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Warnings.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Class.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/BooleanFormula.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- ghc/GHCi/UI.hs
- hadrian/cabal.project
- nofib
- rts/Capability.c
- rts/ContinuationOps.cmm
- rts/PrimOps.cmm
- testsuite/tests/cmm/should_run/AtomicFetch.hs
- testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm
- testsuite/tests/ghc-api/T25121_status.stdout
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/ghci/scripts/bytecodeIPE.hs
- testsuite/tests/haddock/haddock_examples/haddock.Test.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/module/mod185.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15279.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.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/9d7f690dc66c520237aef819fc11bb…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d7f690dc66c520237aef819fc11bb…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
16 Jul '26
Simon Jakobi pushed new branch wip/sjakobi/T27507 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/T27507
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0