How to inline early in a GHC plugin?

I'm implementing a GHC plugin that installs a `BuiltInRule` that does the work, and I'd like to learn how to inline more flexibly. Given an identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a later compiler phase. Meanwhile, I guess my variable `v` has been replaced by one with inlining info. First, am I understanding this mechanism correctly? A GHC source pointer to how inlining is made available would help me. Second, can I access the inlining info before it's made available to the rest of the simplifier? Thanks, - Conal

I don’t really understand your question clearly. So I’ll guess Unfoldings are added to Ids in Simplify.completeBind (look for setUnfoldingInfo). Apart from INLINE pragmas, that’s about the only place it happens. Does that help? S From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of Conal Elliott Sent: 01 December 2016 21:51 To: ghc-devs@haskell.org Subject: How to inline early in a GHC plugin? I'm implementing a GHC plugin that installs a `BuiltInRule` that does the work, and I'd like to learn how to inline more flexibly. Given an identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a later compiler phase. Meanwhile, I guess my variable `v` has been replaced by one with inlining info. First, am I understanding this mechanism correctly? A GHC source pointer to how inlining is made available would help me. Second, can I access the inlining info before it's made available to the rest of the simplifier? Thanks, - Conal

Thanks for the pointers, Simon. Some more specific questions:
* To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)` the
recommended recipe?
* Is it the case that this recipe succeeds (`Just`) in some compiler
phases and not others?
If so, is this difference due to Ids being altered (presumably via
`setUnfoldingInfo` being called between phases)?
* Before an Id is ready for general inlining by the simplifier, can I get
the Id's unfolding another way so that I can substitute it early?
A short Skype chat might easily clear up my questions and confusions if you
have time and inclination.
Regards, - Conal
On Fri, Dec 2, 2016 at 9:07 AM, Simon Peyton Jones
I don’t really understand your question clearly. So I’ll guess
Unfoldings are added to Ids in Simplify.completeBind (look for setUnfoldingInfo). Apart from INLINE pragmas, that’s about the only place it happens.
Does that help?
S
*From:* ghc-devs [mailto:ghc-devs-bounces@haskell.org] *On Behalf Of *Conal Elliott *Sent:* 01 December 2016 21:51 *To:* ghc-devs@haskell.org *Subject:* How to inline early in a GHC plugin?
I'm implementing a GHC plugin that installs a `BuiltInRule` that does the work, and I'd like to learn how to inline more flexibly. Given an identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a later compiler phase. Meanwhile, I guess my variable `v` has been replaced by one with inlining info. First, am I understanding this mechanism correctly? A GHC source pointer to how inlining is made available would help me. Second, can I access the inlining info before it's made available to the rest of the simplifier?
Thanks, - Conal

* To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)` the recommended recipe?
You can see by looking at the code that idUnfolding returns nothing for a loop breaker. You have to decide if that’s what you want; if not, use realIdUnfolding.
* Is it the case that this recipe succeeds (`Just`) in some compiler phases and not others?
It fails for loop breakers. An Id might be a loop breaker in some phases but not others; e.g. the loop might be broken by some optimisation.
* Before an Id is ready for general inlining by the simplifier, can I get the Id's unfolding another way so that I can substitute it early?
realIdUnfolding always works. As the code shows
idUnfolding :: Id -> Unfolding
-- Do not expose the unfolding of a loop breaker!
idUnfolding id
| isStrongLoopBreaker (occInfo info) = NoUnfolding
| otherwise = unfoldingInfo info
where
info = idInfo id
realIdUnfolding :: Id -> Unfolding
-- Expose the unfolding if there is one, including for loop breakers
realIdUnfolding id = unfoldingInfo (idInfo id)
Does that help?
Simon
From: conal.elliott@gmail.com [mailto:conal.elliott@gmail.com] On Behalf Of Conal Elliott
Sent: 02 December 2016 18:13
To: Simon Peyton Jones

Yes, thank you, Simon. I had not occurred to me that an inlining could
start working in a later phase due to loss of loop-breaker status, rather
than the relationship between the current phase and the identifier's
declared inlining phase.
-- Conal
On Tue, Dec 6, 2016 at 6:02 AM, Simon Peyton Jones
* To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)` the recommended recipe?
You can see by looking at the code that idUnfolding returns nothing for a loop breaker. You have to decide if that’s what you want; if not, use realIdUnfolding.
* Is it the case that this recipe succeeds (`Just`) in some compiler phases and not others?
It fails for loop breakers. An Id might be a loop breaker in some phases but not others; e.g. the loop might be broken by some optimisation.
* Before an Id is ready for general inlining by the simplifier, can I get the Id's unfolding another way so that I can substitute it early?
realIdUnfolding always works. As the code shows
idUnfolding :: Id -> Unfolding
-- Do not expose the unfolding of a loop breaker!
idUnfolding id
| isStrongLoopBreaker (occInfo info) = NoUnfolding
| otherwise = unfoldingInfo info
where
info = idInfo id
realIdUnfolding :: Id -> Unfolding
-- Expose the unfolding if there is one, including for loop breakers
realIdUnfolding id = unfoldingInfo (idInfo id)
Does that help?
Simon
*From:* conal.elliott@gmail.com [mailto:conal.elliott@gmail.com] *On Behalf Of *Conal Elliott *Sent:* 02 December 2016 18:13 *To:* Simon Peyton Jones
*Cc:* ghc-devs@haskell.org *Subject:* Re: How to inline early in a GHC plugin? Thanks for the pointers, Simon. Some more specific questions:
* To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)` the recommended recipe?
* Is it the case that this recipe succeeds (`Just`) in some compiler phases and not others?
If so, is this difference due to Ids being altered (presumably via `setUnfoldingInfo` being called between phases)?
* Before an Id is ready for general inlining by the simplifier, can I get the Id's unfolding another way so that I can substitute it early?
A short Skype chat might easily clear up my questions and confusions if you have time and inclination.
Regards, - Conal
On Fri, Dec 2, 2016 at 9:07 AM, Simon Peyton Jones
wrote: I don’t really understand your question clearly. So I’ll guess
Unfoldings are added to Ids in Simplify.completeBind (look for setUnfoldingInfo). Apart from INLINE pragmas, that’s about the only place it happens.
Does that help?
S
*From:* ghc-devs [mailto:ghc-devs-bounces@haskell.org] *On Behalf Of *Conal Elliott *Sent:* 01 December 2016 21:51 *To:* ghc-devs@haskell.org *Subject:* How to inline early in a GHC plugin?
I'm implementing a GHC plugin that installs a `BuiltInRule` that does the work, and I'd like to learn how to inline more flexibly. Given an identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a later compiler phase. Meanwhile, I guess my variable `v` has been replaced by one with inlining info. First, am I understanding this mechanism correctly? A GHC source pointer to how inlining is made available would help me. Second, can I access the inlining info before it's made available to the rest of the simplifier?
Thanks, - Conal
participants (2)
-
Conal Elliott
-
Simon Peyton Jones