ac7119f0d5
Reviewed-by: kvn, chagedorn, thartmann
236 lines
8.9 KiB
Java
236 lines
8.9 KiB
Java
/*
|
|
* Copyright (c) 2023, 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.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8280126
|
|
* @compile TestDeadIrreducibleLoops.jasm
|
|
* @summary Irreducible loops have many entries, only when the last entry loses
|
|
* control from the outside does the loop die, and have to disappear.
|
|
* @run main/othervm
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoopsMain::test*
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoops::test*
|
|
* -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN
|
|
* TestDeadIrreducibleLoopsMain
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8280126
|
|
* @compile TestDeadIrreducibleLoops.jasm
|
|
* @summary Irreducible loops have many entries, only when the last entry loses
|
|
* control from the outside does the loop die, and have to disappear.
|
|
* @run main/othervm
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoopsMain::test*
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoops::test*
|
|
* -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN
|
|
* -XX:PerMethodTrapLimit=0
|
|
* TestDeadIrreducibleLoopsMain
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8280126
|
|
* @compile TestDeadIrreducibleLoops.jasm
|
|
* @summary Irreducible loops have many entries, only when the last entry loses
|
|
* control from the outside does the loop die, and have to disappear.
|
|
* @run main/othervm
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoopsMain::test*
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoops::test*
|
|
* -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN
|
|
* -Xcomp -XX:-TieredCompilation
|
|
* TestDeadIrreducibleLoopsMain
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8280126
|
|
* @compile TestDeadIrreducibleLoops.jasm
|
|
* @summary Irreducible loops have many entries, only when the last entry loses
|
|
* control from the outside does the loop die, and have to disappear.
|
|
* @run main/othervm
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoopsMain::test*
|
|
* -XX:CompileCommand=compileonly,TestDeadIrreducibleLoops::test*
|
|
* -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN
|
|
* -Xcomp -XX:-TieredCompilation
|
|
* -XX:PerMethodTrapLimit=0
|
|
* TestDeadIrreducibleLoopsMain
|
|
*/
|
|
|
|
// Note: if this test fails intermittently, then use -XX:RepeatCompilation=1000
|
|
// The tests are run in no particular order. If an earlier test fails, a later one
|
|
// may fail too and be easier to debug.
|
|
|
|
public class TestDeadIrreducibleLoopsMain {
|
|
static public void main(String[] args) {
|
|
TestDeadIrreducibleLoops t = new TestDeadIrreducibleLoops();
|
|
test_000(false, false);
|
|
t.test_001(0, 0, 0, 0);
|
|
t.test_002(-1);
|
|
t.test_003(255);
|
|
t.test_004("I am an object\n");
|
|
t.test_005(0, 0);
|
|
t.test_006(0);
|
|
t.test_007(0, 0, 0);
|
|
t.test_008(0, 0, 0);
|
|
t.test_009(0, 0, 0, 0, 0, 0, 0);
|
|
t.test_010(0, 0, 0, 0, 0);
|
|
t.test_011(0, 0, 0, 0, 0);
|
|
t.test_012a(0, 0, 0, 0, 0, 0, 0, 0);
|
|
t.test_012b(0, 0, 0, 0, 0);
|
|
t.test_013(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
t.test_014a(0, 0, 0);
|
|
t.test_014b(0, 0, 0);
|
|
int x = t.test_015a(123);
|
|
int y = t.test_015b(123);
|
|
assert x == y: "pow(3,x)";
|
|
t.test_016(0, 0, 0);
|
|
t.test_017(0, 0, 0);
|
|
t.test_018(0);
|
|
t.test_019(0, 0, 0, 0);
|
|
t.test_020(0, 0, 0, 0, 0);
|
|
t.test_021(0, 0, 0, 0, 0, 0);
|
|
t.test_022a(0, 0, 0, 0);
|
|
t.test_022b(0, 0);
|
|
t.test_023(0);
|
|
t.test_024();
|
|
test_025a(false);
|
|
test_025b(false, false);
|
|
}
|
|
|
|
public static float test_000(boolean flag1, boolean flag2) {
|
|
float ret = 1.0f;
|
|
int x = 0;
|
|
LOOP1:
|
|
for (int i = 1; i < 1000000; i *= 2) { // about 20 iterations
|
|
if (i % 5 != 0) { // SKIP1
|
|
LOOP2:
|
|
for (int j = 1; j < 1000000; j *= 2) { // about 20 iterations
|
|
if (j % 5 != 0) { // SKIP2
|
|
if (x == 0) { // eventually always false -> continue statements float out of loop
|
|
ret *= 1.0001;
|
|
if (j > 100) {
|
|
LOOP3:
|
|
for (float m = 1.0f; m < 30000.0f; m *= 1.0001f) {
|
|
// OSR starts here - should do more than 100k iterations
|
|
ret *= 0.99999f;
|
|
}
|
|
x = 1;
|
|
}
|
|
int y = 77;
|
|
for (int e = 0; e < 77; e++) {
|
|
y -= x; // empty_loop, once we know that x == 1
|
|
}
|
|
if (y == 0) {
|
|
// always true after OSR -> cut off ENTRY1 and ENTRY2
|
|
return ret;
|
|
}
|
|
ret += 0.01;
|
|
if (ret > 20000) {
|
|
ret = 7.0f;
|
|
continue LOOP1; // ENTRY1
|
|
}
|
|
// back to LOOP2 -> ENTRY2
|
|
} // end if (x == 0)
|
|
} // end SKIP2
|
|
} // end LOOP2
|
|
} // end SKIP1
|
|
} // end LOOP1
|
|
return ret;
|
|
}
|
|
|
|
static float test_025a(boolean flag) {
|
|
// Based on test_000, but much simplified.
|
|
// Irreducible loop with OSR. Inlining in irreducible loop.
|
|
float ret = 3.0f;
|
|
LOOP1:
|
|
for (long i = 1; i < 1000_000_000_000L; i *= 2) {
|
|
ret = test_025_inline(ret); // inline region
|
|
LOOP2:
|
|
for (long j = 1; j < 1000_000_000_000L; j *= 2) {
|
|
for (int e = 0; e < 77; e++) {}
|
|
if (flag) {
|
|
continue LOOP1; // ENTRY1
|
|
}
|
|
// back to LOOP2 -> ENTRY2
|
|
} // end LOOP2
|
|
} // end LOOP1
|
|
return ret;
|
|
}
|
|
|
|
static float test_025b(boolean flag1, boolean flag2) {
|
|
// Based on test_000.
|
|
// Irreducible loop with OSR. Inlining in irreducible loop.
|
|
float ret = 1.0f;
|
|
int x = 0;
|
|
LOOP1:
|
|
for (long i = 1; i < 1000_000_000_000L; i *= 2) {
|
|
ret = test_025_inline(ret);
|
|
if (i % 5 != 0) { // SKIP1
|
|
LOOP2:
|
|
for (long j = 1; j < 1000_000_000_000L; j *= 2) {
|
|
if (j % 5 != 0) { // SKIP2
|
|
if (x == 0) { // eventually always false -> continue statements float out of loop
|
|
ret *= 1.0001;
|
|
if (i > 1000_000_000L) {
|
|
LOOP3:
|
|
for (float m = 1.0f; m < 30000.0f; m *= 1.0001f) {
|
|
// OSR starts here - should do more than 100k iterations
|
|
ret *= 0.99999f;
|
|
}
|
|
x = 1;
|
|
}
|
|
int y = 77;
|
|
for (int e = 0; e < 77; e++) {
|
|
y -= x; // empty_loop, once we know that x == 1
|
|
}
|
|
if (y == 0) {
|
|
// always true after OSR -> cut off ENTRY1 and ENTRY2
|
|
return ret;
|
|
}
|
|
ret += 0.01;
|
|
if (ret > 20000) {
|
|
ret = 7.0f;
|
|
continue LOOP1; // ENTRY1
|
|
}
|
|
// back to LOOP2 -> ENTRY2
|
|
} // end if (x == 0)
|
|
} // end SKIP2
|
|
} // end LOOP2
|
|
} // end SKIP1
|
|
} // end LOOP1
|
|
return ret;
|
|
}
|
|
|
|
static float test_025_inline(float x) {
|
|
if (x >= 1.0f) {
|
|
x *= 0.5f;
|
|
} else {
|
|
x *= 2.0f;
|
|
}
|
|
// Region to merge the if
|
|
return x;
|
|
}
|
|
}
|