Software development

We contribute to the development of the main Haskell compiler: GHC

We have already fixed several bugs and added several features as you can see in the following list. If you need specific developments using GHC or to improve it, don’t hesitate to contact us.

Our contributions

2019-02 – Speed up compilation of large Strings literals

GHC creates assembly source files that are assembled by an external program (GNU as, etc.). Dumping very large string literals into the assembly source file isn’t efficient so we implemented an alternative method that uses .incbin assembler directive.

Ticket #16190

2019-02 – Represent Cmm literal strings as ByteString

GHC uses ByteString to represent literals in Haskell, Core and Stg syntaxes but covnerted them into [Word8]] in Cmm syntax. Using ByteString for Cmm string literals improves compiler performance.

Ticket #16198

2019-01 – Template Haskell support for Assembly files

Template Haskell can be used to insert files into the compilation chain. Until now it only supported C, Objective C, C++, Objective C++ and objects (.o). We added the support for assembly files (.s).

Ticket #16180

2018-06 – Add support for built-in Natural literals into Core

We have added support for Natural literals into Core with some constant folding rules. Type-level naturals desugar into Natural and benefit from this.

Ticket #14170

2018-04 – Enhanced constant folding

GHC only supported basic constant folding (lit op lit, expr op 0, etc.). We used laws of +/-/* (associativity, commutativity, distributivity) to support some constant folding into nested expressions.

Examples of new transformations:

  • simple nesting: (10 + x) + 10 becomes 20 + x
  • deep nesting: 5 + x + (y + (z + (t + 5))) becomes 10 + (x + (y + (z + t)))
  • distribution: (5 + x) * 6 becomes 30 + 6*x
  • simple factorization: 5 + x + (x + (x + (x + 5))) becomes 10 + (4 *x)
  • siblings: (5 + 4*x) - (3*x + 2) becomes 3 + x

Ticket #9136

2016-12 – Remove GHC’s static flags

GHC was using “static flags”, i.e., flags whose values are accessed through “global variables”. We converted them into dynamic flags. Some of them still use some kind of global variables but at least they can be set before the first use of the GHC API.

Ticket #8440

2016-11 – Scrutinee Constant Folding

We added constant folding into case expressions. For instance the following code:

now becomes:

Ticket #12877

2016-11 – -fhide-source-paths flag

We added a -fhide-source-paths flag to GHC to reduce the line noise when compiling many modules.

Tickets #12807 and #12851

2016-11 – Fix float out bug

Using pattern synonyms and view patterns in the GHC codebase triggered a bug because the float-out optimisation was allowed to float-out levity polymorphic expressions.

Ticket #12901

Linking was failing with GOLD linker so we fixed this.

Ticket #12816

2016-11 – Fix RTS linker bug with 64-bit symbol tables

The RTS linker wasn’t skipping 64-bit symbol table entries. We fixed this.

Ticket #12827

2016-10 – Check foreign primop imports

Foreign primop imports were not checked if the given entity string was empty. The latter triggered an error in the assembler phase (jump to an empty label). We fixed this by using the function name as a label when the entity string is missing (the ccall convention has this behavior, in accordance with the Haskell 2010 report).

Ticket #12355

2016-10 – Uninstall GHC signal handlers

GHC wasn’t properly uninstalling its signal handlers. It is problematic when using the GHC API so we fixed it.

Ticket #4162

2016-09 – Fix foreign call argument overwriting

GHC was sometimes generating bad assembly code for passing arguments to foreign calls (call into C code for instance): the arguments were corrupted. We fixed this.

Tickets #11792 and #12614

2016-04 – Rework PThread based RTS ticker

The RTS ticker thread wasn’t properly disabled when in STOPPED state. We designed an algorithm using double-checked locking that was then implemented by Ben Gamari to solve this issue.

Ticket #11965

2016-02 – Use timerfd on Linux

GHC runtime system (RTS) used alarm signals to implement green threads scheduling. Signals are problematic because they can interrupt system calls (syscalls) and the user-code can mess up with them. We modified GHC’s RTS so that it uses the timerfd syscall on Linux instead of alarm signals.

Tickets #10840

GHC stores information about each build in a ELF section but it wasn’t following the ELF specification while doing so (“note” sections have to follow some rules that weren’t followed). We fixed this by making GHC follow the spec.

GHC used “readelf” program to read the contents of this section back. It was problematic, especially with the previous fix so we replaced it with a direct extraction of the ELF section by using Data.Binary.Get

Tickets #11022 and #10974

2015-10 – Detect use of foreign primops in GHCi

Currently GHCi cannot use foreign primops but this wasn’t checked, leading to GHC panics. We implemented the check.

Ticket #10462

2015-06 – Fix RTS linker allocation

GHC’s runtime system linker needs to allocate memory in the low 2GB of the memory (so that 32-bit relative addresing can be used). GHC was using one mmap call per object in archive files (.a) wasting a lot of memory space (mmap allocates full memory pages even for small objects) and time (mmap call is costly).

We implemented an allocator named M32 allocator that loads several objects into the same memory page. Our code has been manually merged by Simon Marlow into another patch that has been applied.

Ticket #9314

2015-05 – Allow execution of static programs in initramfs

GHC can compile statically linked programs. However, the produced binary was infinitely looping if it couldn’t find the iconv files (used to convert between character sets). We stumbled on this while trying to use a static binary into an initramfs image. We helped in fixing this.

Tickets #7695 and #10298