This is the twenty-fifth edition of our GHC activities report, which describes the work Well-Typed are doing on GHC, Cabal, HLS and other parts of the core Haskell toolchain. The current edition covers roughly the months of September to November 2024. You can find the previous editions collected under the ghc-activities-report tag.
Sponsorship
We are delighted to offer Haskell Ecosystem Support Packages to provide commercial users with access to Well-Typed’s experts, while investing in the Haskell community and its technical ecosystem. Clients will both fund the work described in this report and support the Haskell Foundation. If your company is using Haskell, read more about our offer, or get in touch with us today, so we can help you get the most out of the toolchain. We need more funding to continue our essential maintenance work!
Many thanks to our existing sponsors who make this work possible: Anduril and Juspay. In addition, we are grateful to Mercury for funding specific work on improved performance for developer tools on large codebases.
Team
The GHC team at Well-Typed currently consists of Andreas Klebinger, Ben Gamari, Matthew Pickering, Rodrigo Mesquita, Sam Derbyshire and Zubin Duggal. Adam Gundry acts as Secretary to the GHC Steering Committee. Cabal maintenance is undertaken by Mikolaj Konarski, and HLS maintenance by Hannes Siebenhandl and Zubin Duggal. In addition, many others within Well-Typed are contributing to GHC more occasionally.
GHC Releases
Ben released GHC 9.8.3 and has been working towards the upcoming release of GHC 9.8.4, which will make some packaging improvements and update libraries distributed with GHC.
Zubin has been preparing for the release of GHC 9.12 series by releasing 9.12-alpha1, 9.12-alpha2 and 9.12-alpha3. The release candidate and final release are expected soon.
There is ongoing discussion regarding potential improvements to the release process, in particular more predictable release schedules, changes to GHC’s boot library upgrade policy, and plans to improve coordination with GHCup.
GHC release status is communicated via the ghc-releases mailing list.
Cabal
Cabal-3.14.0.0
was released in September, adding initial support for the new
hooks build-type we implemented to replace custom setup scripts, as part of our
work for the Sovereign Tech Fund on Cabal long-term
maintainability.
Corresponding new versions of cabal-install
and the release of the
Cabal-hooks
library are due soon, at which point it will become easier for
users to explore replacing their custom setup scripts with the hooks feature.
Related to this effort:
Sam amended the
Cabal-hooks
version to match theCabal
library version (#10579).Rodrigo made progress on Sam’s work to simplify the way
cabal-install
uses theCabal
library to build packages. This will make the code easier to work with in the future, and should improve build performance (#9871).Rodrigo made
cabal-install
invokegit clone
concurrently when downloading fromgit
repositories forsource-repository-package
stanzas orcabal get
, and switched it to use shallow clones by default (#10254). This speeds up the cloning step significantly.Rodrigo’s work on private dependencies (#9743) is slowly making progress, thanks to recent work by Kristen Kozak.
Rodrigo and Matthew fixed various minor Cabal bugs, improved documentation and future-proofed against future core libraries changes (#10311, #10404, #10415 and #10433).
HLS
- Hannes finished off and merged support for a new “jump to instance definition” feature in HLS (#4392), which will make it easier for users to understand which typeclass instance is in use in a particular expression.
GHC
Exception backtraces
Rodrigo worked on improving several facets of the exception backtraces story:
Improved the rendering of uncaught exceptions so the default output is much clearer and easier to understand (CLC proposal #285, !13301). This included reformatting the output, reducing duplication, avoiding exposing internal implementation details in the call stacks, and reducing duplication.
Changed functions such as
catch
to propagate the original cause if another exception is subsequently thrown (CLC proposal #202.Landed a patch by Ben so that the
HasCallStack
-based backtrace for anerror
call is more informative (!12620, #24807).
Overall, exception backtraces will be much more useful in GHC 9.12 and later, making it easier to debug Haskell applications.
Frontend
Andreas added new primops,
is[Mutable]ByteArrayWeaklyPinned#
, which allow checking whether a bytearray can be moved by the RTS, as per CLC proposal #283.Sam fixed a GHC panic involving out-of scope pattern synonyms (#25056, !13092).
Sam augmented the
-fdiagnostics-as-json
output to include the reason an error or warning was emitted (!13577, #25403).Matthew and Rodrigo deprecated the unused
-Wcompat-unqualified-imports
warning (!12755, #24904, !13349, #25330).Ben improved the parsing and parser errors for sizes in GHC RTS flags (!12384, #20201).
Matthew fixed a bug in the interaction of
-working-dir
and foreign files (!13196, #25150).Zubin bumped the Haddock binary interface version to 46, to improve errors when there are mismatched interface files (!13342).
SIMD in the NCG backend
Sam and Andreas teamed up to finish the mega-MR adding SIMD support to GHC’s X86 native code generator backend (!12860, and see our previous report for more background). This also fixed critical correctness bugs that affected SIMD support in the existing LLVM backend, such as #25062 and #25169.
Sam followed this up with user’s guide documentation for the feature (!13880) and a couple of additional fixes for bugs that have been reported since (!13561, !13612).
LLVM backend
Sam implemented several fixes relating to the LLVM backend, in collaboration with GHC contributor
@aratamizuki
:Matthew bumped the LLVM upper bound to allow GHC to use LLVM 19 (!13311, #25295).
RISC-V backend
Andreas added support for floating-point min/max operations in the RISC-V NCG backend (!13325)
Matthew fixed some issues to do with the fact that the RISC-V backend does not yet support SIMD vectors (!13327, #25314, #13327).
Object code determinism
Rodrigo merged !12680, which goes 95% of the way towards ensuring GHC produces fully deterministic object code (#12935).
Rodrigo made the unique generation used by the LLVM backend deterministic (!13307, #25274), thus making GHC 96% object-code deterministic.
Rodrigo ensured that re-exports did not spoil determinism of interface files in !13316 (#25304).
Compiler performance
Matthew, Rodrigo and Adam published a proposal for Explicit Level Imports. The proposed language feature will allow users of Template Haskell to communicate more precise dependencies for quotes and splices, which can unlock significant compile-time performance improvements and is a step towards better cross-compilation support.
Rodrigo improved the performance of module reachability queries (!13593), which can significantly reduce compile times and memory usage for projects with very large numbers of modules.
Andreas introduced a new flag,
-fmax-forced-spec-args
, to control the maximum size of specialised functions introduced when using the SPEC keyword (!13184, #25197). This avoids a potential compile-time performance cliff caused by specialisations with excessively large numbers of arguments.Matthew greatly reduced the memory footprint of linking with the Javascript backend by making some parts of the compiler more lazy (!13346).
Zubin’s proposal to address libc compatibility issues when using semaphores for build parallelism has been making progress through the proposal process.
Runtime system
Ben fixed the encoding of breakpoint instructions in the RTS to account for a recent addition of support for inlining breakpoints (!13423, #25374).
Ben tightened up the documentation and invariants in the bytecode interpreter (!13565).
Ben allowed GNU-style non-executable stack notes to be used on FreeBSD (!13587, #25475).
Ben fixed an incorrect EINTR check in the timerfd ticker (!13588, #25477).
Zubin ensured that any new cost centres added by freshly-loaded objects are correctly included in the eventlog (!13114, #24148).
Ben increased the
gen_workspace
alignment in the RTS from 64 bytes to 128 bytes in order to prevent false sharing on Apple’s ARMv8 implementation, which uses a cache-line size of 128 bytes (!13594, #25459).Ben removed some incorrect platform-dependent pointer casts in the RTS (!13597).
Zubin fixed a segfault when using the non-moving GC with profiling (!13271, #25232).
Ben fixed a stack overrun error with i386 adjustors (!13599, #25485).
Ben introduced a convenience
printIPE
debugging function for printing info-provenance table entries (!13614).Andreas fixed a crash that could happen if an exception and the compacting GC aligned in specific ways (#24791, !13640).
Documentation
Ben fleshed out missing documentation of the eventlog format in the user’s guide (!13398, #25296).
Andreas clarified the documentation of
fexpose-overloaded-unfoldings
(!13286, #24844).Ben documented that GHC coalesces adjacent sub-word size fields of data constructors (!13397).
Ben improved the documentation of equality constraints to mention which language extensions are required to use them (!12395, #24127).
Codebase improvements
Ben fixed a few warnings in the runtime system, including some FreeBSD specific warnings (!13586).
Ben fixed (!13394, #25362) some incomplete pattern matches in
GHC.Internal.IO.Windows.Handle
that came to light in !13308, a refactor of the desugarer. Andreas also chipped in, squashing some warnings inghc-heap
(!13510).Matthew refactored the
partitionByWorkerSize
function to avoid spurious pattern-match warning bugs when compiling with-g3
(!13359, #25338).Matthew removed the
hs-boot
file forLanguage.Haskell.Syntax.ImpExp
and introduced one forGHC.Hs.Doc
, which better reflects the intended modular hierarchy of the modules (!13406).
GHC API
We are pleased to see that the Haskell Foundation and Tweag are resuming efforts aimed at defining a stable API for GHC.
Ben added
lookupTHName
, a more convenient way to look up a name in a GHC plugin that re-uses Template Haskell lookup functions (!12432, #24741).Zubin made sure that the
driverPlugin
is correctly run for static plugins (!13199, #25217).
Libraries
Andreas allowed unknown FD device types in the
setNonBlockingMode
function (!13204, #25199), as per CLC proposal #282. This fixes a regression in thehinotify
package on GHC 9.10.Andreas made sure that all primops are re-exported in the
ghc-experimental
package via the moduleGHC.PrimOps
(!13245), and changed the versioning scheme ofghc-experimental
to follow GHC versions (!13344, #25289).Ben fixed a performance regression in
throw
by judicious insertion ofnoinline
(!13275, #25066), as discussed in CLC proposal #290.Matthew unwired the
base
package to pave the way for a reinstallablebase
package (!13200).Matthew upgraded GHC’s Unicode support to Unicode 16 (!13514).
Rodrigo removed BCO primops from the
GHC.Exts
re-export, as per CLC proposal #212 (!13211, #25110).
Profiling
Matthew enabled late cost-centres by default when the libraries distributed with GHC are built for profiling (!10930, #21732). This greatly improves the resolution of cost centre stacks when profiling.
Andreas fixed a bug in which profiling could affect program behaviour by allowing profiling ticks to move past
unsafeCoerce#
in Core (!13413, #25212).
Build system
Ben fixed the configure script incorrectly reporting that
subsections-via-symbols
is enabled on AArch64/Darwin (!12834, #24962).The first alpha pre-release of 9.12 incorrectly had a version number of 9.12.20241014 instead of 9.12.0.20241014, which broke the expected lexicographic ordering of GHC releases. Ben added a check for the validity of a release GHC version number to prevent such issues in the future (!13456).
Matthew allowed GHC to build with
happy-2.0.2
(!13318, #25276), and Ben withhappy-2.1.2
(!13532, #25438).Andreas made the Hadrian progress messages including the working directory to allow quickly distinguishing builds when multiple builds are in progress (!13353, #25335).
Ben allowed Haddock options to be passed as Hadrian key-value settings (!11006).
Testsuite
Ben improved the reporting of certain errors in the testsuite (!13332).
Ben ensured performance metrics are collected even when there are untracked files (!13579, #25471).
Ben ensured performance metrics are properly pushed for WebAssembly jobs (!13312).
Zubin made several improvements to the testsuite, in particular regarding normalisation of tests and fixing a Haddock bug involving files with the same modification time (!13418, !13522).
CI
Matthew added a i386 validation job that can be triggered by adding the
i386
label on an MR (!13352).Matthew added a mechanism for only triggering certain individual jobs in CI by using the
ONLY_JOBS
variable (!13350).Matthew fixed some issues of variable inheritance in the
ghcup-metadata
testing job (!13306).Matthew added Ubuntu 22.04 jobs to CI (!13335).