<div dir="ltr"><p dir="ltr">Thanks for the lengthy response :)</p>
<p dir="ltr">8. apr. 2015 01.52 skrev "Connor Abbott" <<a href="mailto:cwabbott0@gmail.com" target="_blank">cwabbott0@gmail.com</a>>:<br>
><br>
> Hi Thomas,<br>
><br>
> Thanks for submitting a proposal! Some comments/answers below.<br>
><br>
> On Tue, Apr 7, 2015 at 3:34 PM, Thomas Helland<br>
> <<a href="mailto:thomashelland90@gmail.com" target="_blank">thomashelland90@gmail.com</a>> wrote:<br>
> > Hi,<br>
> ><br>
> > For those that don't know I've submitted a proposal for this years GSoC.<br>
> > I've proposed to implement value range propagation and loop unrolling in<br>
> > NIR.<br>
> > Since I'm no expert on compilers I've read up on some litterature:<br>
> ><br>
> > I started with "Constant propagation with conditional branches"  (thanks<br>
> > Connor).<br>
> > This paper describes an algorithm, "sparse conditional constant<br>
> > propagation",<br>
> > that seems to be the defacto standard in compilers today.<br>
> ><br>
> > I also found the paper;<br>
> > "Accurate static branch prediction by value range propagation " (VRP).<br>
> > This describes a value range propagation implementation based on SCCP.<br>
> > (This also allows one to set heuristics to calculate educated guesses for<br>
> > the<br>
> > probability of a certain branch, but that's probably more than we're<br>
> > interested in.)<br>
><br>
> Thanks for mentioning that... I had forgotten the name of that paper.<br>
> You're right in that the branch probability stuff isn't too useful for<br>
> us. Also, it raises an important issue about back-edges from phi<br>
> nodes; they present a more sophisticated method to handle it, but I<br>
> think that for now we can just force back edges to have an infinite<br>
> range unless they're constant.<br>
><br>
> ><br>
> > There is also a GCC paper (with whatever licensing issues that may apply);<br>
> > "A propagation engine for GCC".<br>
> > They have a shared engine for doing all propagation passes.<br>
> > It handles the worklists, and the logic to traverse these.<br>
> > The implementing passes then supply callbacks to define the lattice rules.<br>
> > They reply back if the instruction was interesting or not,<br>
> > and the propagation engine basically handles the rest.<br>
> ><br>
> > Maybe that's an interesting solution? Or it might not be worth the hassle?<br>
> > We already have copy propagation, and with value range propagation<br>
> > we probably don't want separate constant propagation?<br>
> > (I'm hoping to write the pass so that it handles both constants and value<br>
> > ranges.)<br>
><br>
> Yes, copy propagation probably won't be so useful once we have value<br>
> range propagation; the former is a special case of the latter. Note<br>
> that we have a nifty way of actually doing the constant folding<br>
> (nir_constant_expressions.py and nir_constant_expressions.h), which<br>
> you should still use if all the inputs are constant.<br>
></p>
<p dir="ltr">I'll have a look at nir_constant_expressions to see what it's about.<br>
I was thinking of making a separate struct with some flags and<br>
the range of the assignment. I thought of having an is_constant<br>
flag in there to keep control of if the value is constant.<br>Or do we have a metadata system for sticking useful<br>information in that gets shared between all passes?</p>
<p dir="ltr">> > The GCC guys have used this engine to get copy propagation that propagates<br>
> > copies accross conditionals, maybe this makes such a solution more<br>
> > interesting?<br>
><br>
> I'm not so sure how useful such a general framework will be. Constant<br>
> propagation that handles back-edges seems interesting, but I'm not<br>
> sure it's worth the time to implement something this general as a<br>
> first pass.<br>
></p>
<p dir="ltr">I agree with you on this one.<br>
If there was a potential for a lot of code<br>sharing it would be more appealing.<br>But if we drop having a separate constant propagation pass<br>then I see only VRP and copy prop. as potential users.<br>That's not a large user base for a generalized framework.</p>
<p dir="ltr">> ><br>
> > Connor: I just remembered you saying something about your freedesktop<br>
> > git repo, so I poked around some and found that you have already done<br>
> > some work on VRP based on SCCP? How far did you get?<br>
><br>
> I started on it, but then I realized that the approach I was using was<br>
> too cumbersome/complicated so I don't think what I have is too useful.<br>
> Feel free to work on it yourself, although Jason and I have discussed<br>
> it so we have some ideas of how to do it. I've written a few notes on<br>
> this below that you may find useful.<br>
><br>
> - I have a branch I created while working on VRP that you'll probably<br>
> find useful: <a href="http://cgit.freedesktop.org/~cwabbott0/mesa/log/?h=nir-worklist" target="_blank">http://cgit.freedesktop.org/~cwabbott0/mesa/log/?h=nir-worklist</a><br>
> . The first two commits are already in master, but the last two should<br>
> be useful for implementing SCCP/VRP (although they'll need to be<br>
> rebased, obviously).<br>
><br>
> - There's a comment in the SCCP paper (5.3, Nodes versus Edges) that<br>
> says: "An alternative way of implementing this would be to add nodes<br>
> to the<br>
> graph and then associate an ExecutableFlag with each node. An<br>
> additional node must be inserted between any node that has more than<br>
> one immediate successor and any successor node that has more than one<br>
> immediate predecessor." <br><br>This is the method mentioned in the VRP (If I remember correctly).<br><br>> I think this procedure is what's usually<br>
> called "splitting critical edges"; in NIR, thanks to the structured<br>
> control flow, there are never any critical edges except for one edge<br>
> case you don't really have to care about too much (namely, an infinite<br>
> loop with one basic block) and therefore you can just use the basic<br>
> block worklist that I added in the branch mentioned above, rather than<br>
> a worklist of basic block edges as the paper describes.<br>
><br>
> - The reason my pass was becoming so cumbersome was because I was<br>
> trying to solve two problems at once. First, there's actually<br>
> propagating the ranges. Then, there's taking into account restrictions<br>
> on range due to branch predicates. For example, if I have something<br>
> like:<br>
><br>
> if (x > 0) {<br>
>     y = max(x, 0);<br>
> }<br>
><br>
> then since the use of x is dominated by the then-branch of the if, x<br>
> has to be greater than 0 and we can optimize it. This is a little<br>
> contrived, but we have seen things like:<br>
><br>
> if (foo)<br>
>     break;<br>
><br>
> /* ... */<br>
><br>
> if (foo)<br>
>     break;<br>
><br>
> in the wild, where we could get rid of the redundant break using this<br>
> analysis by recognizing that since the second condition is dominated<br>
> by the else-branch of the first, foo must be false there. I was trying<br>
> to handle this by storing multiple lattice entries for the same SSA<br>
> value, but it was becoming too messy. Instead, we can solve the first<br>
> problem normally, and then to solve the second problem we can create<br>
> new SSA values, using the standard SSA construction algorithm, any<br>
> time where after a certain point the range of a value is restricted<br>
> (namely, the condition of a branch or the index of an array<br>
> dereference). In the first example, we would create a new value x2:<br>
><br><br>I thnk I've seen this solution mentioned in some paper.<br>Maybe the ISRP pass mentioned below? I don't remember.<br><br>
> if (x > 0) {<br>
>     x2 = x;<br>
>     y = max(x2, 0);<br>
> }<br>
><br>
> and the VRP pass will keep track of "special" copies like the one from<br>
> x to x2 that add restrictions on the range. After everything is<br>
> finished, copy propagation and DCE will clean up the extra copies<br>
> created. There's a paper on this somewhere, but I don't quite remember<br>
> the name of it. I'm not sure if you'll be able to get to this over the<br>
> summer, but I thought I'd explain it in case you were interested.<br>
></p>
<p dir="ltr">May this paper be "Interprocedural symbolic range propagation"?<br>
Or maybe just " symbolic range propagation"?<br>
I haven't looked much at them, but looks like they might be relevant.</p>
<p dir="ltr">> ><br>
> > If we just want to make an SCCP inspired VRP pass then Connor has work in<br>
> > progress.<br>
> > Finishing that, and loop unrolling, may not be enough work for GSoC?<br>
><br>
> I'm not sure... on the one hand, there's enough here that it may take<br>
> the entire summer for you to do. On the other hand, it's possible that<br>
> you'll be able to finish it with enough time left over, and there are<br>
> plenty of other things you'd be able to do. It depends on several<br>
> factors, and no one has a crystal ball here. I'm not experienced<br>
> enough with GSoC to be able to give you a recommendation, so it would<br>
> be nice for someone more experienced to give their opinion.<br>
></p>
<p dir="ltr">That's what I struggle with. While I've done some programming<br>
projects before they have been quite small, with a large amount<br>
of hardware that needed to be made, so that was the time consuming<br>part and not the programming. Setting a realistic plan is .... hard.</p>
<p dir="ltr">> > Or maybe Connor wants to finish it of himself, and I should spend my time<br>
> > implementing some other pass instead, alongside loop unrolling?<br>
> ><br>
> > Realising Connor has partially started on this I thought it was a good<br>
> > idea to get some feedback and ideas from others (if I need to change my<br>
> > proposal)<br>
> > All suggestions, ideas and opinions are more than welcome.<br>
> > Fire at will, I'm all ears =)<br>
> ><br>
> > Regards,<br>
> > Thomas<br>
><br>
> Thanks,<br>
> Connor<br>
</p>
</div>