Request for Reviews (S): JDK-8003585 strength reduce or eliminate range checks for power-of-two sized arrays (Was: Re: A simple optimization proposal)
Vladimir Kozlov
vladimir.kozlov at oracle.com
Fri Feb 14 15:27:19 PST 2014
Changes are fine now.
I am mostly concern about correctness of optimization and not that range
check is folded. But any test is good so, please, add it.
For foo*() method you can also compare returned value with value from
array's element it should read.
Thanks,
Vladimir
On 2/14/14 2:47 PM, Krystal Mok wrote:
> Hi Vladimir,
>
> Thanks for catching it. Another one of the left overs. But it's
> interesting that it's only missing a chance to do the transformation
> earlier; the expected optimizations were still performed by C2 in a
> later phase even when I got that line wrong...so I didn't notice I
> missed a place.
>
> Webrev updated in place again.
>
> The test that I used locally to verify the generated code patterns was:
>
> import java.util.*;
>
> public class TestArrayRangeCheck {
> private static Object foo1(Object[] a, int x) throws Exception {
> if (a.length == 0) throw new Exception();
> return a[x & (a.length - 1)];
> }
>
> private static Object foo2(Object[] a, int x) throws Exception {
> a[1] = a[2];
> return a[(a.length - 1) & x];
> }
>
> private static Object foo3(Object[] a, int x) throws Exception {
> if (a.length != 0) {
> return a[x & (a.length - 1)];
> }
> return null;
> }
>
> private static Object foo4(Object[] a, int x) throws Exception {
> if (a.length > 0) {
> return a[x & (a.length - 1)];
> }
> return null;
> }
> public static void main(String[] args) throws Exception {
> foo1(a, 6);
> foo1(a, 6);
> foo2(a, 6);
> foo2(a, 6);
> foo3(a, 6);
> foo3(a, 6);
> foo4(a, 6);
> foo4(a, 6);
> HashMap<String, Integer> map = new HashMap<>();
> String[] strs = new String[] {
> "alpha", "beta", "charlie", "delta", "echo", "foxtrot", "golf",
> "helios"
> };
> for (String s : strs) {
> map.put(s, s.length());
> }
> for (int i = 0; i < 100; i++) {
> int index = i % strs.length;
> String key = strs[index];
> int len = map.get(key);
> if (len != key.length()) throw new Exception("unexpected
> HashMap.getNode");
> }
>
> System.in.read();
> }
> }
>
> The "foo" methods were for manual inspection of the generated code, and
> the big loop in main() was to verify HashMap.getNode() still runs
> correctly after compilation.
>
> The command to run the test was:
>
> java -XX:CompileCommand="compileonly java/util/HashMap get*"
> -XX:CompileCommand="dontinline java/util/HashMap getNode"
> -XX:CompileCommand="compileonly TestArrayRangeCheck foo*"
> -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:CompileThreshold=6
> -XX:PrintIdealGraphLevel=4 -XX:PrintIdealGraphFile=ideal_hash.xml
> -XX:+PrintCompilation -XX:+PrintAssembly TestArrayRangeCheck
>
> If that's the kind of test that you're looking for, then I can
> rename/refactor the code a little bit and fit it into HotSpot's unit test.
>
> Thanks,
> Kris
>
>
>
> On Fri, Feb 14, 2014 at 11:59 AM, Vladimir Kozlov
> <vladimir.kozlov at oracle.com <mailto:vladimir.kozlov at oracle.com>> wrote:
>
> I found a problem:
>
> 1231 Node* ncmp = r->Opcode() == Op_LoadRange
>
> should be
>
> 1231 Node* ncmp = cmp2->Opcode() == Op_LoadRange
>
> because r->Opcode() == Op_AddI
>
> Kris, can you also add a test to verify correctness of these
> transformations?
>
> Thanks,
> Vlaidmir
>
>
> On 2/14/14 11:48 AM, Vladimir Kozlov wrote:
>
> I assigned it to Nils, he will sponsor these changes.
> We need to do more testing than just JPRT before the push.
>
> Thanks,
> Vladimir
>
> On 2/14/14 11:16 AM, Krystal Mok wrote:
>
> Hi Vladimir,
>
> Thank you for your reviews, Vladimir.
>
> I've removed the bogus comment and updated the webrev in place:
> http://cr.openjdk.java.net/~__kmo/8003585/webrev.02/
> <http://cr.openjdk.java.net/~kmo/8003585/webrev.02/>
>
> Could someone on the compiler team run JPRT tests and push
> for me?
>
> Thanks,
> Kris
>
> On Fri, Feb 14, 2014 at 11:10 AM, Vladimir Kozlov
> <vladimir.kozlov at oracle.com
> <mailto:vladimir.kozlov at oracle.com>
> <mailto:vladimir.kozlov at __oracle.com
> <mailto:vladimir.kozlov at oracle.com>>> wrote:
>
> Hi Kris,
>
> Changes are good.
>
> Next comment does not describe the following
> optimization correctly:
>
> + // Integer expressions which perform bitwise and can
> be proven to
> + // be less than or equal (unsigned) to either
> operand, as long
> as the
> + // compared operand is non-negative.
>
> originally it was for "(x & m) <= m, if and only if (m
> >= 0)".
>
> Thanks,
> Vladimir
>
>
> On 2/13/14 7:57 PM, Krystal Mok wrote:
>
> Hi all,
>
> I've updated the patch again,
> Webrev:
> http://cr.openjdk.java.net/~____kmo/8003585/webrev.02/
> <http://cr.openjdk.java.net/~__kmo/8003585/webrev.02/>
>
> <http://cr.openjdk.java.net/~__kmo/8003585/webrev.02/
> <http://cr.openjdk.java.net/~kmo/8003585/webrev.02/>>
>
> This version slightly differs from the original
> equivalence
> patterns as
> stated in the bug report, in that it doesn't
> transform the
> following:
> (x & array.length) < array.length
> to:
> array.length != 0
> and instead transforms it to:
> array.length u> 0
> which are semantically the same.
>
> 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.
>
> Also, I've added one more pattern matching to
> transform:
> array.length > 0
> to:
> array.length u> 0
> (the actually code implements it inverted)
> This is safe because array lengths are always >= 0,
> while
> changing the
> form makes them more likely to get optimized by
> IfNode::Ideal()
> later.
>
> With this patch, C2 can now elide redundant range
> checks in the
> following two cases:
>
> Case 1:
> array[1] = array[2]; // ensures array.length > 2
> Object o = array[x & (array.length - 1)];
>
> Case 2:
> if (array.length > 0) { // this is a signed
> comparison
> Object o = array[x & (array.length - 1)];
> }
>
> I've tested the patch to compile
> java.util.HashMap.getNode(), and
> confirmed that redundant array bounds checks are
> elided (matches
> Case 2
> above).
>
> Thanks,
> Kris
>
>
More information about the hotspot-compiler-dev
mailing list