<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 19, 2018 at 10:21 AM, Dylan Baker <span dir="ltr"><<a href="mailto:dylan@pnwbakers.com" target="_blank">dylan@pnwbakers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Quoting Jason Ekstrand (2018-03-17 23:37:51)<br>
<div><div class="h5">> On Sat, Mar 17, 2018 at 10:32 PM, Dylan Baker <<a href="mailto:dylan@pnwbakers.com">dylan@pnwbakers.com</a>> wrote:<br>
><br>
>     Quoting Jason Ekstrand (2018-03-17 09:53:13)<br>
>     > On March 16, 2018 23:36:50 Dylan Baker <<a href="mailto:dylan@pnwbakers.com">dylan@pnwbakers.com</a>> wrote:<br>
>     ><br>
>     > > Quoting Rob Clark (2018-03-16 14:25:09)<br>
>     > >> On Fri, Mar 16, 2018 at 4:30 PM, Dylan Baker <<a href="mailto:dylan@pnwbakers.com">dylan@pnwbakers.com</a>><br>
>     wrote:<br>
>     > >> > Quoting Rob Clark (2018-03-16 12:20:10)<br>
>     > >> >> On Fri, Mar 16, 2018 at 3:13 PM, Jason Ekstrand <<br>
>     <a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
>     > >> wrote:<br>
>     > >> >> > On Fri, Mar 16, 2018 at 11:53 AM, Dylan Baker <<br>
>     <a href="mailto:dylan@pnwbakers.com">dylan@pnwbakers.com</a>> wrote:<br>
>     > >> >> >><br>
>     > >> >> >> Quoting Jason Ekstrand (2018-03-16 11:38:47)<br>
>     > >> >> >> > On Fri, Mar 16, 2018 at 11:28 AM, Dylan Baker <<br>
>     <a href="mailto:dylan@pnwbakers.com">dylan@pnwbakers.com</a>><br>
>     > >> >> >> > wrote:<br>
>     > >> >> >> ><br>
>     > >> >> >> >     intr_opcodes = {<br>
>     > >> >> >> >         'nop': Intrinsic('nop', flags=[CAN_ELIMINATE]),<br>
>     > >> >> >> >         ...<br>
>     > >> >> >> >     }<br>
>     > >> >> >> ><br>
>     > >> >> >> >     I prefer this since each dictionary is clearly created<br>
>     without a<br>
>     > >> >> >> > function<br>
>     > >> >> >> >     obscuring what's actually going on. If you dislike having<br>
>     to repeat<br>
>     > >> >> >> > the<br>
>     > >> >> >> >     name you<br>
>     > >> >> >> >     could even do something like:<br>
>     > >> >> >> >     intr_opcodes = [<br>
>     > >> >> >> >         'nop': Intrinsic('nop', flags=[CAN_ELIMINATE]),<br>
>     > >> >> >> >         ...<br>
>     > >> >> >> >     ]<br>
>     > >> >> >> >     intr_opcodes = {<a href="http://i.name" rel="noreferrer" target="_blank">i.name</a>: i for i in intr_opcodes}<br>
>     > >> >> >> ><br>
>     > >> >> >> ><br>
>     > >> >> >> > I'm not sure what I think about this.  On the one hand, having<br>
>     the<br>
>     > >> >> >> > dictionary<br>
>     > >> >> >> > explicitly declared is nice.  On the other hand, in<br>
>     nir_opcodes.py we<br>
>     > >> >> >> > have a<br>
>     > >> >> >> > bunch of other helper functions we declare along the way to<br>
>     help with<br>
>     > >> >> >> > specific<br>
>     > >> >> >> > kinds of opcodes.  It's not as practical to do this if<br>
>     everything is<br>
>     > >> >> >> > inside of<br>
>     > >> >> >> > a dictionary declaration.<br>
>     > >> >> >><br>
>     > >> >> >> Why not?<br>
>     > >> >> >><br>
>     > >> >> >> def make_op(name, *args):<br>
>     > >> >> >>     return Intrinsic(name, foo='bar', *args)<br>
>     > >> >> >><br>
>     > >> >> >> intr_opcodes = [<br>
>     > >> >> >>     make_op('nop', ...),<br>
>     > >> >> >> ]<br>
>     > >> >> ><br>
>     > >> >> ><br>
>     > >> >> > Because it's nice to keep the definition of the wrapper close to<br>
>     where<br>
>     > >> it's<br>
>     > >> >> > used.<br>
>     > >> >> ><br>
>     > >> >><br>
>     > >> >> also, fwiw, I end up needing two sets (or possibly lists), a second<br>
>     > >> >> one for the builders that are generated for sysval intrinsics.. I'm<br>
>     > >> >> not entirely sure how that would work if everything was declared<br>
>     > >> >> inline instead of via helper fxns<br>
>     > >> ><br>
>     > >> > I'm missing where a helper function adds an intrinsic to more than<br>
>     one list.<br>
>     > >><br>
>     > >> system_value() adds to system_values table, after calling intrinsic()<br>
>     > >> which adds to the global table (this is the reason for the return<br>
>     > >> statement in intrinsic()<br>
>     > >><br>
>     > >> BR,<br>
>     > >> -R<br>
>     > >><br>
>     > ><br>
>     > > I don't know, maybe it's just that I really don't like side effects,<br>
>     but<br>
>     > > functions with side-effects that call functions with side-effects make<br>
>     me<br>
>     > > nervous.<br>
>     ><br>
>     > I think side effects are ok here.  This is one of those cases where we're<br>
>     > not so much writing python code as writing a tiny DSL in python for<br>
>     > declaring NIR intrinsics.  Alternatively, you can think of the<br>
>     "intrinsic"<br>
>     > function as a sort of "add this to a database" function which is<br>
>     something<br>
>     > which has fairly natural and easy to understand side effects.  In either<br>
>     > case, the focus needs to be on the NIR intrinsics being declared and the<br>
>     > details of how the python works should fade into the background.<br>
>     ><br>
><br>
>     That's the sort of logic that made the mess in mapi/glapi/gen. These<br>
>     generators<br>
>     are like the shell script thats "just a one off script, it's just a few<br>
>     lines",<br>
>     and suddenly ten people have modified it and no one understands how it<br>
>     works or<br>
>     can modify it without everything falling apart.<br>
><br>
><br>
> That is likely true. :-)  <br>
><br>
><br>
>     Code generators need to be clean<br>
>     and maintainable just like the C and C++ code that makes up mesa.<br>
>     Seriously,<br>
>     this is why I'm rewriting all of the generators in mapi/glapi/gen instead<br>
>     of<br>
>     trying to fix them to work with Khronos XML.<br>
><br>
><br>
> Yes they do and I whole-heatedly agree with your desire for cleanliness.  The<br>
> reason why this particular script gets sticky is that there are two pieces<br>
> whose cleanliness is in conflict: the list of intrinsic definitions, and the<br>
> python code which puts them into a data structure.  You are arguing for the<br>
> cleanliness of the python code over the list of declarations.  What is really<br>
> important in this file, however, is the list of declarations.  The python code<br>
> that turns those declarations into a data structure is just an implementation<br>
> detail.<br>
><br>
> Unfortunately, all of the mechanisms that have so-far been suggested to clean<br>
> up the python have one or more of the following side-effects:<br>
><br>
>  1) Duplicating names of opcodes so that they can get out-of-sync<br>
>  2) Replacing immutable objects with mutable ones (so we can add names later)<br>
>  3) Expose the underlying data structure used to store the opcodes.<br>
><br>
> The third one is interesting because, in nir_opcodes.py, I believe we did<br>
> actually change the underlying data structure at one point.  If it's exposed,<br>
> then doing so requires altering every single line of the file.<br>
><br>
> The more I think about this, the more I think that Rob's code is more-or-less<br>
> the right direction.  I'm not sure what to think about system values and agree<br>
> that adding a side-effecting wrapper for those seems wrong.  However, I think<br>
> that having declaration functions is, in this case, actually the cleanest way<br>
> to do it when you consider all of the different pieces in play.<br>
><br>
> --Jason<br>
<br>
</div></div>The side effects of side effects is *exactly* why the GLX generators are<br>
*HORRIBLE*, you can't change anything because every function has a return value<br>
and at least one side-effect. Want to alter a return value? oh, sorry that<br>
causes a function three levels down in the call chain's side effect to change<br>
and now the generated code is completely broken. At the very least I will put my<br>
foot down hard on return values and side effects.</blockquote><div><br></div><div>I think I agree with you on return values.  If we're going to use a "register an intrinsic" model, we shouldn't have magic create+register+other functions.  We need to pick and I'd like to pick side-effects and can return values.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I really don't like side<br>
effects, but pick one. And you're right, I'm asking that the python code that<br>
has to be maintained should be maintainable. I don't understand why that's such<br>
a big ask.<br></blockquote><div><br></div><div>I also want it to be maintainable.  I just don't think that<br><br></div><div>INTRINSICS = {<br></div><div>   'foo' = intrinsic('foo', ...)<br>   ...<br>}<br><br></div><div>is maintainable.<br><br></div><div>--Jason<br></div></div></div></div>