[GHC] #13993: Certain inter-module specializations run out of simplifier ticks
GHC
ghc-devs at haskell.org
Tue Jul 18 21:35:26 UTC 2017
#13993: Certain inter-module specializations run out of simplifier ticks
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: new
Priority: high | Milestone: 8.4.1
Component: Compiler | Version: 8.0.1
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: Compile-time
Unknown/Multiple | performance bug
Test Case: | Blocked By:
Blocking: | Related Tickets: #9630
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
A modification of ezyang's test case in #9630 yields the below. Triggering
specialization in a separate module can run the simplifier out of ticks.
Notably, moving the definition of `T` into `GenSpec` resolves the problem.
Unlike #9630 proper, this seems to cause trouble going back as far as GHC
7.4.
{{{#!hs
module GenSpec where
import Gen
import GHC.Generics
-- Trigger specialization
tput :: T -> Put
tput = gput . from
}}}
{{{#!hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
module Gen where
import GHC.Generics
import Control.Monad
import Control.Applicative
import Data.Monoid
data PairS a = PairS a !(() -> ())
newtype PutM a = Put { unPut :: PairS a }
-- Use of this writer monad seems to be important; IO speeds it up
type Put = PutM ()
--type Put = IO ()
-- binary has INLINE pragmas on most of the instances but you can still
-- trigger bad behavior without them.
instance Functor PutM where
fmap f m = Put $ let PairS a w = unPut m in PairS (f a) w
-- Just to appease AMP
instance Applicative PutM where
pure = return
(<*>) = ap
instance Monad PutM where
return a = Put $ PairS a id
m >>= k = Put $
let PairS a w = unPut m
PairS b w' = unPut (k a)
in PairS b (w . w')
class GBinary f where
gput :: f t -> Put
-- Forcing the dictionary to have two elements hurts
-- the optimizer a lot.
not_used :: f t
instance GBinary a => GBinary (M1 i c a) where
gput = gput . unM1
instance Binary a => GBinary (K1 i a) where
gput = put . unK1
instance (GBinary a, GBinary b) => GBinary (a :*: b) where
gput (x :*: y) = gput x >> gput y
class Binary t where
put :: t -> Put
instance Binary () where
put () = return ()
data T = T () () () () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
() () () () () () () () () ()
deriving Generic
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13993>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list