blob: d5111b0c142fa43587a03694a9b50c73140a8cf6 [file] [log] [blame]
Aart Bik22af3be2015-09-10 12:50:58 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Test on loop optimizations.
19//
20public class Main {
21
22 static int sResult;
23
24 //
Aart Bik9401f532015-09-28 16:25:56 -070025 // Various sequence variables used in bound checks.
Aart Bik22af3be2015-09-10 12:50:58 -070026 //
27
28 /// CHECK-START: int Main.linear(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080029 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080030 //
Aart Bik22af3be2015-09-10 12:50:58 -070031 /// CHECK-START: int Main.linear(int[]) BCE (after)
32 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080033 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070034 private static int linear(int[] x) {
35 int result = 0;
36 for (int i = 0; i < x.length; i++) {
37 result += x[i];
38 }
39 return result;
40 }
41
42 /// CHECK-START: int Main.linearDown(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080043 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080044 //
Aart Bik22af3be2015-09-10 12:50:58 -070045 /// CHECK-START: int Main.linearDown(int[]) BCE (after)
46 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080047 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070048 private static int linearDown(int[] x) {
49 int result = 0;
50 for (int i = x.length - 1; i >= 0; i--) {
51 result += x[i];
52 }
53 return result;
54 }
55
56 /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080057 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080058 //
Aart Bik22af3be2015-09-10 12:50:58 -070059 /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
60 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080061 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070062 private static int linearObscure(int[] x) {
63 int result = 0;
64 for (int i = x.length - 1; i >= 0; i--) {
65 int k = i + 5;
66 result += x[k - 5];
67 }
68 return result;
69 }
70
Aart Bikf475bee2015-09-16 12:50:25 -070071 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080072 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080073 //
Aart Bikf475bee2015-09-16 12:50:25 -070074 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
75 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080076 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -070077 private static int linearVeryObscure(int[] x) {
78 int result = 0;
79 for (int i = 0; i < x.length; i++) {
80 int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
81 result += x[k - 5];
82 }
83 return result;
84 }
85
Aart Bik7d57d7f2015-12-09 14:39:48 -080086 /// CHECK-START: int Main.hiddenStride(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080087 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080088 //
89 /// CHECK-START: int Main.hiddenStride(int[]) BCE (after)
90 /// CHECK-NOT: BoundsCheck
91 /// CHECK-NOT: Deoptimize
92 static int hiddenStride(int[] a) {
93 int result = 0;
94 for (int i = 1; i <= 1; i++) {
95 // Obscured unit stride.
96 for (int j = 0; j < a.length; j += i) {
97 result += a[j];
98 }
99 }
100 return result;
101 }
102
Aart Bik22af3be2015-09-10 12:50:58 -0700103 /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800104 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800105 //
Aart Bik22af3be2015-09-10 12:50:58 -0700106 /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
107 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800108 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700109 private static int linearWhile(int[] x) {
110 int i = 0;
111 int result = 0;
112 while (i < x.length) {
113 result += x[i++];
114 }
115 return result;
116 }
117
Aart Bikf475bee2015-09-16 12:50:25 -0700118 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800119 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800120 //
Aart Bikf475bee2015-09-16 12:50:25 -0700121 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
122 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800123 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700124 private static int linearThreeWayPhi(int[] x) {
125 int result = 0;
126 for (int i = 0; i < x.length; ) {
127 if (x[i] == 5) {
128 i++;
129 continue;
130 }
131 result += x[i++];
132 }
133 return result;
134 }
135
136 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800137 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800138 //
Aart Bikf475bee2015-09-16 12:50:25 -0700139 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
140 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800141 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700142 private static int linearFourWayPhi(int[] x) {
143 int result = 0;
144 for (int i = 0; i < x.length; ) {
145 if (x[i] == 5) {
146 i++;
147 continue;
148 } else if (x[i] == 6) {
149 i++;
150 result += 7;
151 continue;
152 }
153 result += x[i++];
154 }
155 return result;
156 }
157
Aart Bik22af3be2015-09-10 12:50:58 -0700158 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800159 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800160 //
Aart Bik22af3be2015-09-10 12:50:58 -0700161 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
162 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800163 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700164 private static int wrapAroundThenLinear(int[] x) {
165 // Loop with wrap around (length - 1, 0, 1, 2, ..).
166 int w = x.length - 1;
167 int result = 0;
168 for (int i = 0; i < x.length; i++) {
169 result += x[w];
170 w = i;
171 }
172 return result;
173 }
174
Aart Bikf475bee2015-09-16 12:50:25 -0700175 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800176 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800177 //
Aart Bikf475bee2015-09-16 12:50:25 -0700178 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
179 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800180 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700181 private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
182 // Loop with wrap around (length - 1, 0, 1, 2, ..).
183 int w = x.length - 1;
184 int result = 0;
185 for (int i = 0; i < x.length; ) {
186 if (x[w] == 1) {
187 w = i++;
188 continue;
189 }
190 result += x[w];
191 w = i++;
192 }
193 return result;
194 }
195
Aart Bik22af3be2015-09-10 12:50:58 -0700196 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800197 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800198 //
Aart Bik22af3be2015-09-10 12:50:58 -0700199 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
200 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800201 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700202 private static int[] linearWithParameter(int n) {
203 int[] x = new int[n];
204 for (int i = 0; i < n; i++) {
205 x[i] = i;
206 }
207 return x;
208 }
209
Aart Bikf475bee2015-09-16 12:50:25 -0700210 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800211 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800212 //
Aart Bikf475bee2015-09-16 12:50:25 -0700213 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
214 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800215 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700216 private static int[] linearCopy(int x[]) {
217 int n = x.length;
218 int y[] = new int[n];
219 for (int i = 0; i < n; i++) {
220 y[i] = x[i];
221 }
222 return y;
223 }
224
Aart Bik4a342772015-11-30 10:17:46 -0800225 /// CHECK-START: int Main.linearByTwo(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800226 /// CHECK-DAG: BoundsCheck
227 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800228 //
Aart Bik4a342772015-11-30 10:17:46 -0800229 /// CHECK-START: int Main.linearByTwo(int[]) BCE (after)
230 /// CHECK-NOT: BoundsCheck
231 /// CHECK-NOT: Deoptimize
232 private static int linearByTwo(int x[]) {
233 int n = x.length / 2;
234 int result = 0;
235 for (int i = 0; i < n; i++) {
236 int ii = i << 1;
237 result += x[ii];
238 result += x[ii + 1];
239 }
240 return result;
241 }
242
243 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800244 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800245 //
Aart Bik4a342772015-11-30 10:17:46 -0800246 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (after)
247 /// CHECK-NOT: BoundsCheck
248 /// CHECK-NOT: Deoptimize
249 private static int linearByTwoSkip1(int x[]) {
250 int result = 0;
251 for (int i = 0; i < x.length / 2; i++) {
252 result += x[2 * i];
253 }
254 return result;
255 }
256
257 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800258 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800259 //
Aart Bik4a342772015-11-30 10:17:46 -0800260 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800261 /// CHECK-DAG: BoundsCheck
262 //
263 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800264 /// CHECK-NOT: Deoptimize
265 private static int linearByTwoSkip2(int x[]) {
266 int result = 0;
267 // This case is not optimized.
268 for (int i = 0; i < x.length; i+=2) {
269 result += x[i];
270 }
271 return result;
272 }
273
Aart Bik22af3be2015-09-10 12:50:58 -0700274 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800275 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800276 //
Aart Bik22af3be2015-09-10 12:50:58 -0700277 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
278 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800279 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700280 private static int linearWithCompoundStride() {
281 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
282 int result = 0;
283 for (int i = 0; i <= 12; ) {
284 i++;
285 result += x[i];
286 i++;
287 }
288 return result;
289 }
290
291 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800292 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800293 //
Aart Bik22af3be2015-09-10 12:50:58 -0700294 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
295 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800296 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700297 private static int linearWithLargePositiveStride() {
298 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
299 int result = 0;
300 int k = 0;
301 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700302 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700303 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
304 result += x[k++];
305 }
306 return result;
307 }
308
309 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800310 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800311 //
Aart Bik22af3be2015-09-10 12:50:58 -0700312 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800313 /// CHECK-DAG: BoundsCheck
314 //
315 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800316 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700317 private static int linearWithVeryLargePositiveStride() {
318 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
319 int result = 0;
320 int k = 0;
321 // Range analysis conservatively bails due to potential of wrap-around
322 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700323 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700324 result += x[k++];
325 }
326 return result;
327 }
328
329 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800330 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800331 //
Aart Bik22af3be2015-09-10 12:50:58 -0700332 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
333 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800334 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700335 private static int linearWithLargeNegativeStride() {
336 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
337 int result = 0;
338 int k = 0;
339 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700340 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700341 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
342 result += x[k++];
343 }
344 return result;
345 }
346
347 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800348 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800349 //
Aart Bik22af3be2015-09-10 12:50:58 -0700350 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800351 /// CHECK-DAG: BoundsCheck
352 //
353 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800354 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700355 private static int linearWithVeryLargeNegativeStride() {
356 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
357 int result = 0;
358 int k = 0;
359 // Range analysis conservatively bails due to potential of wrap-around
360 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700361 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700362 result += x[k++];
363 }
364 return result;
365 }
366
Aart Bik9401f532015-09-28 16:25:56 -0700367 /// CHECK-START: int Main.linearForNEUp() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800368 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800369 //
Aart Bik9401f532015-09-28 16:25:56 -0700370 /// CHECK-START: int Main.linearForNEUp() BCE (after)
Aart Bikf475bee2015-09-16 12:50:25 -0700371 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800372 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700373 private static int linearForNEUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700374 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
375 int result = 0;
376 for (int i = 0; i != 10; i++) {
377 result += x[i];
378 }
379 return result;
380 }
381
Aart Bik9401f532015-09-28 16:25:56 -0700382 /// CHECK-START: int Main.linearForNEDown() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800383 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800384 //
Aart Bik9401f532015-09-28 16:25:56 -0700385 /// CHECK-START: int Main.linearForNEDown() BCE (after)
386 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800387 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700388 private static int linearForNEDown() {
389 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
390 int result = 0;
391 for (int i = 9; i != -1; i--) {
392 result += x[i];
393 }
394 return result;
395 }
396
Aart Bik358af832016-02-24 14:17:53 -0800397 /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (before)
398 /// CHECK-DAG: BoundsCheck
399 //
400 /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (after)
401 /// CHECK-NOT: BoundsCheck
402 /// CHECK-NOT: Deoptimize
403 private static int linearForNEArrayLengthUp(int[] x) {
404 int result = 0;
405 for (int i = 0; i != x.length; i++) {
406 result += x[i];
407 }
408 return result;
409 }
410
411 /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (before)
412 /// CHECK-DAG: BoundsCheck
413 //
414 /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (after)
415 /// CHECK-NOT: BoundsCheck
416 /// CHECK-NOT: Deoptimize
417 private static int linearForNEArrayLengthDown(int[] x) {
418 int result = 0;
419 for (int i = x.length - 1; i != -1; i--) {
420 result += x[i];
421 }
422 return result;
423 }
424
Aart Bik9401f532015-09-28 16:25:56 -0700425 /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800426 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800427 //
Aart Bik9401f532015-09-28 16:25:56 -0700428 /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
429 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800430 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700431 private static int linearDoWhileUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700432 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
433 int result = 0;
434 int i = 0;
Aart Bikf475bee2015-09-16 12:50:25 -0700435 do {
436 result += x[i++];
437 } while (i < 10);
438 return result;
439 }
440
Aart Bik9401f532015-09-28 16:25:56 -0700441 /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800442 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800443 //
Aart Bik9401f532015-09-28 16:25:56 -0700444 /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
445 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800446 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700447 private static int linearDoWhileDown() {
448 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
449 int result = 0;
450 int i = 9;
451 do {
452 result += x[i--];
453 } while (0 <= i);
454 return result;
455 }
456
Aart Bikf475bee2015-09-16 12:50:25 -0700457 /// CHECK-START: int Main.linearShort() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800458 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800459 //
Aart Bikf475bee2015-09-16 12:50:25 -0700460 /// CHECK-START: int Main.linearShort() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800461 /// CHECK-DAG: BoundsCheck
462 //
463 /// CHECK-START: int Main.linearShort() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800464 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700465 private static int linearShort() {
466 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
467 int result = 0;
468 // TODO: make this work
469 for (short i = 0; i < 10; i++) {
470 result += x[i];
471 }
472 return result;
473 }
474
Aart Bik4a342772015-11-30 10:17:46 -0800475 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800476 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800477 //
Aart Bik4a342772015-11-30 10:17:46 -0800478 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after)
479 /// CHECK-NOT: BoundsCheck
480 /// CHECK-NOT: Deoptimize
481 private static int invariantFromPreLoop(int[] x, int y) {
482 int result = 0;
483 // Strange pre-loop that sets upper bound.
484 int hi;
485 while (true) {
486 y = y % 3;
487 hi = x.length;
488 if (y != 123) break;
489 }
490 for (int i = 0; i < hi; i++) {
491 result += x[i];
492 }
493 return result;
494 }
495
Aart Bikb738d4f2015-12-03 11:23:35 -0800496 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800497 /// CHECK-DAG: BoundsCheck
498 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800499 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800500 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after)
501 /// CHECK-NOT: BoundsCheck
Aart Bik97412c922016-02-19 20:14:38 -0800502 // TODO: also CHECK-NOT: Deoptimize, see b/27151190
Aart Bikb738d4f2015-12-03 11:23:35 -0800503 private static void linearTriangularOnTwoArrayLengths(int n) {
504 int[] a = new int[n];
505 for (int i = 0; i < a.length; i++) {
506 int[] b = new int[i];
507 for (int j = 0; j < b.length; j++) {
508 // Need to know j < b.length < a.length for static bce.
509 a[j] += 1;
510 // Need to know just j < b.length for static bce.
511 b[j] += 1;
512 }
513 verifyTriangular(a, b, i, n);
514 }
515 }
516
517 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800518 /// CHECK-DAG: BoundsCheck
519 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800520 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800521 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (after)
522 /// CHECK-NOT: BoundsCheck
Aart Bikb738d4f2015-12-03 11:23:35 -0800523 /// CHECK-NOT: Deoptimize
524 private static void linearTriangularOnOneArrayLength(int n) {
525 int[] a = new int[n];
526 for (int i = 0; i < a.length; i++) {
527 int[] b = new int[i];
528 for (int j = 0; j < i; j++) {
529 // Need to know j < i < a.length for static bce.
530 a[j] += 1;
531 // Need to know just j < i for static bce.
532 b[j] += 1;
533 }
534 verifyTriangular(a, b, i, n);
535 }
536 }
537
538 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800539 /// CHECK-DAG: BoundsCheck
540 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800541 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800542 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after)
543 /// CHECK-NOT: BoundsCheck
Aart Bik97412c922016-02-19 20:14:38 -0800544 // TODO: also CHECK-NOT: Deoptimize, see b/27151190
Aart Bikb738d4f2015-12-03 11:23:35 -0800545 private static void linearTriangularOnParameter(int n) {
546 int[] a = new int[n];
547 for (int i = 0; i < n; i++) {
548 int[] b = new int[i];
549 for (int j = 0; j < i; j++) {
550 // Need to know j < i < n for static bce.
551 a[j] += 1;
552 // Need to know just j < i for static bce.
553 b[j] += 1;
554 }
555 verifyTriangular(a, b, i, n);
556 }
557 }
558
Aart Bik97412c922016-02-19 20:14:38 -0800559 /// CHECK-START: void Main.linearTriangularVariationsInnerStrict(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800560 /// CHECK-DAG: BoundsCheck
561 /// CHECK-DAG: BoundsCheck
562 /// CHECK-DAG: BoundsCheck
563 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800564 //
Aart Bik97412c922016-02-19 20:14:38 -0800565 /// CHECK-START: void Main.linearTriangularVariationsInnerStrict(int) BCE (after)
Aart Bik7d57d7f2015-12-09 14:39:48 -0800566 /// CHECK-NOT: BoundsCheck
Aart Bik97412c922016-02-19 20:14:38 -0800567 // TODO: also CHECK-NOT: Deoptimize, see b/27151190
568 private static void linearTriangularVariationsInnerStrict(int n) {
Aart Bik7d57d7f2015-12-09 14:39:48 -0800569 int[] a = new int[n];
570 for (int i = 0; i < n; i++) {
571 for (int j = 0; j < i; j++) {
572 a[j] += 1;
573 }
Aart Bik97412c922016-02-19 20:14:38 -0800574 for (int j = i - 1; j > -1; j--) {
Aart Bik7d57d7f2015-12-09 14:39:48 -0800575 a[j] += 1;
576 }
577 for (int j = i; j < n; j++) {
578 a[j] += 1;
579 }
580 for (int j = n - 1; j > i - 1; j--) {
581 a[j] += 1;
582 }
583 }
584 verifyTriangular(a);
585 }
586
Aart Bik97412c922016-02-19 20:14:38 -0800587 /// CHECK-START: void Main.linearTriangularVariationsInnerNonStrict(int) BCE (before)
588 /// CHECK-DAG: BoundsCheck
589 /// CHECK-DAG: BoundsCheck
590 /// CHECK-DAG: BoundsCheck
591 /// CHECK-DAG: BoundsCheck
592 //
593 /// CHECK-START: void Main.linearTriangularVariationsInnerNonStrict(int) BCE (after)
594 /// CHECK-NOT: BoundsCheck
595 // TODO: also CHECK-NOT: Deoptimize, see b/27151190
596 private static void linearTriangularVariationsInnerNonStrict(int n) {
597 int[] a = new int[n];
598 for (int i = 0; i < n; i++) {
599 for (int j = 0; j <= i - 1; j++) {
600 a[j] += 1;
601 }
602 for (int j = i - 1; j >= 0; j--) {
603 a[j] += 1;
604 }
605 for (int j = i; j <= n - 1; j++) {
606 a[j] += 1;
607 }
608 for (int j = n - 1; j >= i; j--) {
609 a[j] += 1;
610 }
611 }
612 verifyTriangular(a);
613 }
614
Aart Bik7d57d7f2015-12-09 14:39:48 -0800615 // Verifier for triangular loops.
Aart Bikb738d4f2015-12-03 11:23:35 -0800616 private static void verifyTriangular(int[] a, int[] b, int m, int n) {
617 expectEquals(n, a.length);
618 for (int i = 0, k = m; i < n; i++) {
619 expectEquals(a[i], k);
620 if (k > 0) k--;
621 }
622 expectEquals(m, b.length);
623 for (int i = 0; i < m; i++) {
624 expectEquals(b[i], 1);
625 }
626 }
627
Aart Bik7d57d7f2015-12-09 14:39:48 -0800628 // Verifier for triangular loops.
629 private static void verifyTriangular(int[] a) {
630 int n = a.length;
631 for (int i = 0; i < n; i++) {
632 expectEquals(a[i], n + n);
633 }
634 }
635
Aart Bik22af3be2015-09-10 12:50:58 -0700636 public static void main(String[] args) {
637 int[] empty = { };
638 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
639
640 // Linear and wrap-around.
641 expectEquals(0, linear(empty));
642 expectEquals(55, linear(x));
643 expectEquals(0, linearDown(empty));
644 expectEquals(55, linearDown(x));
645 expectEquals(0, linearObscure(empty));
646 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700647 expectEquals(0, linearVeryObscure(empty));
648 expectEquals(55, linearVeryObscure(x));
Aart Bik7d57d7f2015-12-09 14:39:48 -0800649 expectEquals(0, hiddenStride(empty));
650 expectEquals(55, hiddenStride(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700651 expectEquals(0, linearWhile(empty));
652 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700653 expectEquals(0, linearThreeWayPhi(empty));
654 expectEquals(50, linearThreeWayPhi(x));
655 expectEquals(0, linearFourWayPhi(empty));
656 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700657 expectEquals(0, wrapAroundThenLinear(empty));
658 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700659 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
660 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700661
662 // Linear with parameter.
663 sResult = 0;
664 try {
665 linearWithParameter(-1);
666 } catch (NegativeArraySizeException e) {
667 sResult = 1;
668 }
669 expectEquals(1, sResult);
670 for (int n = 0; n < 32; n++) {
671 int[] r = linearWithParameter(n);
672 expectEquals(n, r.length);
673 for (int i = 0; i < n; i++) {
674 expectEquals(i, r[i]);
675 }
676 }
677
Aart Bikf475bee2015-09-16 12:50:25 -0700678 // Linear copy.
679 expectEquals(0, linearCopy(empty).length);
680 {
681 int[] r = linearCopy(x);
682 expectEquals(x.length, r.length);
683 for (int i = 0; i < x.length; i++) {
684 expectEquals(x[i], r[i]);
685 }
686 }
687
Aart Bik22af3be2015-09-10 12:50:58 -0700688 // Linear with non-unit strides.
Aart Bik4a342772015-11-30 10:17:46 -0800689 expectEquals(55, linearByTwo(x));
690 expectEquals(25, linearByTwoSkip1(x));
691 expectEquals(25, linearByTwoSkip2(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700692 expectEquals(56, linearWithCompoundStride());
693 expectEquals(66, linearWithLargePositiveStride());
694 expectEquals(66, linearWithVeryLargePositiveStride());
695 expectEquals(66, linearWithLargeNegativeStride());
696 expectEquals(66, linearWithVeryLargeNegativeStride());
697
Aart Bikf475bee2015-09-16 12:50:25 -0700698 // Special forms.
Aart Bik9401f532015-09-28 16:25:56 -0700699 expectEquals(55, linearForNEUp());
700 expectEquals(55, linearForNEDown());
Aart Bik358af832016-02-24 14:17:53 -0800701 expectEquals(55, linearForNEArrayLengthUp(x));
702 expectEquals(55, linearForNEArrayLengthDown(x));
Aart Bik9401f532015-09-28 16:25:56 -0700703 expectEquals(55, linearDoWhileUp());
704 expectEquals(55, linearDoWhileDown());
Aart Bikf475bee2015-09-16 12:50:25 -0700705 expectEquals(55, linearShort());
Aart Bik4a342772015-11-30 10:17:46 -0800706 expectEquals(55, invariantFromPreLoop(x, 1));
Aart Bikb738d4f2015-12-03 11:23:35 -0800707 linearTriangularOnTwoArrayLengths(10);
708 linearTriangularOnOneArrayLength(10);
709 linearTriangularOnParameter(10);
Aart Bik97412c922016-02-19 20:14:38 -0800710 linearTriangularVariationsInnerStrict(10);
711 linearTriangularVariationsInnerNonStrict(10);
Aart Bik22af3be2015-09-10 12:50:58 -0700712 }
713
714 private static void expectEquals(int expected, int result) {
715 if (expected != result) {
716 throw new Error("Expected: " + expected + ", found: " + result);
717 }
718 }
719}