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.