Example.hs is the plugin code to be used with GHC, and which contains all the logic to write out, as well as read in the core expressions and inline them.
The setup consists of a Lib module, and a Main module, where the Main module depends on the Lib module. Thus compiling the Main module with the Example plugin should demonstrate the inlining of core expressions.
NOTE: There is also a Makefile that ties this all together and provides a reproducible setup.
Please observe that we can see in (2), that the following expression from (1)
g (+ @Int $fNumInt (f x) y)
was replaced by
case + @Int
$fNumInt
(+ @Int $fNumInt (I# 1#) (I# 1#))
(+ @Int $fNumInt x (I# 2#))
of
{ I# ds ->
case ds of {
__DEFAULT -> False;
0# -> True
}
}
If we now treat Lib as it's own cabal package, this also works - with identical results. This is because the loading process is agnostic to package, so as long as the bindings exist, they will be loaded. In the case of one-shot compilation, modules appear as external anyway, so we would have to explicitly test for external package names if we wanted (for some reason) to exclude this working outside of the home package.
This is an example use case for the Extensible Interface Files, ghc!2948 GHC extension. The idea is to use store and load GHCs core representation from the interface files without having to resort to
-fexpose-all-unfoldings
or excessiveINLINE
pragmas. A high level overview is given in README.Example.hs is the plugin code to be used with GHC, and which contains all the logic to write out, as well as read in the core expressions and inline them.
The setup consists of a Lib module, and a Main module, where the
Main
module depends on theLib
module. Thus compiling theMain
module with theExample
plugin should demonstrate the inlining of core expressions.NOTE: There is also a Makefile that ties this all together and provides a reproducible setup.
Discussion
The
Main
module contains the following functiont
: https://github.com/input-output-hk/tools/blob/23c7b7c1d0d7fc4de649ebfe124a0ed2b5a7c329/examples/extensible-interface-files/core-plugins/basic-example/Main.hs#L19-L20which we call in the
main
function of theMain
module here:https://github.com/input-output-hk/tools/blob/23c7b7c1d0d7fc4de649ebfe124a0ed2b5a7c329/examples/extensible-interface-files/core-plugins/basic-example/Main.hs#L6-L9
Thus to evaluate
t
we needf
,g
as well asx
andy
, from theLib
module. https://github.com/input-output-hk/tools/blob/23c7b7c1d0d7fc4de649ebfe124a0ed2b5a7c329/examples/extensible-interface-files/core-plugins/basic-example/Lib.hs#L21-L23https://github.com/input-output-hk/tools/blob/23c7b7c1d0d7fc4de649ebfe124a0ed2b5a7c329/examples/extensible-interface-files/core-plugins/basic-example/Lib.hs#L25-L28
https://github.com/input-output-hk/tools/blob/23c7b7c1d0d7fc4de649ebfe124a0ed2b5a7c329/examples/extensible-interface-files/core-plugins/basic-example/Lib.hs#L35-L37
(1) Without using the plugin we can see that the
Main
module produces the following core:(2) when using the
Example
plugin, we observe that theMain
modules core now looks like this:Please observe that we can see in (2), that the following expression from (1)
was replaced by
If we now treat
Lib
as it's own cabal package, this also works - with identical results. This is because the loading process is agnostic to package, so as long as the bindings exist, they will be loaded. In the case of one-shot compilation, modules appear as external anyway, so we would have to explicitly test for external package names if we wanted (for some reason) to exclude this working outside of the home package.