<div dir="ltr">On 1 March 2013 02:02, Aras Pranckevicius <span dir="ltr"><<a href="mailto:aras@unity3d.com" target="_blank">aras@unity3d.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<div><br></div><div>opt_constant_variable was marking a variable as constant as long as there was exactly one constant assignment to it, but did not take into account that this assignment might be in a dynamic branch or a loop.</div>
<div><br></div><div>Was happening on a fragment shader like this:</div><div><br></div><div><div>uniform float mode;</div><div>float func (float c) {</div><div> if (mode == 2.0)</div><div> return c; // was returning 0.1 after optimization!</div>
<div> if (mode == 3.0)</div><div> <span style="white-space:pre-wrap"> </span>discard;</div><div> if (mode == 10.0)</div><div> c = 0.1;</div><div> return c;</div><div>}</div><div>void main() {</div>
<div> vec4 c = gl_FragCoord;</div><div> c.x = func(c.x);</div><div> gl_FragColor = c;</div><div>}</div><div><br><br>Now, looking further this optimization pass should also not mark variables as const if there was a dereference of them before that first assignment. I had code to do this (a hashtable that would track dereferences before assignment is done). But couldn't come up with a test case that would break the whole set of optimizations that Mesa does (lower jumps, or inlining, ... were getting in the way and hide the bug).</div>
</div></blockquote><div><br></div><div>I'm not sure I agree with this. The real problem with the example code you showed above is that there's an implicit write to the variable c at the top of the function, so c is not in fact constant--it's written twice. What we should really do is modify the optimization pass so that it's aware of the implicit write that happens in "in" and "inout" function args.<br>
<br></div><div>If we resolve the implicit write issue, there should be no harm in marking variables as const if there's a dereference of them before the first assignment, because a dereference of a variable before the first assignment is undefined.<br>
<br></div><div>I'm also not certain I like the idea of disabling the optimization in cases where the assignment is in a dynamic branch or a loop. It misses out, for instance, on the opportunity to optimize this code:<br>
<br></div><div>uniform int u;<br><br></div><div>void main()<br>{<br></div><div> float c;<br></div><div> for (int i = 0; i < u; i++) {<br></div><div> c = 0.5;<br> ...<br> }<br><br></div><div> /* It should be fine to constant-fold c in the code below, since<br>
</div><div> * it is guaranteed to be == 0.5 or undefined, depending on<br></div><div> * the value of u.<br> */<br></div><div> gl_FragColor = vec4(c);<br>}<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><span class="HOEnZb"><font color="#888888">
<div><br></div><div><br></div>-- <br>Aras Pranckevičius<br>work: <a href="http://unity3d.com" target="_blank">http://unity3d.com</a><br>home: <a href="http://aras-p.info" target="_blank">http://aras-p.info</a>
<br><br></font></span></div>
<br>_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
<br></blockquote></div><br></div></div>