This is the thirteenth edition of our GHC activities report, which describes the work on GHC and related projects that we are doing at Well-Typed. The current edition covers roughly the months of June and July 2022. You can find the previous editions collected under the ghc-activities-report tag.

A bit of background: One aspect of our work at Well-Typed is to support GHC and the Haskell core infrastructure. Several companies, including IOHK and GitHub via the Haskell Foundation, are providing us with funding to do this work. We are also working with Hasura on better debugging tools and improvements to HLS. We are very grateful on behalf of the whole Haskell community for the support these companies provide.

If you are interested in also contributing funding to ensure we can continue or even scale up this kind of work, please get in touch.

Of course, GHC is a large community effort, and Well-Typed’s contributions are just a small part of this. This report does not aim to give an exhaustive picture of all GHC work that is ongoing, and there are many fantastic features currently being worked on that are omitted here simply because none of us are currently involved in them in any way. Furthermore, the aspects we do mention are still the work of many people. In many cases, we have just been helping with the last few steps of integration. We are immensely grateful to everyone contributing to GHC!

Team

The current GHC team consists of Ben Gamari, Andreas Klebinger, Matthew Pickering, Zubin Duggal and Sam Derbyshire.

Many others within Well-Typed, including Adam Gundry, Alfredo Di Napoli, Alp Mestanogullari, Douglas Wilson and Oleg Grenrus, are contributing to GHC more occasionally.

Releases

  • Zubin released GHC 9.2.4 which contains a backport of the DeepSubsumption language extension.

  • Ben, Matt and Doug have been finalising GHC 9.4.1, which is due to be released at the beginning of August.

GHCi

  • Matt extended the support for multiple components in GHCi. In particular, enough operations are now supported to be able to use ghcid with multiple components. (!8584, !8548)

  • Zubin fixed Ctrl-C behaving very poorly in GHCi on Windows. This could cause broken terminals, even after exiting GHCi. (#21889)

Driver

  • Matt fixed a space leak in --make mode, greatly reducing the memory usage for projects which have module loops (!8710). This patch has been observed to reduce the allocation peak in --make mode when compiling packages which contain many hs-boot files – such as GHC or Agda – by around 25-30%.

  • Matt fixed an issue where dependencies were calculated incorrectly when using multiple home units with hs-boot files (!8573). This led to compiler crashes for projects with hs-boot files when used with multiple home units.

  • Matt fixed a bug where certain build steps were added into the build graph when they would never be executed. This avoids the last compilation build step in --make mode being displayed as, e.g., [7 of 8] instead of [8 of 8] (!8665).

Compiler performance

  • Andreas optimized the rule matching code in !8608, which resulted in a ~2% speedup when compiling the Cabal library.
  • Andreas investigated a compile time regression in #21839. This unearthed some potential improvements in the binary library as well as potential improvements for inlining heuristics described in #21938.
  • Zubin and Matt discovered and fixed a space leak affecting HLS that manifested when using the extendMG function from the GHC API, and also backported a fix to GHC 9.2 (#21816).

Typechecker

  • Sam improved the disambiguation mechanism for record updates, fixing #21443. Now, a record update such as r { fld1 = v1, fld2 = v2, fld3 = v3 } will typecheck when there is a single constructor which has all of the fields fld1, fld2 and fld3. (Beforehand, we would insist there be only one datatype with all those fields, without looking at constructors.)

  • Matt fixed a subtle issue to do with different varieties of built-in syntax which meant re-exports of FUN,TYPE,One and Many didn’t work properly (#21752, #20695, #18302).

  • Matt spent quite a bit of time helping Simon Peyton Jones with the DeepSubsumption patch by testing various iterations of the patch on the head.hackage package set. This uncovered quite a few regressions which we managed to fix before merging the feature.

Error messages

  • Matt added a flag -fsuppress-error-contexts which makes error messages less verbose (!8563, #21722).

  • Sam fixed #21662, a bug in the treatment of dictionaries in the pattern match checker. The pattern-match checker now does a better job at emitting warnings in the presence of class dictionaries.

Code generation

  • Ben debugged #21708, identifying it as a soundness issue in the implementation of the keepAlive# primop where the Cmm pipeline could in very particular cases inappropriately drop the touch# to which keepAlive# was desugared (similar to the issue seen in #14346, the issue which keepAlive# was intended to fix). As a stop-gap measure, he implemented a naive fix, making keepAlive# an out-of-line primop. He then began work on #16098, an optimisation which will allow GHC to eliminate much of the overhead incurred by this approach. Whilst difficult to trigger, the issue manifested when compiling xmonad with GHC 9.2.3 so it was critical to fix promptly in the GHC 9.2.4 release.

  • While working on #21708, Ben identified a soundness issue in GHC’s current usage runtime-representationally polymorphic primops and started thinking about how this might be mitigated (#21868).

  • Ben debugged and fixed a bug in the AArch64/Darwin NCG which lead to incorrect behavior in the presence of foreign calls to functions expecting narrow, signed arguments (#21773, #20735).

  • Ben continued work on !3012, a change introducing a standard thunk for unpacking of string literals. This significantly reduces both compilation time and code size for programs containing many strings.

Primops

  • Sam changed the desugaring of the withDict# function to avoid GHC’s typeclass specialiser from performing incorrect, semantic-changing program transformations (#21575). In future releases withDict# is intended to be a compiler primitive which replaces assumptions libraries such as reflection use about the internal representation of type class dictionaries.

  • Ben worked on finishing a rework of GHC’s treatment of undersaturated primops, simplifying the code generator’s treatment of primops and reducing the size of the compiler’s symbol table (#20155).

Core-to-Core pipeline

  • Andreas fixed a bug in the worker-wrapper implementation, which caused certain programs compiled with -fmax-worker-args=20 to panic (#21472).

  • Andreas fixed #21770 which caused a debugged build of GHC to panic under certain circumstances.

Runtime system

  • Ben fixed a number of issues in the RTS linker. These included the introduction of proper support for global constructors and destructors, fixing the resolution of DSO handles on Darwin, and fixing unregistration of unwind information on Windows. Together, this work fixed a number of issues in statically-linked configurations as well as enabled the RTS linker to load libc++ on Windows (#21618).

  • Ben debugged and fixed a bug in GHC 9.4’s new adjustor-pool implementation which lead to double-allocation of adjustor slots and consequently crashes (#21768).

  • Ben debugged and fixed a subtle bug in the non-moving garbage collector’s scavenging logic which could result in undefined behavior (#21885).

  • Ben debugged and fixed a bug in the biographical profiler which resulted in program crashes in long-running programs (#21880).

Profiling

  • Andreas fixed #21233 by restoring the textual ticky output for ticky profiling.

  • Andreas improved how the (new in 9.4) profiling mode -fprof-late interacts with the creation of unfoldings, in order to avoid interfering with Core optimizations. This means that profiles produced with late cost centres will be more faithful to their original (optimised, unprofiled) programs (#21249).

Libraries

  • Ben finished work on a set of interfaces allowing users to introspect on a program’s threads, their labels and statuses (!2816). In the process he came up with a few ideas for extending this infrastructure to enable better diagnostics of looping evaluation and multi-threaded deadlocks (#21877).

  • Zubin discovered and implemented a workaround for a bug in the GHC linker affecting programs which use text-2.0 in Template Haskell splices with a statically linked compiler (#21787, text!453).

  • Doug fixed a long latent concurrency bug in GHC.Event.Thread.closeFdWith (#21651).

  • Doug fixed a bug in forkOn, where the wrong thread was context-switched (#21824).

  • Ben worked-around process#247, a spurious failure of process’s posix_spawn backend caused by an infelicity in Darwin’s implementation.

Packaging

  • Matt added a number of workarounds to fix latent issues in the soon-to-be retired Make build system (for example !8751, !8731).

  • Matt added support to the build system to allow a specific base-url to be used when generating haddock documentation so the result can be uploaded to hackage (!8542).

  • Ben fixed a number of issues noticed when using Hadrian-built binary distributions on Darwin (#21506, #21570).

Hadrian

  • Sam added a Hadrian key-value setting which allows flags to be passed when running Hsc2Hs.

  • Matt added an experimental mode to hadrian which uses GHC’s --make mode rather than -c in order to compile libraries (!8640). In the future, this should improve build times for GHC developers, as using --make mode is faster than using -c.

  • Matt added a new ./hadrian/ghci-multi target which loads the GHC project into a single GHCi multi-repl using the new multiple home units feature.

Infrastructure

  • Ben began introducing CI infrastructure to validate building of GHC in a cross-compiled configuration (#11958).

  • Andreas did a maintenance pass over open merge requests to nofib.