mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8276162: Optimise unsigned comparison pattern
Reviewed-by: thartmann, kvn
This commit is contained in:
parent
9a9a157a7d
commit
f3eb5014aa
3 changed files with 521 additions and 5 deletions
|
@ -1480,13 +1480,15 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const int cmp1_op = cmp1->Opcode();
|
||||
const int cmp2_op = cmp2->Opcode();
|
||||
|
||||
// Constant on left?
|
||||
Node *con = cmp1;
|
||||
uint op2 = cmp2->Opcode();
|
||||
// Move constants to the right of compare's to canonicalize.
|
||||
// Do not muck with Opaque1 nodes, as this indicates a loop
|
||||
// guard that cannot change shape.
|
||||
if( con->is_Con() && !cmp2->is_Con() && op2 != Op_Opaque1 &&
|
||||
if( con->is_Con() && !cmp2->is_Con() && cmp2_op != Op_Opaque1 &&
|
||||
// Because of NaN's, CmpD and CmpF are not commutative
|
||||
cop != Op_CmpD && cop != Op_CmpF &&
|
||||
// Protect against swapping inputs to a compare when it is used by a
|
||||
|
@ -1504,7 +1506,7 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
// Change "bool eq/ne (cmp (and X 16) 16)" into "bool ne/eq (cmp (and X 16) 0)".
|
||||
if (cop == Op_CmpI &&
|
||||
(_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
|
||||
cmp1->Opcode() == Op_AndI && cmp2->Opcode() == Op_ConI &&
|
||||
cmp1_op == Op_AndI && cmp2_op == Op_ConI &&
|
||||
cmp1->in(2)->Opcode() == Op_ConI) {
|
||||
const TypeInt *t12 = phase->type(cmp2)->isa_int();
|
||||
const TypeInt *t112 = phase->type(cmp1->in(2))->isa_int();
|
||||
|
@ -1518,7 +1520,7 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
// Same for long type: change "bool eq/ne (cmp (and X 16) 16)" into "bool ne/eq (cmp (and X 16) 0)".
|
||||
if (cop == Op_CmpL &&
|
||||
(_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
|
||||
cmp1->Opcode() == Op_AndL && cmp2->Opcode() == Op_ConL &&
|
||||
cmp1_op == Op_AndL && cmp2_op == Op_ConL &&
|
||||
cmp1->in(2)->Opcode() == Op_ConL) {
|
||||
const TypeLong *t12 = phase->type(cmp2)->isa_long();
|
||||
const TypeLong *t112 = phase->type(cmp1->in(2))->isa_long();
|
||||
|
@ -1529,10 +1531,41 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
}
|
||||
}
|
||||
|
||||
// Change "cmp (add X min_jint) (add Y min_jint)" into "cmpu X Y"
|
||||
// and "cmp (add X min_jint) c" into "cmpu X (c + min_jint)"
|
||||
if (cop == Op_CmpI &&
|
||||
cmp1_op == Op_AddI &&
|
||||
phase->type(cmp1->in(2)) == TypeInt::MIN) {
|
||||
if (cmp2_op == Op_ConI) {
|
||||
Node* ncmp2 = phase->intcon(java_add(cmp2->get_int(), min_jint));
|
||||
Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), ncmp2));
|
||||
return new BoolNode(ncmp, _test._test);
|
||||
} else if (cmp2_op == Op_AddI &&
|
||||
phase->type(cmp2->in(2)) == TypeInt::MIN) {
|
||||
Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), cmp2->in(1)));
|
||||
return new BoolNode(ncmp, _test._test);
|
||||
}
|
||||
}
|
||||
|
||||
// Change "cmp (add X min_jlong) (add Y min_jlong)" into "cmpu X Y"
|
||||
// and "cmp (add X min_jlong) c" into "cmpu X (c + min_jlong)"
|
||||
if (cop == Op_CmpL &&
|
||||
cmp1_op == Op_AddL &&
|
||||
phase->type(cmp1->in(2)) == TypeLong::MIN) {
|
||||
if (cmp2_op == Op_ConL) {
|
||||
Node* ncmp2 = phase->longcon(java_add(cmp2->get_long(), min_jlong));
|
||||
Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), ncmp2));
|
||||
return new BoolNode(ncmp, _test._test);
|
||||
} else if (cmp2_op == Op_AddL &&
|
||||
phase->type(cmp2->in(2)) == TypeLong::MIN) {
|
||||
Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), cmp2->in(1)));
|
||||
return new BoolNode(ncmp, _test._test);
|
||||
}
|
||||
}
|
||||
|
||||
// Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
|
||||
// The XOR-1 is an idiom used to flip the sense of a bool. We flip the
|
||||
// test instead.
|
||||
int cmp1_op = cmp1->Opcode();
|
||||
const TypeInt* cmp2_type = phase->type(cmp2)->isa_int();
|
||||
if (cmp2_type == NULL) return NULL;
|
||||
Node* j_xor = cmp1;
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8276162
|
||||
* @summary Test that unsigned comparison transformation works as intended.
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.TestUnsignedComparison
|
||||
*/
|
||||
public class TestUnsignedComparison {
|
||||
private static final String CMP_REGEX = "(\\d+(\\s){2}(" + "Cmp(I|L)" + ".*)+(\\s){2}===.*)";
|
||||
private static final String CMPU_REGEX = "(\\d+(\\s){2}(" + "Cmp(U|UL)" + ".*)+(\\s){2}===.*)";
|
||||
private static final String ADD_REGEX = "(\\d+(\\s){2}(" + "Add(I|L)" + ".*)+(\\s){2}===.*)";
|
||||
|
||||
private static final int INT_MIN = Integer.MIN_VALUE;
|
||||
private static final long LONG_MIN = Long.MIN_VALUE;
|
||||
|
||||
// Integers are sorted in unsignedly increasing order
|
||||
private static final int[] INT_DATA = {
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
0x8000_0000,
|
||||
0x8000_0001,
|
||||
0x8000_0002,
|
||||
0x8000_0003,
|
||||
0xFFFF_FFFE,
|
||||
0xFFFF_FFFF,
|
||||
};
|
||||
|
||||
// Longs are sorted in unsignedly increasing order
|
||||
private static final long[] LONG_DATA = {
|
||||
0L,
|
||||
1L,
|
||||
2L,
|
||||
3L,
|
||||
0x00000000_80000000L,
|
||||
0x00000000_FFFFFFFFL,
|
||||
0x00000001_00000000L,
|
||||
0x80000000_00000000L,
|
||||
0x80000000_00000001L,
|
||||
0x80000000_00000002L,
|
||||
0x80000000_00000003L,
|
||||
0x80000000_80000000L,
|
||||
0xFFFFFFFF_FFFFFFFEL,
|
||||
0xFFFFFFFF_FFFFFFFFL,
|
||||
};
|
||||
|
||||
// Constants to compare against, add MIN_VALUE beforehand for convenience
|
||||
private static final int CONST_INDEX = 6;
|
||||
private static final int INT_CONST = INT_DATA[CONST_INDEX] + INT_MIN;
|
||||
private static final long LONG_CONST = LONG_DATA[CONST_INDEX] + LONG_MIN;
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework framework = new TestFramework();
|
||||
framework.start();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarEQ(int x, int y) {
|
||||
return x + INT_MIN == y + INT_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarNE(int x, int y) {
|
||||
return x + INT_MIN != y + INT_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarLT(int x, int y) {
|
||||
return x + INT_MIN < y + INT_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarLE(int x, int y) {
|
||||
return x + INT_MIN <= y + INT_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarGT(int x, int y) {
|
||||
return x + INT_MIN > y + INT_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntVarGE(int x, int y) {
|
||||
return x + INT_MIN >= y + INT_MIN;
|
||||
}
|
||||
|
||||
@Run(test = {"testIntVarEQ", "testIntVarNE",
|
||||
"testIntVarLT", "testIntVarLE",
|
||||
"testIntVarGT", "testIntVarGE"})
|
||||
public void checkTestIntVar() {
|
||||
// Verify the transformation "cmp (add X min_jint) (add Y min_jint)"
|
||||
// to "cmpu X Y"
|
||||
for (int i = 0; i < INT_DATA.length; i++) {
|
||||
for (int j = 0; j < INT_DATA.length; j++) {
|
||||
Asserts.assertEquals(testIntVarEQ(INT_DATA[i], INT_DATA[j]),
|
||||
i == j);
|
||||
Asserts.assertEquals(testIntVarNE(INT_DATA[i], INT_DATA[j]),
|
||||
i != j);
|
||||
Asserts.assertEquals(testIntVarLT(INT_DATA[i], INT_DATA[j]),
|
||||
i < j);
|
||||
Asserts.assertEquals(testIntVarLE(INT_DATA[i], INT_DATA[j]),
|
||||
i <= j);
|
||||
Asserts.assertEquals(testIntVarGT(INT_DATA[i], INT_DATA[j]),
|
||||
i > j);
|
||||
Asserts.assertEquals(testIntVarGE(INT_DATA[i], INT_DATA[j]),
|
||||
i >= j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConEQ(int x) {
|
||||
return x + INT_MIN == INT_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConNE(int x) {
|
||||
return x + INT_MIN != INT_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConLT(int x) {
|
||||
return x + INT_MIN < INT_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConLE(int x) {
|
||||
return x + INT_MIN <= INT_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConGT(int x) {
|
||||
return x + INT_MIN > INT_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testIntConGE(int x) {
|
||||
return x + INT_MIN >= INT_CONST;
|
||||
}
|
||||
|
||||
@Run(test = {"testIntConEQ", "testIntConNE",
|
||||
"testIntConLT", "testIntConLE",
|
||||
"testIntConGT", "testIntConGE"})
|
||||
public void checkTestIntCon() {
|
||||
// Verify the transformation "cmp (add X min_jint) c"
|
||||
// to "cmpu X (c + min_jint)"
|
||||
for (int i = 0; i < INT_DATA.length; i++) {
|
||||
Asserts.assertEquals(testIntConEQ(INT_DATA[i]),
|
||||
i == CONST_INDEX);
|
||||
Asserts.assertEquals(testIntConNE(INT_DATA[i]),
|
||||
i != CONST_INDEX);
|
||||
Asserts.assertEquals(testIntConLT(INT_DATA[i]),
|
||||
i < CONST_INDEX);
|
||||
Asserts.assertEquals(testIntConLE(INT_DATA[i]),
|
||||
i <= CONST_INDEX);
|
||||
Asserts.assertEquals(testIntConGT(INT_DATA[i]),
|
||||
i > CONST_INDEX);
|
||||
Asserts.assertEquals(testIntConGE(INT_DATA[i]),
|
||||
i >= CONST_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarEQ(long x, long y) {
|
||||
return x + LONG_MIN == y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarNE(long x, long y) {
|
||||
return x + LONG_MIN != y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarLT(long x, long y) {
|
||||
return x + LONG_MIN < y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarLE(long x, long y) {
|
||||
return x + LONG_MIN <= y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarGT(long x, long y) {
|
||||
return x + LONG_MIN > y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongVarGE(long x, long y) {
|
||||
return x + LONG_MIN >= y + LONG_MIN;
|
||||
}
|
||||
|
||||
@Run(test = {"testLongVarEQ", "testLongVarNE",
|
||||
"testLongVarLT", "testLongVarLE",
|
||||
"testLongVarGT", "testLongVarGE"})
|
||||
public void checkTestLongVar() {
|
||||
// Verify the transformation "cmp (add X min_jlong) (add Y min_jlong)"
|
||||
// to "cmpu X Y"
|
||||
for (int i = 0; i < LONG_DATA.length; i++) {
|
||||
for (int j = 0; j < LONG_DATA.length; j++) {
|
||||
Asserts.assertEquals(testLongVarEQ(LONG_DATA[i], LONG_DATA[j]),
|
||||
i == j);
|
||||
Asserts.assertEquals(testLongVarNE(LONG_DATA[i], LONG_DATA[j]),
|
||||
i != j);
|
||||
Asserts.assertEquals(testLongVarLT(LONG_DATA[i], LONG_DATA[j]),
|
||||
i < j);
|
||||
Asserts.assertEquals(testLongVarLE(LONG_DATA[i], LONG_DATA[j]),
|
||||
i <= j);
|
||||
Asserts.assertEquals(testLongVarGT(LONG_DATA[i], LONG_DATA[j]),
|
||||
i > j);
|
||||
Asserts.assertEquals(testLongVarGE(LONG_DATA[i], LONG_DATA[j]),
|
||||
i >= j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConEQ(long x) {
|
||||
return x + LONG_MIN == LONG_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConNE(long x) {
|
||||
return x + LONG_MIN != LONG_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConLT(long x) {
|
||||
return x + LONG_MIN < LONG_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConLE(long x) {
|
||||
return x + LONG_MIN <= LONG_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConGT(long x) {
|
||||
return x + LONG_MIN > LONG_CONST;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {CMP_REGEX, ADD_REGEX})
|
||||
@IR(counts = {CMPU_REGEX, "1"})
|
||||
public boolean testLongConGE(long x) {
|
||||
return x + LONG_MIN >= LONG_CONST;
|
||||
}
|
||||
|
||||
@Run(test = {"testLongConEQ", "testLongConNE",
|
||||
"testLongConLT", "testLongConLE",
|
||||
"testLongConGT", "testLongConGE"})
|
||||
public void checkTestLongConGE() {
|
||||
// Verify the transformation "cmp (add X min_jlong) c"
|
||||
// to "cmpu X (c + min_jlong)"
|
||||
for (int i = 0; i < LONG_DATA.length; i++) {
|
||||
Asserts.assertEquals(testLongConEQ(LONG_DATA[i]),
|
||||
i == CONST_INDEX);
|
||||
Asserts.assertEquals(testLongConNE(LONG_DATA[i]),
|
||||
i != CONST_INDEX);
|
||||
Asserts.assertEquals(testLongConLT(LONG_DATA[i]),
|
||||
i < CONST_INDEX);
|
||||
Asserts.assertEquals(testLongConLE(LONG_DATA[i]),
|
||||
i <= CONST_INDEX);
|
||||
Asserts.assertEquals(testLongConGT(LONG_DATA[i]),
|
||||
i > CONST_INDEX);
|
||||
Asserts.assertEquals(testLongConGE(LONG_DATA[i]),
|
||||
i >= CONST_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
138
test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java
Normal file
138
test/micro/org/openjdk/bench/vm/compiler/UnsignedComparison.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.vm.compiler;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Fork(2)
|
||||
@State(Scope.Thread)
|
||||
public class UnsignedComparison {
|
||||
private static final int ITERATIONS = 1000;
|
||||
|
||||
private static final int CONST_OPERAND = 4;
|
||||
private static final int INT_MIN = Integer.MIN_VALUE;
|
||||
private static final long LONG_MIN = Long.MIN_VALUE;
|
||||
|
||||
int arg0 = 0, arg1 = 4;
|
||||
|
||||
@Setup(Level.Invocation)
|
||||
public void toggle() {
|
||||
arg0 = (arg0 + 1) & 7;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intVarDirect(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(arg0 + INT_MIN < arg1 + INT_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intVarLibLT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Integer.compareUnsigned(arg0, arg1) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intVarLibGT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Integer.compareUnsigned(arg0, arg1) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intConDirect(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(arg0 + INT_MIN < CONST_OPERAND + INT_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intConLibLT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Integer.compareUnsigned(arg0, CONST_OPERAND) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void intConLibGT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Integer.compareUnsigned(arg0, CONST_OPERAND) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longVarDirect(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(arg0 + LONG_MIN < arg1 + LONG_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longVarLibLT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Long.compareUnsigned(arg0, arg1) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longVarLibGT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Long.compareUnsigned(arg0, arg1) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longConDirect(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(arg0 + LONG_MIN < CONST_OPERAND + LONG_MIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longConLibLT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Long.compareUnsigned(arg0, CONST_OPERAND) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void longConLibGT(Blackhole bh) {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
bh.consume(Long.compareUnsigned(arg0, CONST_OPERAND) > 0);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue