<div dir="ltr"><p>Hi Simon.</p>
<p>Thanks for the reply. Below, I try to explain more clearly what I
want and why below. If it’s still murky, and if you’re up for it, a
Skype chat would probably help a lot.</p>
<p>I think I’m looking for something very close to GHC’s specialization
as it is now, and I’m wondering how to best leverage the specialization
that GHC already does. I have a GHC plugin that transforms Core programs
into reifying versions of themselves. The transformation is triggered
by application of a “function” <code>reify ∷ a → E a</code> for an expression GADT). <code>reify</code>
is more like a macro, in that its implementation relies on the (Core)
syntax of its argument, not just its semantics, but in a well-behaved
way (with a simple, non-syntactic specification). This reifying
transformation benefits from the dictionary elimination that GHC’s
specializer performs, and I’d like to benefit more. After
specialization, or as part of it, I want to reuse the work of reifying
the specialized definition. Currently I have to inline the code
generated by the specializer, across modules (and assuming that its code
is available), and then reify it at each call site. I’d rather have the
option to reify specializations in the defining module and then reuse
those reified specializations at call-sites, even in other modules.
Thus, I don’t want to specialize a function <code>foo</code> at various types, but the result of transforming <code>reify foo</code>
for those types, hence my interest in specializing expressions at least
a bit more complicated than identifiers. I expect that this scheme, or
something like it, will let me eliminate much inlining of code from
other modules and then reifying these large expressions. In other words,
it lets me do “separate reification” akin to separate compilation.</p>
<p>Perhaps I should be thinking of specializing reifications instead of
reifying specializations. I guess that alternative would mean having the
specializer perform reification (using a few <code>CoreExpr</code> rewrites) as part of the work it does. Given <code>foo ∷ T</code> (where <code>T</code> may include polymorphism and dictionaries), I might generate</p>
<div style="margin-left:40px" class=""><pre class=""><code class="">reify_foo <span class="">∷</span> <span class="">E</span> <span class="">T</span>
</code><code class="">reify_foo <span class="">=</span> reify foo</code></pre></div>
<p>and then transform the RHS to remove the <code>reify</code> call, resulting in <code>E</code>-building Core code. Then request specializations for <code>reify_foo</code>.</p>
<p>The types are not quite this simple, due to polymorphism and dictionaries. For instance, given</p>
<div style="margin-left:40px" class=""><pre class=""><code class="">sum <span class="">∷</span> (<span class="">Foldable</span> f, <span class="">Num</span> a) <span class="">⇒</span> f a <span class="">→</span> a</code></pre></div>
<p>generate</p>
<div style="margin-left:40px" class=""><pre class=""><code class="">reify_sum <span class="">∷</span> (<span class="">Foldable</span> f, <span class="">Num</span> a) <span class="">⇒</span> <span class="">E</span> (f a <span class="">→</span> a)
reify_sum <span class="">=</span> reify sum</code></pre></div>
<p>In Core,</p>
<div style="margin-left:40px" class=""><pre class=""><code class="">reify_sum <span class="">∷</span> <span class="">∀</span> f a<span class="">.</span> <span class="">Foldable</span> f <span class="">→</span> <span class="">Num</span> a <span class="">→</span> <span class="">E</span> (f a <span class="">→</span> a)
reify_sum <span class="">=</span> λ (<span class="">@</span> f) (<span class="">@</span> a) (<span class="">$</span>dFoldable <span class="">∷</span> <span class="">Foldable</span> f) (<span class="">$</span>dNum <span class="">∷</span> <span class="">Num</span> a)
<span class="">→</span> reify (sum <span class="">@</span> f <span class="">@</span> a <span class="">$</span>dFoldable <span class="">$</span>dNum)</code></pre></div>
<p>Then ask for specializations of <code>reify_sum</code>. Since reification all happens invisibly, <code>reify_sum</code> won’t ever get called in client code. Instead, I’d have to also recognize calls to <code>reify sum</code> from other modules and replace those calls with <code>reify_sum</code>.</p>
<p>Oh. Hm. Perhaps the specializer doesn’t have to invoke the reifier after all. Maybe I can generate definitions like <code>reify_sum</code> and some <code>SPECIALIZE</code> pragmas (or directly invoke the equivalent code GHC), and then reify the results after the specializer runs.</p>
<p>I’ve started down a path of doing something similar:</p>
<ul><li>Wait until the specializer has run.</li><li>Reify all top-level definitions I’m able to, adding new reifying definitions and <code>reify</code>
rules that use those new definitions (as the specializer does). Here’s
where I’m worried about the efficiency of having many rules with the
same RHS top-level identifier.</li><li>Apply those rules in other modules during reification, pushing <code>reify</code> calls inward where they can meet up with other functions also <code>reify</code> rules from other modules.</li></ul>
<p>Because I’m worried about the performance with many <code>reify</code> rules, maybe I’ll drop the rules and instead export definitions like <code>reify_sum</code> (after <code>reify</code>-transforming
the RHS), with predictable names, and then explicitly look for those
names across modules during reification. Or does GHC handle that
situation well, as long there are few uses (probably only one use) of
each name that <code>reify</code> is applied to in these rules (thanks to the specializer having already run, yielding many differently named specializations).
</p><p>As I mentioned, a Skype chat may be helpful.</p><p>Best regards, - Conal<br></p><p><br></p> </div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 3, 2016 at 8:47 AM, Simon Peyton Jones <span dir="ltr"><<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div link="blue" vlink="purple" lang="EN-GB">
<div>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">I’m sorry Conal I’m not getting this.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Specialisation happens when you have a named chunk of code that is repeatedly called at different types, and with different args. We can inline it bodily to specialise
to that one call site, but it’s cooler to make a single specialised version which can be shared among many call sites. (And that approach deals with recursive functions too.)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">But that explanation is fundamentally about named functions, so I don’t understand this “general expression” bit. Sorry!<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Simon<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif" lang="EN-US">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif" lang="EN-US"> ghc-devs [mailto:<a href="mailto:ghc-devs-bounces@haskell.org" target="_blank">ghc-devs-bounces@haskell.org</a>]
<b>On Behalf Of </b>Conal Elliott<br>
<b>Sent:</b> 01 February 2016 01:16<br>
<b>To:</b> <a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<b>Subject:</b> Re: Specializing expressions beyond names?<u></u><u></u></span></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:12.0pt;margin-left:0cm">
A related question: if there are a great many rules of the form "reify (foo ...) = ...", where 'reify' is always present (and the outermost application head) but for many different argument expressions, will rule matching be linear (expensive) in the number
of such rules?<u></u><u></u></p>
</div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
-- Conal<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u> <u></u></p>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
On Sun, Jan 31, 2016 at 1:58 PM, Conal Elliott <<a href="mailto:conal@conal.net" target="_blank">conal@conal.net</a>> wrote:<u></u><u></u></p>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
It seems to be the case that <code><span style="font-size:10.0pt">SPECIALIZE</span></code> pragmas are syntactically restricted to type specializations of a
<em>name</em> (identifier) rather than a general expression. Is my understanding correct here? If so, is there any reason for this restriction?
<u></u><u></u></p>
<p>I ask because I’m reifying Core code (into code that constructs a corresponding run-time representation for further processing), and I’m looking for a clean way to integrate that process with GHC, to support separate compilation and to avoid interfering
with GHC’s regular flow. It occurred to me that I could enable separate compilation via a pragma of the form “<code><span style="font-size:10.0pt">{-# SPECIALIZE reify foo
</span></code><code><span style="font-size:10.0pt;font-family:"Cambria Math",serif">∷</span></code><code><span style="font-size:10.0pt"> E t #-}</span></code>” for some
<code><span style="font-size:10.0pt">t</span></code>, where <code><span style="font-size:10.0pt">E t</span></code> is a reified form of values of type
<code><span style="font-size:10.0pt">t</span></code>. Type checking would infer the specialized type of
<code><span style="font-size:10.0pt">foo</span></code>, and the usual specialization phase would do its usual thing on that specialization, leaving “<code><span style="font-size:10.0pt">reify foo = reify specialized_foo</span></code>”, and then the reification
compiler plugin would transform the right-hand side, pushing the <code><span style="font-size:10.0pt">reify</span></code> inward. Some
<code><span style="font-size:10.0pt">reify</span></code> calls may remain (e.g., due to polymorphism), triggering future rule applications. As much as possible of the fully-reified version would be factored out of the generated rule’s RHS for cheap reuse.<u></u><u></u></p>
<p><u></u> <u></u></p>
<p>Thanks, - Conal <u></u><u></u></p>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div>
</div>
</div>
</blockquote></div><br></div>