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
becomes20 + x
- deep nesting:
5 + x + (y + (z + (t + 5)))
becomes10 + (x + (y + (z + t)))
- distribution:
(5 + x) * 6
becomes30 + 6*x
- simple factorization:
5 + x + (x + (x + (x + 5)))
becomes10 + (4 *x)
- siblings:
(5 + 4*x) - (3*x + 2)
becomes3 + 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:
main = case t of t0
0## -> ...
DEFAULT -> case t0 -# 1## of t1
0## -> ...
DEFAUT -> case t1 -# 1## of t2
0## -> ...
DEFAULT -> case t2 -# 1## of _
0## -> ...
DEFAULT -> ...
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.
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
2016-11 – Fix link errors with GOLD linker
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.
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
2015-11 – Fix “link info” ELF section
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
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.