Why can't arguments be levity polymorphic for inline functions?

Andreas Klebinger klebinger.andreas at gmx.at
Fri Oct 8 12:39:00 UTC 2021


Hey Clinton,

I think the state of things is best summarised it's in principle
possible to implement. But it's unclear how best to do so
or even if it's worth having this feature at all.

The biggest issue being code bloat.

As you say a caller could create it's own version of the function with
the right kind of argument type.
But that means duplicating the function for every use site (although
some might be able to be commoned up). Potentially causing a lot of code
bloat and compile time overhead.

In a similar fashion we could create each potential version we need from
the get go to avoid duplicating the same function.
But that runs the risk of generating far more code than what is actually
used.

Last but not least GHC currently doesn't always load unfoldings. In
particular if you compile a module with optimizations disabled the RHS
is currently *not*
available to the compiler when looking at the use site. There already is
a mechanism to bypass this in GHC where a function *must* be inlined
(compulsory unfoldings).
But it's currently reserved for built in functions. We could just make
INLINE bindings compulsory if they have levity-polymorphic arguments
sure. But again it's not clear
this is really desireable.

I don't think this has to mean we couldn't change how things work to
accomodate levity-polymorphic arguments. It just seems it's unclear what
a good design
would look like and if it's worth having.

Cheers
Andreas

Am 08/10/2021 um 01:36 schrieb Clinton Mead:
> Hi All
>
> Not sure if this belongs in ghc-users or ghc-devs, but it seemed devy
> enough to put it here.
>
> Section 6.4.12.1
> <https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/levity_polymorphism.html>
> of the GHC user manual points out, if we allowed levity polymorphic
> arguments, then we would have no way to compile these functions,
> because the code required for different levites is different.
>
> However, if such a function is {-# INLINE #-} or{-# INLINABLE #-}
> there's no need to compile it as it's full definition is in the
> interface file. Callers can just compile it themselves with the levity
> they require. Indeed callers of inline functions already compile their
> own versions even without levity polymorphism (for example, presumably
> inlining function calls that are known at compile time).
>
> The only sticking point to this that I could find was that GHC will
> only inline the function if it is fully applied
> <https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/pragmas.html#inline-pragma>,
> which suggests that the possibility of partial application means we
> can't inline and hence need a compiled version of the code. But this
> seems like a silly restriction, as we have the full RHS of the
> definition in the interface file. The caller can easily create and
> compile it's own partially applied version. It should be able to do
> this regardless of levity.
>
> It seems to me we're okay as long as the following three things aren't
> true simultaneously:
>
> 1. Blah has levity polymorphic arguments
> 2. Blah is exported
> 3. Blah is not inline
>
> If a function "Blah" is not exported, we shouldn't care about levity
> polymorphic arguments, because we have it's RHS on hand in the current
> module and compile it as appropriate. And if it's inline, we're
> exposing it's full RHS to other callers so we're still fine also. Only
> when these three conditions combine should we give an error, say like:
>
> "Blah has levity polymorphic arguments, is exported, and is not
> inline. Please either remove levity polymorphic arguments, not export
> it or add an {-# INLINE #-} or {-# INLINABLE #-} pragma.
>
> I presume however there are some added complications that I don't
> understand, and I'm very interested in what they are as I presume
> they'll be quite interesting.
>
> Thanks,
> Clinton
>
>
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20211008/be082780/attachment.html>


More information about the ghc-devs mailing list