
#12463: SPECIALIZABLE pragma? -------------------------------------+------------------------------------- Reporter: bgamari | Owner: Type: feature | Status: new request | Priority: low | Milestone: Component: Compiler | Version: 8.0.1 Keywords: Inlining | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Currently it is common practice for library authors to use the `INLINEABLE` pragma to make it more likely that a polymorphic function should get an unfolding in the module's interface file to ensure that GHC is able to specialize. While in practice this works reasonably well, it's not really saying what we often mean: we don't want to inline, we really just want GHC to behave like each use-site's module has a `SPECIALISE` pragma for each concrete type that the function is used at. For instance, consider, {{{#!hs module ALibrary where aLibraryFunction :: AClass a => a -> a aLibraryFunction = {- some large expression involving methods of AClass -} module SomeUser where import ALibrary aUser :: Int -> Int aUser = {- some large expression involving aLibraryFunction -} }}} Ideally, we would want GHC to take and produce one specialized version of `aLibraryFunction` for every concrete type which it is used at. However, without an `INLINEABLE` function, GHC won't even consider producing an unfolding for `aLibraryFunction` due to its size. If we include an `INLINEABLE` pragma (as most performance-aware authors would do) then we can convince GHC to produce an unfolding, but only at the expense of lowering its inlining cost as well. This is unfortunate since we never wanted GHC to inline; merely to specialize. This is issue especially prevalent in code using MTL-style effects, where we have ubiquitous overloading of very frequently-used functions (e.g. bind). Really what we want in this case is a way of indicating to GHC that a function shouldn't be inlined (use-sites replaced with the body of the function), but rather that GHC should try hard to specialize away particular type variables. This might look like, {{{#!hs aLibraryFunction :: AClass a => a -> a aLibraryFunction = {- some large expression involving methods of AClass -} {-# SPECIALIZE forall a. LibraryFunction a #-} }}} This would request that GHC would keep an inlining around and produce a specialized version of `aLibraryFunction` every time it saw a concrete instantiation of `a`. Moreover, it would try to minim -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12463 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler