Template Haskell code optimized poorly
Summary
Simple Template Haskell code is optimized poorly, likely harming splice-time performance. I don't know how much of an impact this has on overall compilation time of code using Template Haskell. My guess is not much, since type checking and optimization take so much time, but it might be worth a little bit of thought. And the cause(s) might also affect other, more performance-sensitive, code.
Steps to reproduce
{-# language TemplateHaskellQuotes #-}
module Vroom where
import Language.Haskell.TH.Syntax
vroom :: Quote m => Code m (a -> b) -> Code m a -> Code m b
vroom f x = [|| $$f $$x ||]
groob :: IO (TExp Bool)
groob = unQ $ examineCode $
vroom
[|| (> (0 :: Int)) ||]
[|| 12 ||]
With GHC 9.2 and -O2
, the Core is a real mess. There isn't enough room to paste it here, but I'll just say
Result size of Tidy Core
= {terms: 275, types: 638, coercions: 120, joins: 0/0}
Typeclass dictionaries fly all over. Yuck. Can it be better? Yes. If I switch to GHC 9.0, and change the definition of groob
a tad, then it's much better.
groob :: IO (TExp Bool)
groob = unQ $ examineCode $
inline vroom
(inline [|| (> (0 :: Int)) ||])
(inline [|| 12 ||])
with GHC 9.0 results in
==================== Tidy Core ====================
Result size of Tidy Core
= {terms: 155, types: 258, coercions: 46, joins: 0/1}
groob
ends up being built up from type constructors in an entirely straightforward fashion. So what's going on? Part of the problem seems to be that quoted syntax isn't automatically inserted inline, which is surprising. Another likely aspect is the complexity of the higher-rank class-polymorphic definition of Q
.
I have no good guess for how to fix this.
Environment
- GHC version used: 9.2
Optional:
- Operating System:
- System Architecture: