blob: f85479aa54d67ae9d59e9aea3aca5f640ccb7d0d [file] [log] [blame]
Aart Bik281c6812016-08-26 11:31:48 -07001/*
2 * Copyright (C) 2016 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 * Tests on loop optimizations related to induction.
19 */
20public class Main {
21
22 static int[] a = new int[10];
23
24 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (before)
25 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
26 //
27 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (after)
28 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
29 static void deadSingleLoop() {
30 for (int i = 0; i < 4; i++) {
31 }
32 }
33
Aart Bik9abf8942016-10-14 09:49:42 -070034 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (before)
35 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
36 //
37 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (after)
38 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
39 static void deadSingleLoopN(int n) {
40 for (int i = 0; i < n; i++) {
41 }
42 }
43
44 /// CHECK-START: void Main.potentialInfiniteLoop(int) loop_optimization (before)
45 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
46 //
47 /// CHECK-START: void Main.potentialInfiniteLoop(int) loop_optimization (after)
48 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
49 static void potentialInfiniteLoop(int n) {
50 for (int i = 0; i <= n; i++) { // loops forever when n = MAX_INT
51 }
52 }
53
Aart Bik281c6812016-08-26 11:31:48 -070054 /// CHECK-START: void Main.deadNestedLoops() loop_optimization (before)
55 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
56 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop>>
57 //
58 /// CHECK-START: void Main.deadNestedLoops() loop_optimization (after)
59 /// CHECK-NOT: Phi loop:{{B\d+}}
60 static void deadNestedLoops() {
61 for (int i = 0; i < 4; i++) {
62 for (int j = 0; j < 4; j++) {
63 }
64 }
65 }
66
67 /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (before)
68 /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none
69 /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
70 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>>
71 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>>
72 /// CHECK-DAG: Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
73 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop3>>
74 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
75 //
76 /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (after)
77 /// CHECK-NOT: Phi loop:{{B\d+}}
78 static void deadNestedAndFollowingLoops() {
79 for (int i = 0; i < 4; i++) {
80 for (int j = 0; j < 4; j++) {
81 for (int k = 0; k < 4; k++) {
82 }
83 for (int k = 0; k < 4; k++) {
84 }
85 }
86 for (int j = 0; j < 4; j++) {
87 for (int k = 0; k < 4; k++) {
88 }
89 }
90 }
91 for (int i = 0; i < 4; i++) {
92 }
93 }
94
Aart Bike3dedc52016-11-02 17:50:27 -070095 /// CHECK-START: void Main.deadConditional(int) loop_optimization (before)
96 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
97 //
98 /// CHECK-START: void Main.deadConditional(int) loop_optimization (after)
99 /// CHECK-NOT: Phi loop:{{B\d+}}
100 public static void deadConditional(int n) {
101 int k = 0;
102 int m = 0;
103 for (int i = 0; i < n; i++) {
104 if (i == 3)
105 k = i;
106 else
107 m = i;
108 }
109 }
110
111 /// CHECK-START: void Main.deadConditionalCycle(int) loop_optimization (before)
112 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
113 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
114 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
115 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
116 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
117 //
118 /// CHECK-START: void Main.deadConditionalCycle(int) loop_optimization (after)
119 /// CHECK-NOT: Phi loop:{{B\d+}}
120 public static void deadConditionalCycle(int n) {
121 int k = 0;
122 int m = 0;
123 for (int i = 0; i < n; i++) {
124 if (i == 3)
125 k--;
126 else
127 m++;
128 }
129 }
130
131
Aart Bik281c6812016-08-26 11:31:48 -0700132 /// CHECK-START: void Main.deadInduction() loop_optimization (before)
133 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
134 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
135 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
136 //
137 /// CHECK-START: void Main.deadInduction() loop_optimization (after)
138 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
139 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
140 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
141 static void deadInduction() {
142 int dead = 0;
143 for (int i = 0; i < a.length; i++) {
144 a[i] = 1;
145 dead += 5;
146 }
147 }
148
149 /// CHECK-START: void Main.deadManyInduction() loop_optimization (before)
150 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
151 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
152 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
153 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
154 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
155 //
156 /// CHECK-START: void Main.deadManyInduction() loop_optimization (after)
157 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
158 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
159 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
160 static void deadManyInduction() {
161 int dead1 = 0, dead2 = 1, dead3 = 3;
162 for (int i = 0; i < a.length; i++) {
163 dead1 += 5;
164 a[i] = 2;
165 dead2 += 10;
166 dead3 += 100;
167 }
168 }
169
170 /// CHECK-START: void Main.deadSequence() loop_optimization (before)
171 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
172 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
173 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
174 //
175 /// CHECK-START: void Main.deadSequence() loop_optimization (after)
176 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
177 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
178 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
179 static void deadSequence() {
180 int dead = 0;
181 for (int i = 0; i < a.length; i++) {
182 a[i] = 3;
183 // Increment value defined inside loop,
184 // but sequence itself not used anywhere.
185 dead += i;
186 }
187 }
188
189 /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (before)
190 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
191 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
192 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
193 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700194 /// CHECK-NOT: BoundsCheck
Aart Bik281c6812016-08-26 11:31:48 -0700195 //
196 /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (after)
197 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
198 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
199 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700200 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700201 static void deadCycleWithException(int k) {
202 int dead = 0;
203 for (int i = 0; i < a.length; i++) {
204 a[i] = 4;
Aart Bik482095d2016-10-10 15:39:10 -0700205 // Increment value of dead cycle may throw exception. Dynamic
206 // BCE takes care of the bounds check though, which enables
207 // removing the ArrayGet after removing the dead cycle.
Aart Bik281c6812016-08-26 11:31:48 -0700208 dead += a[k];
209 }
210 }
211
212 /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (before)
213 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
214 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
215 /// CHECK-DAG: Return [<<Phi1>>] loop:none
216 //
217 /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700218 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700219 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700220 //
221 /// CHECK-START: int Main.closedFormInductionUp() instruction_simplifier$after_bce (after)
222 /// CHECK-DAG: <<Int:i\d+>> IntConstant 12395
223 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700224 static int closedFormInductionUp() {
225 int closed = 12345;
226 for (int i = 0; i < 10; i++) {
227 closed += 5;
228 }
229 return closed; // only needs last value
230 }
231
232 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (before)
233 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
234 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
235 /// CHECK-DAG: Return [<<Phi2>>] loop:none
236 //
237 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700238 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700239 /// CHECK-DAG: Return loop:none
240 static int closedFormInductionInAndDown(int closed) {
241 for (int i = 0; i < 10; i++) {
242 closed -= 5;
243 }
244 return closed; // only needs last value
245 }
246
Aart Bik482095d2016-10-10 15:39:10 -0700247 /// CHECK-START: int Main.closedFormNested() loop_optimization (before)
248 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
249 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
250 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
251 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
252 /// CHECK-DAG: Return [<<Phi1>>] loop:none
253 //
254 /// CHECK-START: int Main.closedFormNested() loop_optimization (after)
255 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
256 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:loop{{B\d+}}
257 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700258 //
259 /// CHECK-START: int Main.closedFormNested() instruction_simplifier$after_bce (after)
260 /// CHECK-DAG: <<Int:i\d+>> IntConstant 100
261 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700262 static int closedFormNested() {
263 int closed = 0;
264 for (int i = 0; i < 10; i++) {
265 for (int j = 0; j < 10; j++) {
266 closed++;
267 }
268 }
269 return closed; // only needs last-value
270 }
271
Aart Bik482095d2016-10-10 15:39:10 -0700272 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (before)
273 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
274 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
275 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
276 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
277 /// CHECK-DAG: Return [<<Phi1>>] loop:none
278 //
279 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (after)
280 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
281 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:loop{{B\d+}}
282 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700283 //
284 /// CHECK-START: int Main.closedFormNestedAlt() instruction_simplifier$after_bce (after)
285 /// CHECK-DAG: <<Int:i\d+>> IntConstant 15082
286 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700287 static int closedFormNestedAlt() {
288 int closed = 12345;
289 for (int i = 0; i < 17; i++) {
290 for (int j = 0; j < 23; j++) {
291 closed += 7;
292 }
293 }
294 return closed; // only needs last-value
295 }
296
Aart Bik281c6812016-08-26 11:31:48 -0700297 // TODO: taken test around closed form?
298 static int closedFormInductionUpN(int n) {
299 int closed = 12345;
300 for (int i = 0; i < n; i++) {
301 closed += 5;
302 }
303 return closed; // only needs last value
304 }
305
306 // TODO: taken test around closed form?
307 static int closedFormInductionInAndDownN(int closed, int n) {
308 for (int i = 0; i < n; i++) {
309 closed -= 5;
310 }
311 return closed; // only needs last value
312 }
313
314 // TODO: move closed form even further out?
Aart Bik8c4a8542016-10-06 11:36:57 -0700315 static int closedFormNestedN(int n) {
Aart Bik281c6812016-08-26 11:31:48 -0700316 int closed = 0;
317 for (int i = 0; i < n; i++) {
318 for (int j = 0; j < 10; j++) {
319 closed++;
320 }
321 }
322 return closed; // only needs last-value
323 }
324
Aart Bik8c4a8542016-10-06 11:36:57 -0700325 // TODO: move closed form even further out?
Aart Bik482095d2016-10-10 15:39:10 -0700326 static int closedFormNestedNAlt(int n) {
327 int closed = 12345;
Aart Bik8c4a8542016-10-06 11:36:57 -0700328 for (int i = 0; i < n; i++) {
Aart Bik482095d2016-10-10 15:39:10 -0700329 for (int j = 0; j < 23; j++) {
330 closed += 7;
331 }
332 }
333 return closed; // only needs last-value
334 }
335
336 // TODO: move closed form even further out?
337 static int closedFormNestedMN(int m, int n) {
338 int closed = 0;
339 for (int i = 0; i < m; i++) {
Aart Bik8c4a8542016-10-06 11:36:57 -0700340 for (int j = 0; j < n; j++) {
341 closed++;
342 }
343 }
344 return closed; // only needs last-value
345 }
346
Aart Bik482095d2016-10-10 15:39:10 -0700347 // TODO: move closed form even further out?
348 static int closedFormNestedMNAlt(int m, int n) {
349 int closed = 12345;
350 for (int i = 0; i < m; i++) {
351 for (int j = 0; j < n; j++) {
352 closed += 7;
353 }
354 }
355 return closed; // only needs last-value
356 }
357
Aart Bik8c4a8542016-10-06 11:36:57 -0700358 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (before)
359 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:{{B\d+}} outer_loop:none
360 /// CHECK-DAG: Return [<<Phi>>] loop:none
361 //
362 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (after)
363 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
364 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700365 //
366 /// CHECK-START: int Main.mainIndexReturned() instruction_simplifier$after_bce (after)
367 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10
368 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700369 static int mainIndexReturned() {
Aart Bik281c6812016-08-26 11:31:48 -0700370 int i;
Aart Bik8c4a8542016-10-06 11:36:57 -0700371 for (i = 0; i < 10; i++);
Aart Bik281c6812016-08-26 11:31:48 -0700372 return i;
373 }
374
Aart Bik9abf8942016-10-14 09:49:42 -0700375 /// CHECK-START: int Main.periodicReturned9() loop_optimization (before)
376 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
377 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
378 /// CHECK-DAG: Return [<<Phi2>>] loop:none
379 //
380 /// CHECK-START: int Main.periodicReturned9() loop_optimization (after)
381 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
382 /// CHECK-DAG: Return loop:none
383 //
384 /// CHECK-START: int Main.periodicReturned9() instruction_simplifier$after_bce (after)
385 /// CHECK-DAG: <<Int:i\d+>> IntConstant 1
386 /// CHECK-DAG: Return [<<Int>>] loop:none
387 static int periodicReturned9() {
Aart Bik281c6812016-08-26 11:31:48 -0700388 int k = 0;
Aart Bik8c4a8542016-10-06 11:36:57 -0700389 for (int i = 0; i < 9; i++) {
Aart Bik281c6812016-08-26 11:31:48 -0700390 k = 1 - k;
391 }
392 return k;
393 }
394
Aart Bik9abf8942016-10-14 09:49:42 -0700395 /// CHECK-START: int Main.periodicReturned10() loop_optimization (before)
396 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
397 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
398 /// CHECK-DAG: Return [<<Phi2>>] loop:none
399 //
400 /// CHECK-START: int Main.periodicReturned10() loop_optimization (after)
401 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
402 /// CHECK-DAG: Return loop:none
403 //
404 /// CHECK-START: int Main.periodicReturned10() instruction_simplifier$after_bce (after)
405 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0
406 /// CHECK-DAG: Return [<<Int>>] loop:none
407 static int periodicReturned10() {
408 int k = 0;
409 for (int i = 0; i < 10; i++) {
410 k = 1 - k;
411 }
412 return k;
413 }
414
Aart Bik8c4a8542016-10-06 11:36:57 -0700415 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700416 private static int getSum21() {
417 int k = 0;
418 int sum = 0;
419 for (int i = 0; i < 6; i++) {
420 k++;
421 sum += k;
422 }
423 return sum;
424 }
425
Aart Bik8c4a8542016-10-06 11:36:57 -0700426 // TODO: handle as closed/empty eventually?
427 static int mainIndexReturnedN(int n) {
428 int i;
429 for (i = 0; i < n; i++);
430 return i;
431 }
432
Aart Bik9abf8942016-10-14 09:49:42 -0700433 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before)
434 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
435 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
436 /// CHECK-DAG: Return [<<Phi2>>] loop:none
437 //
438 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (after)
439 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
440 /// CHECK-DAG: Return loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700441 static int periodicReturnedN(int n) {
442 int k = 0;
443 for (int i = 0; i < n; i++) {
444 k = 1 - k;
445 }
446 return k;
447 }
448
449 // If ever replaced by closed form, last value should be correct!
450 private static int getSumN(int n) {
451 int k = 0;
452 int sum = 0;
453 for (int i = 0; i < n; i++) {
454 k++;
455 sum += k;
456 }
457 return sum;
458 }
459
460 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700461 private static int closedTwice() {
462 int closed = 0;
463 for (int i = 0; i < 10; i++) {
464 closed++;
465 }
466 // Closed form of first loop defines trip count of second loop.
467 int other_closed = 0;
468 for (int i = 0; i < closed; i++) {
469 other_closed++;
470 }
471 return other_closed;
472 }
473
474 /// CHECK-START: int Main.closedFeed() loop_optimization (before)
475 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
476 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
477 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
478 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none
479 /// CHECK-DAG: Return [<<Phi3>>] loop:none
480 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
481 //
482 /// CHECK-START: int Main.closedFeed() loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700483 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700484 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700485 //
486 /// CHECK-START: int Main.closedFeed() instruction_simplifier$after_bce (after)
487 /// CHECK-DAG: <<Int:i\d+>> IntConstant 20
488 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700489 private static int closedFeed() {
490 int closed = 0;
491 for (int i = 0; i < 10; i++) {
492 closed++;
493 }
494 // Closed form of first loop feeds into initial value of second loop,
495 // used when generating closed form for the latter.
496 for (int i = 0; i < 10; i++) {
497 closed++;
498 }
499 return closed;
500 }
501
502 /// CHECK-START: int Main.closedLargeUp() loop_optimization (before)
503 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
504 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
505 /// CHECK-DAG: Return [<<Phi1>>] loop:none
506 //
507 /// CHECK-START: int Main.closedLargeUp() loop_optimization (after)
508 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
509 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700510 //
511 /// CHECK-START: int Main.closedLargeUp() instruction_simplifier$after_bce (after)
512 /// CHECK-DAG: <<Int:i\d+>> IntConstant -10
513 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700514 private static int closedLargeUp() {
515 int closed = 0;
516 for (int i = 0; i < 10; i++) {
517 closed += 0x7fffffff;
518 }
519 return closed;
520 }
521
522 /// CHECK-START: int Main.closedLargeDown() loop_optimization (before)
523 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
524 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
525 /// CHECK-DAG: Return [<<Phi1>>] loop:none
526 //
527 /// CHECK-START: int Main.closedLargeDown() loop_optimization (after)
528 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
529 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700530 //
531 /// CHECK-START: int Main.closedLargeDown() instruction_simplifier$after_bce (after)
532 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10
533 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700534 private static int closedLargeDown() {
535 int closed = 0;
536 for (int i = 0; i < 10; i++) {
537 closed -= 0x7fffffff;
538 }
539 return closed;
540 }
541
Aart Bik8c4a8542016-10-06 11:36:57 -0700542 /// CHECK-START: int Main.waterFall() loop_optimization (before)
543 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
544 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
545 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none
546 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none
547 /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none
548 /// CHECK-DAG: Return [<<Phi5>>] loop:none
549 //
550 /// CHECK-START: int Main.waterFall() loop_optimization (after)
551 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
552 /// CHECK-DAG: Return loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700553 //
554 /// CHECK-START: int Main.waterFall() instruction_simplifier$after_bce (after)
555 /// CHECK-DAG: <<Int:i\d+>> IntConstant 50
556 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700557 private static int waterFall() {
558 int i = 0;
559 for (; i < 10; i++);
560 for (; i < 20; i++);
561 for (; i < 30; i++);
562 for (; i < 40; i++);
563 for (; i < 50; i++);
564 return i; // this should become just 50
565 }
566
Aart Bik639cc8c2016-10-18 13:03:31 -0700567 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (before)
568 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
569 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
570 /// CHECK-DAG: Return [<<Phi2>>] loop:none
571 //
572 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (after)
573 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
574 /// CHECK-DAG: Return loop:none
575 //
576 /// CHECK-START: boolean Main.periodicBoolIdiom1() instruction_simplifier$after_bce (after)
577 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0
578 /// CHECK-DAG: Return [<<Int>>] loop:none
579 private static boolean periodicBoolIdiom1() {
580 boolean x = true;
581 for (int i = 0; i < 7; i++) {
582 x = !x;
583 }
584 return x;
585 }
586
587 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (before)
588 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
589 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
590 /// CHECK-DAG: Return [<<Phi2>>] loop:none
591 //
592 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (after)
593 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
594 /// CHECK-DAG: Return loop:none
595 //
596 /// CHECK-START: boolean Main.periodicBoolIdiom2() instruction_simplifier$after_bce (after)
597 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0
598 /// CHECK-DAG: Return [<<Int>>] loop:none
599 private static boolean periodicBoolIdiom2() {
600 boolean x = true;
601 for (int i = 0; i < 7; i++) {
602 x = (x != true);
603 }
604 return x;
605 }
606
607 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (before)
608 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
609 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
610 /// CHECK-DAG: Return [<<Phi2>>] loop:none
611 //
612 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (after)
613 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
614 /// CHECK-DAG: Return loop:none
615 //
616 /// CHECK-START: boolean Main.periodicBoolIdiom3() instruction_simplifier$after_bce (after)
617 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0
618 /// CHECK-DAG: Return [<<Int>>] loop:none
619 private static boolean periodicBoolIdiom3() {
620 boolean x = true;
621 for (int i = 0; i < 7; i++) {
622 x = (x == false);
623 }
624 return x;
625 }
626
627 /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (before)
628 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
629 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
630 /// CHECK-DAG: Return [<<Phi2>>] loop:none
631 //
632 /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (after)
633 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
634 /// CHECK-DAG: Return loop:none
635 private static boolean periodicBoolIdiom1N(boolean x, int n) {
636 for (int i = 0; i < n; i++) {
637 x = !x;
638 }
639 return x;
640 }
641
642 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (before)
643 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
644 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
645 /// CHECK-DAG: Return [<<Phi2>>] loop:none
646 //
647 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (after)
648 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
649 /// CHECK-DAG: Return loop:none
650 private static boolean periodicBoolIdiom2N(boolean x, int n) {
651 for (int i = 0; i < n; i++) {
652 x = (x != true);
653 }
654 return x;
655 }
656
657 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (before)
658 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
659 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
660 /// CHECK-DAG: Return [<<Phi2>>] loop:none
661 //
662 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (after)
663 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
664 /// CHECK-DAG: Return loop:none
665 private static boolean periodicBoolIdiom3N(boolean x, int n) {
666 for (int i = 0; i < n; i++) {
667 x = (x == false);
668 }
669 return x;
670 }
671
Aart Bik281c6812016-08-26 11:31:48 -0700672 private static int exceptionExitBeforeAdd() {
673 int k = 0;
674 try {
675 for (int i = 0; i < 10; i++) {
676 a[i] = 0;
677 k += 10; // increment last
678 }
679 } catch(Exception e) {
680 // Flag error by returning current
681 // value of k negated.
682 return -k-1;
683 }
684 return k;
685 }
686
687 private static int exceptionExitAfterAdd() {
688 int k = 0;
689 try {
690 for (int i = 0; i < 10; i++) {
691 k += 10; // increment first
692 a[i] = 0;
693 }
694 } catch(Exception e) {
695 // Flag error by returning current
696 // value of k negated.
697 return -k-1;
698 }
699 return k;
700 }
701
702 public static void main(String[] args) {
703 deadSingleLoop();
Aart Bik9abf8942016-10-14 09:49:42 -0700704 deadSingleLoopN(4);
705 potentialInfiniteLoop(4);
Aart Bik281c6812016-08-26 11:31:48 -0700706 deadNestedLoops();
707 deadNestedAndFollowingLoops();
Aart Bike3dedc52016-11-02 17:50:27 -0700708 deadConditional(4);
709 deadConditionalCycle(4);
Aart Bik281c6812016-08-26 11:31:48 -0700710
711 deadInduction();
712 for (int i = 0; i < a.length; i++) {
713 expectEquals(1, a[i]);
714 }
715 deadManyInduction();
716 for (int i = 0; i < a.length; i++) {
717 expectEquals(2, a[i]);
718 }
719 deadSequence();
720 for (int i = 0; i < a.length; i++) {
721 expectEquals(3, a[i]);
722 }
723 try {
724 deadCycleWithException(-1);
725 throw new Error("Expected: IOOB exception");
726 } catch (IndexOutOfBoundsException e) {
727 }
728 for (int i = 0; i < a.length; i++) {
729 expectEquals(i == 0 ? 4 : 3, a[i]);
730 }
731 deadCycleWithException(0);
732 for (int i = 0; i < a.length; i++) {
733 expectEquals(4, a[i]);
734 }
735
Aart Bik8c4a8542016-10-06 11:36:57 -0700736 expectEquals(12395, closedFormInductionUp());
737 expectEquals(12295, closedFormInductionInAndDown(12345));
738 expectEquals(10 * 10, closedFormNested());
Aart Bik482095d2016-10-10 15:39:10 -0700739 expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
Aart Bik281c6812016-08-26 11:31:48 -0700740 for (int n = -4; n < 10; n++) {
741 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700742 expectEquals(12345 + tc * 5, closedFormInductionUpN(n));
743 expectEquals(12345 - tc * 5, closedFormInductionInAndDownN(12345, n));
744 expectEquals(tc * 10, closedFormNestedN(n));
Aart Bik482095d2016-10-10 15:39:10 -0700745 expectEquals(12345 + tc * 23 * 7, closedFormNestedNAlt(n));
746 expectEquals(tc * (tc + 1), closedFormNestedMN(n, n + 1));
747 expectEquals(12345 + tc * (tc + 1) * 7, closedFormNestedMNAlt(n, n + 1));
Aart Bik281c6812016-08-26 11:31:48 -0700748 }
749
Aart Bik8c4a8542016-10-06 11:36:57 -0700750 expectEquals(10, mainIndexReturned());
Aart Bik9abf8942016-10-14 09:49:42 -0700751 expectEquals(1, periodicReturned9());
752 expectEquals(0, periodicReturned10());
Aart Bik8c4a8542016-10-06 11:36:57 -0700753 expectEquals(21, getSum21());
Aart Bik281c6812016-08-26 11:31:48 -0700754 for (int n = -4; n < 4; n++) {
755 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700756 expectEquals(tc, mainIndexReturnedN(n));
757 expectEquals(tc & 1, periodicReturnedN(n));
758 expectEquals((tc * (tc + 1)) / 2, getSumN(n));
Aart Bik281c6812016-08-26 11:31:48 -0700759 }
Aart Bik8c4a8542016-10-06 11:36:57 -0700760
Aart Bik281c6812016-08-26 11:31:48 -0700761 expectEquals(10, closedTwice());
762 expectEquals(20, closedFeed());
763 expectEquals(-10, closedLargeUp());
764 expectEquals(10, closedLargeDown());
Aart Bik8c4a8542016-10-06 11:36:57 -0700765 expectEquals(50, waterFall());
Aart Bik281c6812016-08-26 11:31:48 -0700766
Aart Bik639cc8c2016-10-18 13:03:31 -0700767 expectEquals(false, periodicBoolIdiom1());
768 expectEquals(false, periodicBoolIdiom2());
769 expectEquals(false, periodicBoolIdiom3());
770 for (int n = -4; n < 10; n++) {
771 int tc = (n <= 0) ? 0 : n;
772 boolean even = (tc & 1) == 0;
773 expectEquals(even, periodicBoolIdiom1N(true, n));
774 expectEquals(!even, periodicBoolIdiom1N(false, n));
775 expectEquals(even, periodicBoolIdiom2N(true, n));
776 expectEquals(!even, periodicBoolIdiom2N(false, n));
777 expectEquals(even, periodicBoolIdiom3N(true, n));
778 expectEquals(!even, periodicBoolIdiom3N(false, n));
779 }
780
Aart Bik281c6812016-08-26 11:31:48 -0700781 expectEquals(100, exceptionExitBeforeAdd());
782 expectEquals(100, exceptionExitAfterAdd());
783 a = null;
784 expectEquals(-1, exceptionExitBeforeAdd());
785 expectEquals(-11, exceptionExitAfterAdd());
786 a = new int[4];
787 expectEquals(-41, exceptionExitBeforeAdd());
788 expectEquals(-51, exceptionExitAfterAdd());
789
790 System.out.println("passed");
791 }
792
793 private static void expectEquals(int expected, int result) {
794 if (expected != result) {
795 throw new Error("Expected: " + expected + ", found: " + result);
796 }
797 }
Aart Bik639cc8c2016-10-18 13:03:31 -0700798
799 private static void expectEquals(boolean expected, boolean result) {
800 if (expected != result) {
801 throw new Error("Expected: " + expected + ", found: " + result);
802 }
803 }
Aart Bik281c6812016-08-26 11:31:48 -0700804}