<div dir="ltr">Hi Kris,<div><br></div><div style>I like it. What about transforming also array.length != 0 into the unsigned test?</div><div style><br></div><div style>Regards,</div><div style>Martin.</div><div class="gmail_extra">
<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 14, 2014 at 4:57 AM, Krystal Mok <span dir="ltr">&lt;<a href="mailto:rednaxelafx@gmail.com" target="_blank">rednaxelafx@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Hi all,<br></div><div><br></div><div>I&#39;ve updated the patch again,</div>
<div>Webrev: <a href="http://cr.openjdk.java.net/~kmo/8003585/webrev.02/" target="_blank">http://cr.openjdk.java.net/~kmo/8003585/webrev.02/</a></div>
<div><br></div><div>This version slightly differs from the original equivalence patterns as stated in the bug report, in that it doesn&#39;t transform the following:</div><div>&nbsp; (x &amp; array.length) &lt; array.length</div>

<div>to:</div><div>&nbsp; array.length != 0</div><div>and instead transforms it to:</div><div>&nbsp; array.length u&gt; 0</div><div>which are semantically the same.</div><div><br></div><div>This is done to better align with the code pattern that C2 generates for array range checks, so that the logic in IfNode::Ideal() can better remove redundant range checks.</div>

<div><br></div><div>Also, I&#39;ve added one more pattern matching to transform:</div><div>&nbsp; array.length &gt; 0</div><div>to:</div><div>&nbsp; array.length u&gt; 0</div><div>(the actually code implements it inverted)</div><div>

This is safe because array lengths are always &gt;= 0, while changing the form makes them more likely to get optimized by IfNode::Ideal() later.</div><div><br></div><div>With this patch, C2 can now elide redundant range checks in the following two cases:</div>

<div><br></div><div>Case 1:</div><div>&nbsp;array[1] = array[2]; // ensures array.length &gt; 2</div><div>&nbsp;Object o = array[x &amp; (array.length - 1)];</div><div><br></div><div>Case 2:</div><div>&nbsp;if (array.length &gt; 0) { // this is a signed comparison</div>

<div>&nbsp; &nbsp;Object o = array[x &amp; (array.length - 1)];</div><div>&nbsp;}</div><div class="gmail_extra"><br></div><div class="gmail_extra">I&#39;ve tested the patch to compile java.util.HashMap.getNode(), and confirmed that redundant array bounds checks are elided (matches Case 2 above).</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Thanks,</div><div class="gmail_extra">Kris<div><div class="h5"><br><br><div class="gmail_quote">On Wed, Feb 12, 2014 at 4:50 PM, Krystal Mok <span dir="ltr">&lt;<a href="mailto:rednaxelafx@gmail.com" target="_blank">rednaxelafx@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Thanks for your reviews, Azeem and Vladimir.<div>

<br></div><div>Updated webrev here:&nbsp;<a href="http://cr.openjdk.java.net/~kmo/8003585/webrev.01/" target="_blank">http://cr.openjdk.java.net/~kmo/8003585/webrev.01/</a></div>
<div>
I removed the two signed variants, leaving only the two unsigned variants.</div><div><br></div><div>As for testing, I&#39;m not up to speed with JMH yet...</div><div>Do you think adapting the JMH benchmarks found on the StackOverflow post will do?</div>


<div><a href="http://stackoverflow.com/questions/21702939/why-the-bounds-check-doesnt-get-eliminated" target="_blank">http://stackoverflow.com/questions/21702939/why-the-bounds-check-doesnt-get-eliminated</a><br></div><div>

<br></div><div>
Thanks,</div><div>Kris</div>
</div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Feb 12, 2014 at 4:32 PM, Vladimir Kozlov <span dir="ltr">&lt;<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">We need to assign 8003585 to someone in our group to sponsor these changes and do our internal testing.<br>


<br>
Second equivalence also does not hold with x = -1:<div><br>
<br>
(x &amp; (m-1)) &lt; m, if and only if (m &gt; 0)<br>
<br></div>
because -3 &lt; -2.<br>
<br>
Which leaves equivalences only for unsigned compares.<br>
<br>
Thanks,<br>
Vladimir<div><br>
<br>
On 2/12/14 4:25 PM, Azeem Jiva wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
It looks good to me (not a Reviewer) but I&rsquo;d ask for some testing to<br>
make sure nothing got broken. &nbsp;How about a JMH micro benchmark to test<br>
the gains?<br>
<br>
<br>
--<br>
Azeem Jiva<br>
@javawithjiva<br>
<br>
On Feb 12, 2014, at 4:17 PM, Krystal Mok &lt;<a href="mailto:rednaxelafx@gmail.com" target="_blank">rednaxelafx@gmail.com</a><br></div>
&lt;mailto:<a href="mailto:rednaxelafx@gmail.com" target="_blank">rednaxelafx@gmail.com</a>&gt;<u></u>&gt; wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
Hi all,<br>
<br>
Could I get a couple of reviews for this change, please?<br>
<br>
Bug: <a href="https://bugs.openjdk.java.net/browse/JDK-8003585" target="_blank">https://bugs.openjdk.java.net/<u></u>browse/JDK-8003585</a><br>
Webrev: <a href="http://cr.openjdk.java.net/~kmo/8003585/webrev.00/" target="_blank">http://cr.openjdk.java.net/~<u></u>kmo/8003585/webrev.00/</a><br>
<br>
Note 1: Cases 2 and 4 are handled by the same code in this change.<br>
Note 2: Martin&#39;s concerns seems to hold, so the patch will need to be<br>
changed to handle that:<br>
<br>
On Wed, Feb 12, 2014 at 3:45 PM, Martin Grajcar &lt;<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a><br></div><div><div>
&lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a>&gt;&gt; wrote:<br>
&gt; I&#39;m afraid, not all equivalences listed in<br>
&gt; <a href="https://bugs.openjdk.java.net/browse/JDK-8003585" target="_blank">https://bugs.openjdk.java.net/<u></u>browse/JDK-8003585</a><br>
&gt; are right, namely the first one<br>
&gt;<br>
&gt; (x &amp; m) &lt;= m, if and only if (m &gt;= 0)<br>
&gt;<br>
&gt; Using x = -1 reduces the LHS to m &lt;= m.<br>
<br>
Description: (copied from the bug report)<br>
<br>
Integer expressions which perform bitwise and can be proven to be less<br>
than or equal to either operand, as long as the compared operand is<br>
non-negative. In other words:<br>
Case 1:<br>
&nbsp; (x &amp; m) &lt;= m, if and only if (m &gt;= 0)<br>
<br>
This means the left-hand test can be replaced by the simpler<br>
right-hand test.<br>
<br>
There are also off-by-one versions, such as:<br>
Case 2:<br>
&nbsp; (x &amp; (m-1)) &lt; m, if and only if (m &gt; 0)<br>
<br>
There are also unsigned versions:<br>
Case 3:<br>
&nbsp; (x &amp; m) u&lt;= m, always<br>
Case 4:<br>
&nbsp; (x &amp; (m-1)) u&lt; m, if and only if (m &gt; 0)<br>
<br>
The optimizer should recognize these patterns. They are common in<br>
implicitly generated range checks for power-of-two sized arrays:<br>
<br>
&nbsp; int hash = ...;<br>
&nbsp; int bucket = hash &amp; (array.length-1);<br>
&nbsp; Entry e = array[bucket];<br>
<br>
The range check is:<br>
&nbsp; (hash &amp; (array.length-1)) u&lt; array.length<br>
<br>
This check can be strength reduced to:<br>
&nbsp; array.length != 0<br>
<br>
If the array is constant, or if user code has a dominating check for<br>
an empty array, this check will go away completely.<br>
<br>
Tests:<br>
Ran some tests manually and checked that Case 1, 2 and 4 does get<br>
pattern matched. Need someone from Oracle to run JPRT and other tests<br>
appropriate.<br>
<br>
Thanks,<br>
Kris (OpenJDK username: kmo)<br>
<br>
On Wed, Feb 12, 2014 at 3:33 PM, Vladimir Kozlov<br></div></div><div>
&lt;<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a> &lt;mailto:<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@<u></u>oracle.com</a>&gt;&gt; wrote:<br>



<br>
&nbsp; &nbsp; Kris,<br>
<br>
&nbsp; &nbsp; Can you submit formal review request as changes for 8003585 with<br>
&nbsp; &nbsp; webrev on cr.openjdk?<br>
<br>
&nbsp; &nbsp; Note, you can&#39;t return return phase-&gt;intcon(1) from Ideal()<br>
&nbsp; &nbsp; because we need new node. Return ConINode::make(phase-&gt;C, 1) instead.<br>
<br>
&nbsp; &nbsp; Thanks,<br>
&nbsp; &nbsp; Vladimir<br>
<br>
<br>
&nbsp; &nbsp; On 2/12/14 3:05 PM, Krystal Mok wrote:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; Hi Vladimir,<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; Thanks for looking at it. I added the other cases and added a<br>
&nbsp; &nbsp; &nbsp; &nbsp; missing<br>
&nbsp; &nbsp; &nbsp; &nbsp; condition check.<br>
&nbsp; &nbsp; &nbsp; &nbsp; The patch is updated in place:<br></div>
&nbsp; &nbsp; &nbsp; &nbsp; <a href="https://gist.github.com/__rednaxelafx/8964030" target="_blank">https://gist.github.com/__<u></u>rednaxelafx/8964030</a><div><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://gist.github.com/rednaxelafx/8964030" target="_blank">https://gist.github.com/<u></u>rednaxelafx/8964030</a>&gt;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; Ran a few small cases on case 1 and 3 manually and the<br>
&nbsp; &nbsp; &nbsp; &nbsp; resulting IR<br>
&nbsp; &nbsp; &nbsp; &nbsp; graphs were right. I wasn&#39;t able to check the case 2 (&quot;Change<br>
&nbsp; &nbsp; &nbsp; &nbsp; ((x &amp; m)<br>
&nbsp; &nbsp; &nbsp; &nbsp; u&lt;= m) to always true&quot;) though, I don&#39;t know what Java code<br>
&nbsp; &nbsp; &nbsp; &nbsp; could be<br>
&nbsp; &nbsp; &nbsp; &nbsp; compiled into that pattern.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; Thanks,<br>
&nbsp; &nbsp; &nbsp; &nbsp; Kris<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; On Wed, Feb 12, 2014 at 2:00 PM, Vladimir Kozlov<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@<u></u>oracle.com</a>&gt;<br></div>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:vladimir.kozlov@" target="_blank">vladimir.kozlov@</a>__<a href="http://oracle.com" target="_blank">orac<u></u>le.com</a><div><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@<u></u>oracle.com</a>&gt;&gt;&gt; wrote:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Looks reasonable. Kris, you need also look for other<br>
&nbsp; &nbsp; &nbsp; &nbsp; patterns listed<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in JDK-8003585.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thanks,<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Vladimir<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; On 2/12/14 12:39 PM, Krystal Mok wrote:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Hi Martin and John,<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; I did a quick-and-dirty patch and it seems to work:<br></div>
&nbsp; &nbsp; &nbsp; &nbsp; <a href="https://gist.github.com/____rednaxelafx/8964030" target="_blank">https://gist.github.com/____<u></u>rednaxelafx/8964030</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://gist.github.com/__rednaxelafx/8964030" target="_blank">https://gist.github.com/__<u></u>rednaxelafx/8964030</a>&gt;<div><br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://gist.github.com/__rednaxelafx/8964030" target="_blank">https://gist.github.com/__<u></u>rednaxelafx/8964030</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://gist.github.com/rednaxelafx/8964030" target="_blank">https://gist.github.com/<u></u>rednaxelafx/8964030</a>&gt;&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If it looks right then I&#39;ll refactor that code a<br>
&nbsp; &nbsp; &nbsp; &nbsp; little bit and<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; send it<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in for official review.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - Kris<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; On Wed, Feb 12, 2014 at 11:17 AM, John Rose<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><u></u>&gt; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><u></u>&gt;__&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><u></u>&gt;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><br></div><div>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:john.r.rose@oracle.com" target="_blank">john.r.rose@oracle.com</a><u></u>&gt;__&gt;__&gt;&gt; wrote:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;It&#39;s totally reasonable, and is already filed as<br>
&nbsp; &nbsp; &nbsp; &nbsp; an RFE (please<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;comment on it!):<br>
<br></div>
&nbsp; &nbsp; &nbsp; &nbsp; <a href="https://bugs.openjdk.java.net/____browse/JDK-8003585" target="_blank">https://bugs.openjdk.java.net/<u></u>____browse/JDK-8003585</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://bugs.openjdk.java.net/__browse/JDK-8003585" target="_blank">https://bugs.openjdk.java.<u></u>net/__browse/JDK-8003585</a>&gt;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://bugs.openjdk.java." target="_blank">https://bugs.openjdk.java.</a>__<u></u>net/browse/JDK-8003585<div><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="https://bugs.openjdk.java.net/browse/JDK-8003585" target="_blank">https://bugs.openjdk.java.<u></u>net/browse/JDK-8003585</a>&gt;&gt;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&mdash; John<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;On Feb 12, 2014, at 9:40 AM, Martin Grajcar<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a> &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a>&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a> &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a>&gt;&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a><br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a>&gt;<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a><br></div><div><div>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;mailto:<a href="mailto:maaartinus@gmail.com" target="_blank">maaartinus@gmail.com</a>&gt;&gt;<u></u>&gt;__&gt; wrote:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Most hash tables are power-of-two sized so<br>
&nbsp; &nbsp; &nbsp; &nbsp; that they<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; can use<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;masking for the access. It looks like the<br>
&nbsp; &nbsp; &nbsp; &nbsp; bounds check<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doesn&#39;t get<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;eliminated, although it could be.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Based on the equivalence |a[x &amp; (a.length -<br>
&nbsp; &nbsp; &nbsp; &nbsp; 1)]| throws<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if and<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;only if |a.length == 0|, I&#39;m proposing this<br>
&nbsp; &nbsp; &nbsp; &nbsp; simple<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; algorithm:<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* For each array access, check if the index<br>
&nbsp; &nbsp; &nbsp; &nbsp; has been<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; computed<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;via a bitwise and.<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* If so, check if either of the operands<br>
&nbsp; &nbsp; &nbsp; &nbsp; was computed<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; as length<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;minus one.<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* If so, replace the bounds check by a<br>
&nbsp; &nbsp; &nbsp; &nbsp; zero-length check.<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;This zero-length check can then be easily<br>
&nbsp; &nbsp; &nbsp; &nbsp; moved out of<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; the loop by<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the existing optimizations.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;I hope I&#39;m not talking non-sense. For more<br>
&nbsp; &nbsp; &nbsp; &nbsp; details see<br></div></div>
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://stackoverflow.com/____questions/21702939/why-the-____bounds-check-doesnt-get-____eliminated" target="_blank">http://stackoverflow.com/____<u></u>questions/21702939/why-the-___<u></u>_bounds-check-doesnt-get-____<u></u>eliminated</a><br>



&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="http://stackoverflow.com/__questions/21702939/why-the-__bounds-check-doesnt-get-__eliminated" target="_blank">http://stackoverflow.com/__<u></u>questions/21702939/why-the-__<u></u>bounds-check-doesnt-get-__<u></u>eliminated</a>&gt;<div>


<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="http://stackoverflow.com/__questions/21702939/why-the-__bounds-check-doesnt-get-__eliminated" target="_blank">http://stackoverflow.com/__<u></u>questions/21702939/why-the-__<u></u>bounds-check-doesnt-get-__<u></u>eliminated</a><br>



&nbsp; &nbsp; &nbsp; &nbsp; &lt;<a href="http://stackoverflow.com/questions/21702939/why-the-bounds-check-doesnt-get-eliminated" target="_blank">http://stackoverflow.com/<u></u>questions/21702939/why-the-<u></u>bounds-check-doesnt-get-<u></u>eliminated</a>&gt;&gt;<br>



<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Regards,<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Martin.<br>
<br>
<br>
<br>
<br>
<br>
</div></blockquote>
<br>
</blockquote>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div></div></div></div>
</blockquote></div><br></div></div>