<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>