>
> it seems like a rather aggressive optimisation strategy to me.

It is indeed aggressive.  Essentially when you declare a data type (like
Step) to be fusible you are declaring that you never want a single value of
type `Step` to be actually built at runtime -- they should all be fused
away.   If a function returns value of type `Step`, it *can't* be fused
away; so we have to inline the function.  Ditto if it takes a value of type
`Step` as argument.

But in Harendra's applications it works rather well apparently.

What is the goal you want to achieve.  "Fuse where possible" perhaps?   But
what is "possible"?

I have a feeling that in your library you do have a very clear idea of what
should be fused and what should not. What is that idea?

Simon

On Mon, 8 Dec 2025 at 18:05, Jaro Reinders <[email protected]> wrote:

> Dear Simon Peyton Jones and other interested GHC devs,
>
> In a recent thread on the issue tracker of the vector package, I was asked
> for
> my thoughts on a specific improvement to their fusion system [1]. I
> replied I
> was a bit disillusioned with GHC's approach to fusion because it is not
> reliable enough for the average user.
>
> Simon pointed me to a GHC plugin by Harendra Kumar which acts as a
> lubricant
> for fusion, telling GHC to inline more than usual [2].
>
> I suggested we could integrate this into GHC by giving an inlining
> discount to
> any function which contains function that is also mentioned in a rewrite
> rule.
> However, I also noted I think this will have a large impact on code size
> and
> compilation time in larger code bases. Simon agreed, but noted that
> Harendra's
> plugin is much more selective than what I suggested.
>
> Since I think this discussion is not that relevant to the particular issue
> in
> the vector package, I'd like to continue this discussion here.
>
> To figure out what Harendra's plugin does, I skimmed the blog post and
> found
> this explanation [2]:
>
>  > fusion-plugin gives programmers control through fusion annotations.
>  >
>  >     {-# ANN type Step Fuse #-}
>  >     data Step s a = Yield a s | Skip s | Stop
>  >
>  > This tells the compiler:
>  >
>  > Any binding that scrutinizes or constructs Step must be inlined,
>  > no matter its size.
>  >
>  > The plugin scans bindings during the simplifier pass:
>  >
>  > * If a fusible type (Step) is involved → mark it INLINE.
>  > * Run another simplifier pass → constructors eliminated → fusion
> restored.
>
> Translating this to the fold/build fusion system in GHC today, we would
> force
> inlining of any function that calls `foldr` or `build` (or `augment`).
> Essentially, we would want to inline any binding that refers to a function
> that
> partakes in the rewrite rules for fusion. I'll admit we probably don't
> have to
> generalise this to all rewrite rules, but even with this restriction it
> seems
> like a rather aggressive optimisation strategy to me.
>
> Please correct me if I have misinterpreted anything.
>
> Cheers,
>
> Jaro
>
> [1] https://github.com/haskell/vector/issues/156#issuecomment-3623339336
> [2] https://blog.composewell.com/versions/v2/posts/streamly-fusion-3.html
>
_______________________________________________
ghc-devs mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to