nomeata / inspection-testing

Inspection Testing for Haskell
MIT License
173 stars 27 forks source link

Obligation that unfoldings are exposed #27

Open phadej opened 5 years ago

phadej commented 5 years ago

This feels like something inspection-testing should be able to do.

fmap2 :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
fmap2 = fmap . fmap

Then in a test-suite, I'd like to verify that fmap2's (optimised) unfoldings are exposed.

There are cases where {-# INLINE #-} would case code size blowup (causing slow compilation, because exported unfolding is not optimised), but we still want unfoldings to be exposed (to get good optimised code which uses the symbol: there are no pragma to guarantee that optmised unfoldings are exposed, -fexpose-all-unfoldings is a blunt hammer).

Real world example is described in http://mpickering.github.io/posts/2017-05-17-inlining-case-study.html

nomeata commented 5 years ago

Sounds like a need for a GHC pragma that has that effect…

Have you already thought about how this would be checked in a core plugin?

phadej commented 5 years ago

@nomeata yes, Matthew ends his post with

It would be good to add a new pragma which instructs GHC to inline an optimised unfolding across modules rather than the unoptimised version so that the second scenario can be reliably achieved.

I haven't thought how, I'm not sure what's possible in core plugin. If a name in defined outside current module, one probably could ask if its unfolding is available; but can it be done in typechecker, or is the ship sailed at that point? Or can TemplateHaskell already do that?

nomeata commented 5 years ago

For an imported name, I expect it can be done reliably in any GHC-internal pass (Typechecker, Core2core), but not in TH.