blob: 87a69b25c4addb04e0692bfd18ebe9aa8269b828 [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)
Aart Bikdf7822e2016-12-06 10:05:30 -080028 /// CHECK-NOT: Phi
Aart Bik281c6812016-08-26 11:31:48 -070029 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)
Aart Bikdf7822e2016-12-06 10:05:30 -080038 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -070039 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)
Aart Bikdf7822e2016-12-06 10:05:30 -080059 /// CHECK-NOT: Phi
Aart Bik281c6812016-08-26 11:31:48 -070060 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)
Aart Bikdf7822e2016-12-06 10:05:30 -080077 /// CHECK-NOT: Phi
Aart Bik281c6812016-08-26 11:31:48 -070078 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)
Aart Bikdf7822e2016-12-06 10:05:30 -080099 /// CHECK-NOT: Phi
Aart Bike3dedc52016-11-02 17:50:27 -0700100 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)
Aart Bikdf7822e2016-12-06 10:05:30 -0800119 /// CHECK-NOT: Phi
Aart Bike3dedc52016-11-02 17:50:27 -0700120 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 Bikdf7822e2016-12-06 10:05:30 -0800218 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700219 //
220 /// CHECK-START: int Main.closedFormInductionUp() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800221 /// CHECK-DAG: <<Int:i\d+>> IntConstant 12395 loop:none
222 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700223 static int closedFormInductionUp() {
224 int closed = 12345;
225 for (int i = 0; i < 10; i++) {
226 closed += 5;
227 }
228 return closed; // only needs last value
229 }
230
231 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (before)
232 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
233 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
234 /// CHECK-DAG: Return [<<Phi2>>] loop:none
235 //
236 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800237 /// CHECK-NOT: Phi
238 //
239 /// CHECK-START: int Main.closedFormInductionInAndDown(int) instruction_simplifier$after_bce (after)
240 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
241 /// CHECK-DAG: <<Int:i\d+>> IntConstant -50 loop:none
242 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
243 /// CHECK-DAG: Return [<<Add>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700244 static int closedFormInductionInAndDown(int closed) {
245 for (int i = 0; i < 10; i++) {
246 closed -= 5;
247 }
248 return closed; // only needs last value
249 }
250
Aart Bik482095d2016-10-10 15:39:10 -0700251 /// CHECK-START: int Main.closedFormNested() loop_optimization (before)
252 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
253 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
254 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
255 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
256 /// CHECK-DAG: Return [<<Phi1>>] loop:none
257 //
258 /// CHECK-START: int Main.closedFormNested() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800259 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700260 //
261 /// CHECK-START: int Main.closedFormNested() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800262 /// CHECK-DAG: <<Int:i\d+>> IntConstant 100 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700263 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700264 static int closedFormNested() {
265 int closed = 0;
266 for (int i = 0; i < 10; i++) {
267 for (int j = 0; j < 10; j++) {
268 closed++;
269 }
270 }
271 return closed; // only needs last-value
272 }
273
Aart Bik482095d2016-10-10 15:39:10 -0700274 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (before)
275 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
276 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
277 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
278 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
279 /// CHECK-DAG: Return [<<Phi1>>] loop:none
280 //
281 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800282 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700283 //
284 /// CHECK-START: int Main.closedFormNestedAlt() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800285 /// CHECK-DAG: <<Int:i\d+>> IntConstant 15082 loop:none
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)
Aart Bikdf7822e2016-12-06 10:05:30 -0800363 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700364 //
365 /// CHECK-START: int Main.mainIndexReturned() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800366 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700367 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700368 static int mainIndexReturned() {
Aart Bik281c6812016-08-26 11:31:48 -0700369 int i;
Aart Bik8c4a8542016-10-06 11:36:57 -0700370 for (i = 0; i < 10; i++);
Aart Bik281c6812016-08-26 11:31:48 -0700371 return i;
372 }
373
Aart Bik9abf8942016-10-14 09:49:42 -0700374 /// CHECK-START: int Main.periodicReturned9() loop_optimization (before)
375 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
376 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
377 /// CHECK-DAG: Return [<<Phi2>>] loop:none
378 //
379 /// CHECK-START: int Main.periodicReturned9() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800380 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700381 //
382 /// CHECK-START: int Main.periodicReturned9() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800383 /// CHECK-DAG: <<Int:i\d+>> IntConstant 1 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700384 /// CHECK-DAG: Return [<<Int>>] loop:none
385 static int periodicReturned9() {
Aart Bik281c6812016-08-26 11:31:48 -0700386 int k = 0;
Aart Bik8c4a8542016-10-06 11:36:57 -0700387 for (int i = 0; i < 9; i++) {
Aart Bik281c6812016-08-26 11:31:48 -0700388 k = 1 - k;
389 }
390 return k;
391 }
392
Aart Bik9abf8942016-10-14 09:49:42 -0700393 /// CHECK-START: int Main.periodicReturned10() loop_optimization (before)
394 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
395 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
396 /// CHECK-DAG: Return [<<Phi2>>] loop:none
397 //
398 /// CHECK-START: int Main.periodicReturned10() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800399 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700400 //
401 /// CHECK-START: int Main.periodicReturned10() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800402 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700403 /// CHECK-DAG: Return [<<Int>>] loop:none
404 static int periodicReturned10() {
405 int k = 0;
406 for (int i = 0; i < 10; i++) {
407 k = 1 - k;
408 }
409 return k;
410 }
411
Aart Bikdf7822e2016-12-06 10:05:30 -0800412 /// CHECK-START: int Main.getSum21() loop_optimization (before)
413 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
414 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
415 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop>> outer_loop:none
416 /// CHECK-DAG: Return [<<Phi3>>] loop:none
417 //
418 /// CHECK-START: int Main.getSum21() loop_optimization (after)
419 /// CHECK-NOT: Phi
420 //
421 /// CHECK-START: int Main.getSum21() instruction_simplifier$after_bce (after)
422 /// CHECK-DAG: <<Int:i\d+>> IntConstant 21 loop:none
423 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700424 private static int getSum21() {
425 int k = 0;
426 int sum = 0;
427 for (int i = 0; i < 6; i++) {
428 k++;
429 sum += k;
430 }
431 return sum;
432 }
433
Aart Bik8c4a8542016-10-06 11:36:57 -0700434 // TODO: handle as closed/empty eventually?
435 static int mainIndexReturnedN(int n) {
436 int i;
437 for (i = 0; i < n; i++);
438 return i;
439 }
440
Aart Bik9abf8942016-10-14 09:49:42 -0700441 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before)
442 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
443 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
444 /// CHECK-DAG: Return [<<Phi2>>] loop:none
445 //
446 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800447 /// CHECK-NOT: Phi
Aart Bik8c4a8542016-10-06 11:36:57 -0700448 static int periodicReturnedN(int n) {
449 int k = 0;
450 for (int i = 0; i < n; i++) {
451 k = 1 - k;
452 }
453 return k;
454 }
455
456 // If ever replaced by closed form, last value should be correct!
457 private static int getSumN(int n) {
458 int k = 0;
459 int sum = 0;
460 for (int i = 0; i < n; i++) {
461 k++;
462 sum += k;
463 }
464 return sum;
465 }
466
467 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700468 private static int closedTwice() {
469 int closed = 0;
470 for (int i = 0; i < 10; i++) {
471 closed++;
472 }
473 // Closed form of first loop defines trip count of second loop.
474 int other_closed = 0;
475 for (int i = 0; i < closed; i++) {
476 other_closed++;
477 }
478 return other_closed;
479 }
480
481 /// CHECK-START: int Main.closedFeed() loop_optimization (before)
482 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
483 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
484 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
485 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none
486 /// CHECK-DAG: Return [<<Phi3>>] loop:none
487 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
488 //
489 /// CHECK-START: int Main.closedFeed() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800490 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700491 //
492 /// CHECK-START: int Main.closedFeed() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800493 /// CHECK-DAG: <<Int:i\d+>> IntConstant 20 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700494 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700495 private static int closedFeed() {
496 int closed = 0;
497 for (int i = 0; i < 10; i++) {
498 closed++;
499 }
500 // Closed form of first loop feeds into initial value of second loop,
501 // used when generating closed form for the latter.
502 for (int i = 0; i < 10; i++) {
503 closed++;
504 }
505 return closed;
506 }
507
508 /// CHECK-START: int Main.closedLargeUp() loop_optimization (before)
509 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
510 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
511 /// CHECK-DAG: Return [<<Phi1>>] loop:none
512 //
513 /// CHECK-START: int Main.closedLargeUp() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800514 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700515 //
516 /// CHECK-START: int Main.closedLargeUp() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800517 /// CHECK-DAG: <<Int:i\d+>> IntConstant -10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700518 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700519 private static int closedLargeUp() {
520 int closed = 0;
521 for (int i = 0; i < 10; i++) {
522 closed += 0x7fffffff;
523 }
524 return closed;
525 }
526
527 /// CHECK-START: int Main.closedLargeDown() loop_optimization (before)
528 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
529 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
530 /// CHECK-DAG: Return [<<Phi1>>] loop:none
531 //
532 /// CHECK-START: int Main.closedLargeDown() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800533 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700534 //
535 /// CHECK-START: int Main.closedLargeDown() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800536 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700537 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700538 private static int closedLargeDown() {
539 int closed = 0;
540 for (int i = 0; i < 10; i++) {
541 closed -= 0x7fffffff;
542 }
543 return closed;
544 }
545
Aart Bik8c4a8542016-10-06 11:36:57 -0700546 /// CHECK-START: int Main.waterFall() loop_optimization (before)
547 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
548 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
549 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none
550 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none
551 /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none
552 /// CHECK-DAG: Return [<<Phi5>>] loop:none
553 //
554 /// CHECK-START: int Main.waterFall() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800555 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700556 //
557 /// CHECK-START: int Main.waterFall() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800558 /// CHECK-DAG: <<Int:i\d+>> IntConstant 50 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700559 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700560 private static int waterFall() {
561 int i = 0;
562 for (; i < 10; i++);
563 for (; i < 20; i++);
564 for (; i < 30; i++);
565 for (; i < 40; i++);
566 for (; i < 50; i++);
567 return i; // this should become just 50
568 }
569
Aart Bik639cc8c2016-10-18 13:03:31 -0700570 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (before)
571 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
572 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
573 /// CHECK-DAG: Return [<<Phi2>>] loop:none
574 //
575 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800576 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700577 //
578 /// CHECK-START: boolean Main.periodicBoolIdiom1() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800579 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700580 /// CHECK-DAG: Return [<<Int>>] loop:none
581 private static boolean periodicBoolIdiom1() {
582 boolean x = true;
583 for (int i = 0; i < 7; i++) {
584 x = !x;
585 }
586 return x;
587 }
588
589 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (before)
590 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
591 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
592 /// CHECK-DAG: Return [<<Phi2>>] loop:none
593 //
594 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800595 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700596 //
597 /// CHECK-START: boolean Main.periodicBoolIdiom2() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800598 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700599 /// CHECK-DAG: Return [<<Int>>] loop:none
600 private static boolean periodicBoolIdiom2() {
601 boolean x = true;
602 for (int i = 0; i < 7; i++) {
603 x = (x != true);
604 }
605 return x;
606 }
607
608 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (before)
609 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
610 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
611 /// CHECK-DAG: Return [<<Phi2>>] loop:none
612 //
613 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800614 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700615 //
616 /// CHECK-START: boolean Main.periodicBoolIdiom3() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800617 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700618 /// 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)
Aart Bikdf7822e2016-12-06 10:05:30 -0800633 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700634 private static boolean periodicBoolIdiom1N(boolean x, int n) {
635 for (int i = 0; i < n; i++) {
636 x = !x;
637 }
638 return x;
639 }
640
641 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (before)
642 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
643 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
644 /// CHECK-DAG: Return [<<Phi2>>] loop:none
645 //
646 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800647 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700648 private static boolean periodicBoolIdiom2N(boolean x, int n) {
649 for (int i = 0; i < n; i++) {
650 x = (x != true);
651 }
652 return x;
653 }
654
655 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (before)
656 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
657 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
658 /// CHECK-DAG: Return [<<Phi2>>] loop:none
659 //
660 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800661 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700662 private static boolean periodicBoolIdiom3N(boolean x, int n) {
663 for (int i = 0; i < n; i++) {
664 x = (x == false);
665 }
666 return x;
667 }
668
Aart Bik281c6812016-08-26 11:31:48 -0700669 private static int exceptionExitBeforeAdd() {
670 int k = 0;
671 try {
672 for (int i = 0; i < 10; i++) {
673 a[i] = 0;
674 k += 10; // increment last
675 }
676 } catch(Exception e) {
677 // Flag error by returning current
678 // value of k negated.
679 return -k-1;
680 }
681 return k;
682 }
683
684 private static int exceptionExitAfterAdd() {
685 int k = 0;
686 try {
687 for (int i = 0; i < 10; i++) {
688 k += 10; // increment first
689 a[i] = 0;
690 }
691 } catch(Exception e) {
692 // Flag error by returning current
693 // value of k negated.
694 return -k-1;
695 }
696 return k;
697 }
698
699 public static void main(String[] args) {
700 deadSingleLoop();
Aart Bik9abf8942016-10-14 09:49:42 -0700701 deadSingleLoopN(4);
702 potentialInfiniteLoop(4);
Aart Bik281c6812016-08-26 11:31:48 -0700703 deadNestedLoops();
704 deadNestedAndFollowingLoops();
Aart Bike3dedc52016-11-02 17:50:27 -0700705 deadConditional(4);
706 deadConditionalCycle(4);
Aart Bik281c6812016-08-26 11:31:48 -0700707
708 deadInduction();
709 for (int i = 0; i < a.length; i++) {
710 expectEquals(1, a[i]);
711 }
712 deadManyInduction();
713 for (int i = 0; i < a.length; i++) {
714 expectEquals(2, a[i]);
715 }
716 deadSequence();
717 for (int i = 0; i < a.length; i++) {
718 expectEquals(3, a[i]);
719 }
720 try {
721 deadCycleWithException(-1);
722 throw new Error("Expected: IOOB exception");
723 } catch (IndexOutOfBoundsException e) {
724 }
725 for (int i = 0; i < a.length; i++) {
726 expectEquals(i == 0 ? 4 : 3, a[i]);
727 }
728 deadCycleWithException(0);
729 for (int i = 0; i < a.length; i++) {
730 expectEquals(4, a[i]);
731 }
732
Aart Bik8c4a8542016-10-06 11:36:57 -0700733 expectEquals(12395, closedFormInductionUp());
734 expectEquals(12295, closedFormInductionInAndDown(12345));
735 expectEquals(10 * 10, closedFormNested());
Aart Bik482095d2016-10-10 15:39:10 -0700736 expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
Aart Bik281c6812016-08-26 11:31:48 -0700737 for (int n = -4; n < 10; n++) {
738 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700739 expectEquals(12345 + tc * 5, closedFormInductionUpN(n));
740 expectEquals(12345 - tc * 5, closedFormInductionInAndDownN(12345, n));
741 expectEquals(tc * 10, closedFormNestedN(n));
Aart Bik482095d2016-10-10 15:39:10 -0700742 expectEquals(12345 + tc * 23 * 7, closedFormNestedNAlt(n));
743 expectEquals(tc * (tc + 1), closedFormNestedMN(n, n + 1));
744 expectEquals(12345 + tc * (tc + 1) * 7, closedFormNestedMNAlt(n, n + 1));
Aart Bik281c6812016-08-26 11:31:48 -0700745 }
746
Aart Bik8c4a8542016-10-06 11:36:57 -0700747 expectEquals(10, mainIndexReturned());
Aart Bik9abf8942016-10-14 09:49:42 -0700748 expectEquals(1, periodicReturned9());
749 expectEquals(0, periodicReturned10());
Aart Bik8c4a8542016-10-06 11:36:57 -0700750 expectEquals(21, getSum21());
Aart Bik281c6812016-08-26 11:31:48 -0700751 for (int n = -4; n < 4; n++) {
752 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700753 expectEquals(tc, mainIndexReturnedN(n));
754 expectEquals(tc & 1, periodicReturnedN(n));
755 expectEquals((tc * (tc + 1)) / 2, getSumN(n));
Aart Bik281c6812016-08-26 11:31:48 -0700756 }
Aart Bik8c4a8542016-10-06 11:36:57 -0700757
Aart Bik281c6812016-08-26 11:31:48 -0700758 expectEquals(10, closedTwice());
759 expectEquals(20, closedFeed());
760 expectEquals(-10, closedLargeUp());
761 expectEquals(10, closedLargeDown());
Aart Bik8c4a8542016-10-06 11:36:57 -0700762 expectEquals(50, waterFall());
Aart Bik281c6812016-08-26 11:31:48 -0700763
Aart Bik639cc8c2016-10-18 13:03:31 -0700764 expectEquals(false, periodicBoolIdiom1());
765 expectEquals(false, periodicBoolIdiom2());
766 expectEquals(false, periodicBoolIdiom3());
767 for (int n = -4; n < 10; n++) {
768 int tc = (n <= 0) ? 0 : n;
769 boolean even = (tc & 1) == 0;
770 expectEquals(even, periodicBoolIdiom1N(true, n));
771 expectEquals(!even, periodicBoolIdiom1N(false, n));
772 expectEquals(even, periodicBoolIdiom2N(true, n));
773 expectEquals(!even, periodicBoolIdiom2N(false, n));
774 expectEquals(even, periodicBoolIdiom3N(true, n));
775 expectEquals(!even, periodicBoolIdiom3N(false, n));
776 }
777
Aart Bik281c6812016-08-26 11:31:48 -0700778 expectEquals(100, exceptionExitBeforeAdd());
779 expectEquals(100, exceptionExitAfterAdd());
780 a = null;
781 expectEquals(-1, exceptionExitBeforeAdd());
782 expectEquals(-11, exceptionExitAfterAdd());
783 a = new int[4];
784 expectEquals(-41, exceptionExitBeforeAdd());
785 expectEquals(-51, exceptionExitAfterAdd());
786
787 System.out.println("passed");
788 }
789
790 private static void expectEquals(int expected, int result) {
791 if (expected != result) {
792 throw new Error("Expected: " + expected + ", found: " + result);
793 }
794 }
Aart Bik639cc8c2016-10-18 13:03:31 -0700795
796 private static void expectEquals(boolean expected, boolean result) {
797 if (expected != result) {
798 throw new Error("Expected: " + expected + ", found: " + result);
799 }
800 }
Aart Bik281c6812016-08-26 11:31:48 -0700801}