Skip to content

Allow specialization of more functions provided by GHC/base.

Motivation

Many functions and instances provided with GHC are defined in a recursive manner.

Using the Eq [a] instance as example

instance (Eq a) => Eq [a] where
    {-# SPECIALISE instance Eq [[Char]] #-}
    {-# SPECIALISE instance Eq [Char] #-}
    {-# SPECIALISE instance Eq [Int] #-}
    []     == []     = True
    (x:xs) == (y:ys) = x == y && xs == ys
    _xs    == _ys    = False

By default GHC won't provide unfoldings for a function like this. Since it's a loop breaker it won't be inlined so exposing the unfolding is considered wasteful.

However it can still be specialized. This removes the overhead of the overloaded Eq instance improving performance by a lot when it happens.

Proposal

Alternative 1

GHC should retain unfoldings for certain loop breakers.

If a function:

  • Take a dictionary argument
  • Is sufficiently small

Then specializing it has a high chance of being beneficial and the unfolding should be kept.

Alternative 2

Keep eliminating loopbreaker unfoldings.

But add INLINEABLE to GHC provided definitions where it's deemed useful.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information