Huge unfolding of generic Hashable instance
Summary
I discovered this because certain small modules would take a long time to compile. I looked at the Core and discovered that the Hashable
instance's hashWithSalt
had a huge unfolding. Much of the code was devoted to repeatedly expressing generic Rep
's in type applications.
I managed to extract the following reproducer, and confirmed the behaviour also occurs on ghc-{8.8.4,8.10.4,9.0.1}.
9.3 does a much better job of optimising the hashWithSalt
function, eliminating the use of Rep
s entirely. Previous versions didn't eliminate these at all.
Removing the INLINE
pragma on hashWithSalt
in the Hashable
class's definition avoids this issue.
Whereas with previous versions of GHC, the unfolding gave the best GHC could do, with GHC-9.3, we can better optimise this code, and the unfolding should give that version.
Steps to reproduce
Examine the core for the following module when compiled with ghc-9.3:
{-# LANGUAGE DeriveGeneric #-}
module Test where
import Data.Hashable
import GHC.Generics
data A = A1
| A2
| A3
| A4
| A5
| A6
| A7
| A8
| A9
| A10
| A11
| A12
| A13
| A14
| A15
| A16
deriving Generic
instance Hashable A
Expected behaviour
The core for this module should be reasonably small
Environment
- GHC version used:
The Glorious Glasgow Haskell Compilation System, version 9.3.20210723
Optional:
- Operating System: Linux
- System Architecture: x86_64