Skip to content

Pattern match coverage checker allocates twice as much for trivial program with instance constraint vs. without

While preparing a comparison chart of performance test cases between GHC 8.8.3 and GHC HEAD, T11276 (#11276 (closed)) stood out as the only test that actually allocated 28% more than it used to. @RyanGlScott and I managed to boil the test case down to the following offending program:

module Bug where

instance Monad m => Functor (Pipe m) where
    fmap = undefined
    {-# INLINE fmap #-}

instance Monad m => Applicative (Pipe m) where
    pure = undefined
    {-# INLINE pure #-}
    (<*>) = undefined
    {-# INLINE (<*>) #-}

instance Monad m => Monad (Pipe m) where
    return = undefined
    {-# INLINE return #-}
    (>>=) = undefined

data Pipe m a = P (m a)

Removing the Monad => instance constraint cuts down allocations by desugaring by 50%.

Apparently it's due to calling GHC.HsToCore.PmCheck.addTyCsDs thrice with the same dictionary from the desugarer, which seems completely unnecessary. I imagine that we can handle this case more efficiently when we don't throw away the state of the type-checker anymore (#17836 (closed)). But let's see if we can get rid of the redundant calls.

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