Skip to content

Commit 21e7402

Browse files
Hui ShiNils Eliasson
authored andcommitted
8263707: C1 RangeCheckEliminator support constant array and NewMultiArray
Reviewed-by: thartmann, neliasso
1 parent 2ad6f2d commit 21e7402

File tree

3 files changed

+164
-3
lines changed

3 files changed

+164
-3
lines changed

src/hotspot/share/c1/c1_Canonicalizer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -242,10 +242,15 @@ void Canonicalizer::do_ArrayLength (ArrayLength* x) {
242242
// with same value Otherwise a Constant is live over multiple
243243
// blocks without being registered in a state array.
244244
Constant* length;
245+
NewMultiArray* nma;
245246
if (na->length() != NULL &&
246247
(length = na->length()->as_Constant()) != NULL) {
247248
assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
248249
set_constant(length->type()->as_IntConstant()->value());
250+
} else if ((nma = x->array()->as_NewMultiArray()) != NULL &&
251+
(length = nma->dims()->at(0)->as_Constant()) != NULL) {
252+
assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
253+
set_constant(length->type()->as_IntConstant()->value());
249254
}
250255

251256
} else if ((ct = x->array()->as_Constant()) != NULL) {

src/hotspot/share/c1/c1_GraphBuilder.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,8 +984,10 @@ void GraphBuilder::load_indexed(BasicType type) {
984984
Value array = apop();
985985
Value length = NULL;
986986
if (CSEArrayLength ||
987+
(array->as_Constant() != NULL) ||
987988
(array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
988-
(array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
989+
(array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant()) ||
990+
(array->as_NewMultiArray() && array->as_NewMultiArray()->dims()->at(0)->type()->is_constant())) {
989991
length = append(new ArrayLength(array, state_before));
990992
}
991993
push(as_ValueType(type), append(new LoadIndexed(array, index, length, type, state_before)));
@@ -1001,8 +1003,10 @@ void GraphBuilder::store_indexed(BasicType type) {
10011003
Value array = apop();
10021004
Value length = NULL;
10031005
if (CSEArrayLength ||
1006+
(array->as_Constant() != NULL) ||
10041007
(array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
1005-
(array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
1008+
(array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant()) ||
1009+
(array->as_NewMultiArray() && array->as_NewMultiArray()->dims()->at(0)->type()->is_constant())) {
10061010
length = append(new ArrayLength(array, state_before));
10071011
}
10081012
ciType* array_type = array->declared_type();
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8263707
27+
* @summary Test range check for constant array and NewMultiArray is removed properly
28+
* @requires vm.debug == true & vm.compiler1.enabled
29+
*
30+
* @library /test/lib
31+
* @run main/othervm compiler.c1.TestRangeCheckEliminated
32+
*
33+
* @author Hui Shi
34+
*/
35+
36+
package compiler.c1;
37+
38+
import jdk.test.lib.Asserts;
39+
import jdk.test.lib.process.OutputAnalyzer;
40+
import jdk.test.lib.process.ProcessTools;
41+
42+
public class TestRangeCheckEliminated {
43+
static final String eliminated = "can be fully eliminated";
44+
public static void main(String[] args) throws Throwable {
45+
boolean error = false;
46+
String[] procArgs = new String[] {
47+
"-XX:CompileCommand=compileonly,*test_constant_array::constant_array_rc",
48+
"-XX:TieredStopAtLevel=1",
49+
"-XX:+TraceRangeCheckElimination",
50+
"-XX:-BackgroundCompilation",
51+
"compiler.c1.TestRangeCheckEliminated$test_constant_array"
52+
};
53+
54+
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs);
55+
String output = new OutputAnalyzer(pb.start()).getOutput();
56+
// should have 2 "can be fully eliminated"
57+
System.out.println(output);
58+
if ((output.split(eliminated, -1).length - 1) == 2) {
59+
System.out.println("test_constant_array pass");
60+
} else {
61+
System.out.println("test_constant_array fail");
62+
error = true;
63+
}
64+
65+
procArgs = new String[] {
66+
"-XX:CompileCommand=compileonly,*test_multi_constant_array::multi_constant_array_rc",
67+
"-XX:TieredStopAtLevel=1",
68+
"-XX:+TraceRangeCheckElimination",
69+
"-XX:-BackgroundCompilation",
70+
"compiler.c1.TestRangeCheckEliminated$test_multi_constant_array"
71+
};
72+
73+
pb = ProcessTools.createJavaProcessBuilder(procArgs);
74+
output = new OutputAnalyzer(pb.start()).getOutput();
75+
// should have 1 "can be fully eliminated"
76+
System.out.println(output);
77+
if ((output.split(eliminated, -1).length - 1) == 1) {
78+
System.out.println("test_multi_constant_array pass");
79+
} else {
80+
System.out.println("test_multi_constant_array fail");
81+
error = true;
82+
}
83+
84+
procArgs = new String[] {
85+
"-XX:CompileCommand=compileonly,*test_multi_new_array::multi_new_array_rc",
86+
"-XX:TieredStopAtLevel=1",
87+
"-XX:+TraceRangeCheckElimination",
88+
"-XX:-BackgroundCompilation",
89+
"compiler.c1.TestRangeCheckEliminated$test_multi_new_array"
90+
};
91+
92+
pb = ProcessTools.createJavaProcessBuilder(procArgs);
93+
output = new OutputAnalyzer(pb.start()).getOutput();
94+
// should have 2 "can be fully eliminated"
95+
System.out.println(output);
96+
if ((output.split(eliminated, -1).length - 1) == 2) {
97+
System.out.println("test_multi_new_array pass");
98+
} else {
99+
System.out.println("test_multi_new_array fail");
100+
error = true;
101+
}
102+
103+
if (error) {
104+
throw new InternalError();
105+
}
106+
}
107+
108+
public static class test_constant_array {
109+
static final int constant_array[] =
110+
{50,60,55,67,70,62,65,70,70,81,72,66,77,80,69};
111+
static void constant_array_rc() {
112+
constant_array[1] += 5;
113+
}
114+
115+
public static void main(String[] args) {
116+
for(int i = 0; i < 1_000; i++) {
117+
constant_array_rc();
118+
}
119+
}
120+
}
121+
122+
public static class test_multi_constant_array {
123+
static final int constant_multi_array[][] = {
124+
{50,60,55,67,70}, {62,65,70,70,81}, {72,66,77,80,69}};
125+
static void multi_constant_array_rc() {
126+
constant_multi_array[2][3] += 5;
127+
}
128+
129+
public static void main(String[] args) {
130+
for(int i = 0; i < 1_000; i++) {
131+
multi_constant_array_rc();
132+
}
133+
}
134+
}
135+
136+
public static class test_multi_new_array {
137+
static void foo(int i) {}
138+
static void multi_new_array_rc(int index) {
139+
int na[] = new int[800];
140+
int nma[][] = new int[600][2];
141+
nma[20][1] += 5; // optimize rc on NewMultiArray first dimension
142+
nma[index][0] = 0; // index < 600 after this statement
143+
foo(na[index]); // index must < 800, remove rc
144+
}
145+
146+
public static void main(String[] args) {
147+
for(int i = 0; i < 600; i++) {
148+
multi_new_array_rc(i);
149+
}
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)