Skip to main content

GHC DevX Update 2023-01-12

· 3 min read

Starting in 2023 we–the IOG GHC DevX team–are going to provide biweekly updates about our work. This is the first edition.

JS backend

JS backend in the browser tutorial

We are working on a draft of a JS backend tutorial about using it to build a simple web application:

Publication is expected next week.

Cabal support for js-sources

Sylvain made a patch to add cabal support for the js-sources stanza when GHC is used as a compiler (and not only when GHCJS is used as a compiler):

It’s missing tests and then it should be ready to be merged.

JS backend CI

Jeff worked on adding a proper CI job that runs the full testsuite with the JS backend. Cf ticket #22128 and merge request !9552.

He had to fix some unexpected test passes (!) with the JS backend due to an imprecise req_smp predicate used by the testsuite. More details on #22630 and !9568.

JS backend: Template Haskell

Luite and Sylvain started implementing support for Template Haskell (TH) with the JS backend.

Sylvain reimplemented support for running an adapted version of the THRunner.js script from GHCJS. He also refactored the JS linker and implemented incremental linking.

The next step is to link and to run an instance of the external interpreter code that implements the Template Haskell protocol (execution of the Q monad) adapted to run in JavaScript. GHCJS used to have its own duplicated code for this but for maintenance concerns it’s much better to reuse the external interpreter code.


GHCi: sized primitive types (Word8#, etc.)

Luite implemented support for sized primitive types in GHCi. Cf !8822.

GHCi: “prim” calling convention

Luite implemented support for the “prim” calling convention in GHCi. Cf !9026

Compiler performance


Each of these improves allocations between 0.2 - 0.7% depending on the input (improvements by a thousand cuts):

  • GHC.Foreign improved Strictness: An Attempt to remove lazy IO and SAT an argument that is only used for a debug message. Got a review from Andreas. Want to try to 2 more improvements then ready to merge. !9644

  • InfoTableProv: ShortText → ShortByteString: Post review from Ben I made some improvements that preserved type safety and still recovered most of the performance improvements. Ready to merge !9637

  • GHC.Unit.State: swapped use of Data.Map for GHC.Unique.UniqMap and expanded UniqMap API. Results in progress (need to patch Haddock) and still experimental. The idea here is to use a data structure that no longer needs to balance on insertions because Unit.State performs a lot of merges on these maps.

  • GHC.Utils.Binary.foldGet’ removed lazy IO and lazy accumulator: merged !9538


  • Stricter break: we noticed in a ticky profile that GHC.List.break allocates 3 thunks and 1 datacon per list element returned the first part of the list. If this list is fully evaluated later, we can allocate only 1 datacon per list element instead. Preliminary results bootstrapping GHC with this change look very promising.

  • FastMutInt (Binary): Josh started reviving Sylvain’s MR !7246 about bundling more than one Int# in a FastMutInt for performance. He tried to make a proof of concept generalisation of 2-FastMutInt into n-FastMutInts (using GHC type level Natural). The types don’t really recurse in a convenient way (Int -> (… -> IO ())) so it would probably introduce more complexity than the problem is worth. Now, he’s just implementing the original patch with the fixes and documentation.