<div dir="auto">Let me give an example. Suppose we have<div dir="auto"><br></div><div dir="auto">data L = LCon1 Int | LCon2</div><div dir="auto">data S = SCon !Int</div><div dir="auto"><br></div><div dir="auto">{-# RULES</div><div dir="auto">"L" LCon1 0 = LCon2</div><div dir="auto">"S" forall x . f (SCon x) = g x</div><div dir="auto"> #-}</div><div dir="auto"><br></div><div dir="auto">The immediate problem today is with "S". The SCon wrapper could very well inline before the rule has a chance to fire. We'd like to be able to phase that inline to give it a chance.</div><div dir="auto"><br></div><div dir="auto">The "L" rule becomes problematic when we try to identify static data the simplifier shouldn't have to try to optimize. If it identifies LCon 0 as static, the "L" rule will never fire.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Feb 16, 2017 7:08 PM, "David Feuer" <<a href="mailto:david.feuer@gmail.com">david.feuer@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Semantically, the proposed scheme is very nearly equivalent to breaking *every* data constructor into a worker and a wrapper, and allowing INLINE and NOINLINE pragmas on the wrappers. That would allow terms built only from constructor workers and literals to be identified as they're constructed in any stage and left alone by the simplifier. It would also allow people using RULES that match on constructors to make those work reliably, by making sure the bindings they match on don't inline away or get marked static too early. Of course, we don't actually need to add more worker/wrapper pairs to do this; we can fake that.</div><div class="gmail_extra"><br><div class="gmail_quote">On Feb 16, 2017 6:53 PM, "Simon Peyton Jones" <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-GB" link="blue" vlink="purple">
<div class="m_-990701045371733205m_392705073088009676WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">I’m sorry I still don’t understand the problem.  Can you give an example?  It all works fine today; what will change in the proposed new scheme. 
 Indeed what IS the proposed new scheme?  <u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">I’m lost<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">Simon<u></u><u></u></span></p>
<p class="MsoNormal"><a name="m_-990701045371733205_m_392705073088009676__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u> <u></u></span></a></p>
<span></span>
<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 lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> David Feuer [mailto:<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>]
<br>
<b>Sent:</b> 16 February 2017 23:51<br>
<b>To:</b> Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>><br>
<b>Cc:</b> ghc-devs <<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a>>; Reid Barton <<a href="mailto:rwbarton@gmail.com" target="_blank">rwbarton@gmail.com</a>>; Ben Gamari <<a href="mailto:bgamari@gmail.com" target="_blank">bgamari@gmail.com</a>><br>
<b>Subject:</b> RE: Static data and RULES<u></u><u></u></span></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
Sorry; guess I should have given more background on that. <span style="font-family:"Arial",sans-serif">This goes back to the performance problems Ben encountered in Typeable. </span>The goal is to avoid trying to optimize something over and over that's never
 ever going to change. If we know that a term is made only of static data, we can skip it altogether in simplification. Suppose we have<u></u><u></u></p>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
foo = Just (Right [1])<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>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
Then no amount of optimization will ever be useful. But what about RULES? If the outermost pattern in a rule matches on a data constructor, then it's not static anymore! We may be replacing it with something else. So we need a finer mechanism. We *also* need
 a finer mechanism for strict constructors in general. We need to avoid inlining those too early if they're mentioned in any position in RULES. Trying to make this work right automagically looks a bit tricky in the face of orphan rules and such.<u></u><u></u></p>
</div>
</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 Feb 16, 2017 6:35 PM, "Simon Peyton Jones" <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</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>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">I don’t understand any of this. 
</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> </span><u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">
However, RULES are allowed to match on data constructors and it would be nice to let that keep happening.<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:5.3pt">
 <u></u><u></u></p>
<p class="MsoNormal">Why won’t it keep happening?  What is the problem you are trying to solve?  Why does the fast-path make it harder?<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">Maybe open a ticket?<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">Simon<u></u><u></u></p>
<p class="MsoNormal"><a name="m_-990701045371733205_m_392705073088009676_m_-1961727496805304294__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> </span></a><u></u><u></u></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 lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> ghc-devs
 [mailto:<a href="mailto:ghc-devs-bounces@haskell.org" target="_blank">ghc-devs-bounces@haske<wbr>ll.org</a>]
<b>On Behalf Of </b>David Feuer<br>
<b>Sent:</b> 16 February 2017 22:13<br>
<b>To:</b> Ben Gamari <<a href="mailto:bgamari@gmail.com" target="_blank">bgamari@gmail.com</a>>; Reid Barton <<a href="mailto:rwbarton@gmail.com" target="_blank">rwbarton@gmail.com</a>><br>
<b>Cc:</b> ghc-devs <<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a>><br>
<b>Subject:</b> Static data and RULES</span><u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">Ben Gamari and Reid Barton are interested in making it cheaper for static data to pass through simplification. The basic idea is that if a term is already made entirely of data constructors
 and literals, then there's nothing left to optimize.<u></u><u></u></p>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">However, RULES are allowed to match on data constructors and it would be nice to let that keep happening. But on the other hand, RULES are apparently (according to Duncan Coutts) already
 broken for strict data constructors, because they have workers and wrappers.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">My thought: let's allow phased INLINE and NOINLINE pragmas for data constructors. The default would be INLINE. The ~ phase choice would not be available: once inline, always inline.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">Semantics<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">~~~~~~~~~~<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">For all constructors:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">If a constructor is allowed by pragmas to inline in a certain phase, then in that phase terms built from it can be considered static. Once static, always static.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">If a constructor is not allowed to inline in a certain phase, terms built from it will be considered non-static.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">After demand analysis and worker/wrapper, all constructors are considered inline.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">For strict constructors:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">A strict constructor wrapper prohibited from inlining in a certain phase simply will not.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">Strict constructor wrappers will all be allowed to inline after demand analysis and worker/wrapper. This matches the way we now handle wrappers actually created in that phase.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">Syntax:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">For GADT syntax, this is easy:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">data Foo ... where<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">  {-# INLINE [1] Bar #-}<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">  Bar :: ...<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">For traditional syntax, I think it's probably best to pull the pragmas to the top:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">{-# NOINLINE Quux #-}<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:6.0pt">data Baz ... = Quux ... | ...<u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>

</blockquote></div></div>
</blockquote></div></div>