blob: ecc129a37419cd16cde3a05f778fab73c4ca7792 [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 Bikd0a022d2016-12-13 11:22:31 -0800251 /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (before)
252 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
253 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
254 /// CHECK-DAG: Select loop:<<Loop>> outer_loop:none
255 /// CHECK-DAG: Return [<<Phi1>>] loop:none
256 //
257 /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (after)
258 /// CHECK-NOT: Phi
259 /// CHECK-NOT: Select
260 //
261 /// CHECK-START: int Main.closedFormInductionTrivialIf() instruction_simplifier$after_bce (after)
262 /// CHECK-DAG: <<Int:i\d+>> IntConstant 81 loop:none
263 /// CHECK-DAG: Return [<<Int>>] loop:none
264 static int closedFormInductionTrivialIf() {
265 int closed = 11;
266 for (int i = 0; i < 10; i++) {
267 // Trivial if becomes trivial select at HIR level.
268 // Make sure this is still recognized as induction.
269 if (i < 5) {
270 closed += 7;
271 } else {
272 closed += 7;
273 }
274 }
275 return closed; // only needs last value
276 }
277
Aart Bik482095d2016-10-10 15:39:10 -0700278 /// CHECK-START: int Main.closedFormNested() loop_optimization (before)
279 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
280 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
281 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
282 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
283 /// CHECK-DAG: Return [<<Phi1>>] loop:none
284 //
285 /// CHECK-START: int Main.closedFormNested() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800286 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700287 //
288 /// CHECK-START: int Main.closedFormNested() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800289 /// CHECK-DAG: <<Int:i\d+>> IntConstant 100 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700290 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700291 static int closedFormNested() {
292 int closed = 0;
293 for (int i = 0; i < 10; i++) {
294 for (int j = 0; j < 10; j++) {
295 closed++;
296 }
297 }
298 return closed; // only needs last-value
299 }
300
Aart Bik482095d2016-10-10 15:39:10 -0700301 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (before)
302 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
303 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
304 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
305 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
306 /// CHECK-DAG: Return [<<Phi1>>] loop:none
307 //
308 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800309 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700310 //
311 /// CHECK-START: int Main.closedFormNestedAlt() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800312 /// CHECK-DAG: <<Int:i\d+>> IntConstant 15082 loop:none
313 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700314 static int closedFormNestedAlt() {
315 int closed = 12345;
316 for (int i = 0; i < 17; i++) {
317 for (int j = 0; j < 23; j++) {
318 closed += 7;
319 }
320 }
321 return closed; // only needs last-value
322 }
323
Aart Bik281c6812016-08-26 11:31:48 -0700324 // TODO: taken test around closed form?
325 static int closedFormInductionUpN(int n) {
326 int closed = 12345;
327 for (int i = 0; i < n; i++) {
328 closed += 5;
329 }
330 return closed; // only needs last value
331 }
332
333 // TODO: taken test around closed form?
334 static int closedFormInductionInAndDownN(int closed, int n) {
335 for (int i = 0; i < n; i++) {
336 closed -= 5;
337 }
338 return closed; // only needs last value
339 }
340
341 // TODO: move closed form even further out?
Aart Bik8c4a8542016-10-06 11:36:57 -0700342 static int closedFormNestedN(int n) {
Aart Bik281c6812016-08-26 11:31:48 -0700343 int closed = 0;
344 for (int i = 0; i < n; i++) {
345 for (int j = 0; j < 10; j++) {
346 closed++;
347 }
348 }
349 return closed; // only needs last-value
350 }
351
Aart Bik8c4a8542016-10-06 11:36:57 -0700352 // TODO: move closed form even further out?
Aart Bik482095d2016-10-10 15:39:10 -0700353 static int closedFormNestedNAlt(int n) {
354 int closed = 12345;
Aart Bik8c4a8542016-10-06 11:36:57 -0700355 for (int i = 0; i < n; i++) {
Aart Bik482095d2016-10-10 15:39:10 -0700356 for (int j = 0; j < 23; j++) {
357 closed += 7;
358 }
359 }
360 return closed; // only needs last-value
361 }
362
363 // TODO: move closed form even further out?
364 static int closedFormNestedMN(int m, int n) {
365 int closed = 0;
366 for (int i = 0; i < m; i++) {
Aart Bik8c4a8542016-10-06 11:36:57 -0700367 for (int j = 0; j < n; j++) {
368 closed++;
369 }
370 }
371 return closed; // only needs last-value
372 }
373
Aart Bik482095d2016-10-10 15:39:10 -0700374 // TODO: move closed form even further out?
375 static int closedFormNestedMNAlt(int m, int n) {
376 int closed = 12345;
377 for (int i = 0; i < m; i++) {
378 for (int j = 0; j < n; j++) {
379 closed += 7;
380 }
381 }
382 return closed; // only needs last-value
383 }
384
Aart Bik8c4a8542016-10-06 11:36:57 -0700385 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (before)
386 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:{{B\d+}} outer_loop:none
387 /// CHECK-DAG: Return [<<Phi>>] loop:none
388 //
389 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800390 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700391 //
392 /// CHECK-START: int Main.mainIndexReturned() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800393 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700394 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700395 static int mainIndexReturned() {
Aart Bik281c6812016-08-26 11:31:48 -0700396 int i;
Aart Bik8c4a8542016-10-06 11:36:57 -0700397 for (i = 0; i < 10; i++);
Aart Bik281c6812016-08-26 11:31:48 -0700398 return i;
399 }
400
Aart Bik9abf8942016-10-14 09:49:42 -0700401 /// CHECK-START: int Main.periodicReturned9() loop_optimization (before)
402 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
403 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
404 /// CHECK-DAG: Return [<<Phi2>>] loop:none
405 //
406 /// CHECK-START: int Main.periodicReturned9() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800407 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700408 //
409 /// CHECK-START: int Main.periodicReturned9() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800410 /// CHECK-DAG: <<Int:i\d+>> IntConstant 1 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700411 /// CHECK-DAG: Return [<<Int>>] loop:none
412 static int periodicReturned9() {
Aart Bik281c6812016-08-26 11:31:48 -0700413 int k = 0;
Aart Bik8c4a8542016-10-06 11:36:57 -0700414 for (int i = 0; i < 9; i++) {
Aart Bik281c6812016-08-26 11:31:48 -0700415 k = 1 - k;
416 }
417 return k;
418 }
419
Aart Bik9abf8942016-10-14 09:49:42 -0700420 /// CHECK-START: int Main.periodicReturned10() loop_optimization (before)
421 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
422 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
423 /// CHECK-DAG: Return [<<Phi2>>] loop:none
424 //
425 /// CHECK-START: int Main.periodicReturned10() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800426 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700427 //
428 /// CHECK-START: int Main.periodicReturned10() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800429 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700430 /// CHECK-DAG: Return [<<Int>>] loop:none
431 static int periodicReturned10() {
432 int k = 0;
433 for (int i = 0; i < 10; i++) {
434 k = 1 - k;
435 }
436 return k;
437 }
438
Aart Bikdf7822e2016-12-06 10:05:30 -0800439 /// CHECK-START: int Main.getSum21() loop_optimization (before)
440 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
441 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
442 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop>> outer_loop:none
443 /// CHECK-DAG: Return [<<Phi3>>] loop:none
444 //
445 /// CHECK-START: int Main.getSum21() loop_optimization (after)
446 /// CHECK-NOT: Phi
447 //
448 /// CHECK-START: int Main.getSum21() instruction_simplifier$after_bce (after)
449 /// CHECK-DAG: <<Int:i\d+>> IntConstant 21 loop:none
450 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700451 private static int getSum21() {
452 int k = 0;
453 int sum = 0;
454 for (int i = 0; i < 6; i++) {
455 k++;
456 sum += k;
457 }
458 return sum;
459 }
460
Aart Bik8c4a8542016-10-06 11:36:57 -0700461 // TODO: handle as closed/empty eventually?
462 static int mainIndexReturnedN(int n) {
463 int i;
464 for (i = 0; i < n; i++);
465 return i;
466 }
467
Aart Bik9abf8942016-10-14 09:49:42 -0700468 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before)
469 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
470 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
471 /// CHECK-DAG: Return [<<Phi2>>] loop:none
472 //
473 /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800474 /// CHECK-NOT: Phi
Aart Bik8c4a8542016-10-06 11:36:57 -0700475 static int periodicReturnedN(int n) {
476 int k = 0;
477 for (int i = 0; i < n; i++) {
478 k = 1 - k;
479 }
480 return k;
481 }
482
483 // If ever replaced by closed form, last value should be correct!
484 private static int getSumN(int n) {
485 int k = 0;
486 int sum = 0;
487 for (int i = 0; i < n; i++) {
488 k++;
489 sum += k;
490 }
491 return sum;
492 }
493
494 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700495 private static int closedTwice() {
496 int closed = 0;
497 for (int i = 0; i < 10; i++) {
498 closed++;
499 }
500 // Closed form of first loop defines trip count of second loop.
501 int other_closed = 0;
502 for (int i = 0; i < closed; i++) {
503 other_closed++;
504 }
505 return other_closed;
506 }
507
508 /// CHECK-START: int Main.closedFeed() loop_optimization (before)
509 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
510 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
511 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
512 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none
513 /// CHECK-DAG: Return [<<Phi3>>] loop:none
514 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
515 //
516 /// CHECK-START: int Main.closedFeed() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800517 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700518 //
519 /// CHECK-START: int Main.closedFeed() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800520 /// CHECK-DAG: <<Int:i\d+>> IntConstant 20 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700521 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700522 private static int closedFeed() {
523 int closed = 0;
524 for (int i = 0; i < 10; i++) {
525 closed++;
526 }
527 // Closed form of first loop feeds into initial value of second loop,
528 // used when generating closed form for the latter.
529 for (int i = 0; i < 10; i++) {
530 closed++;
531 }
532 return closed;
533 }
534
535 /// CHECK-START: int Main.closedLargeUp() loop_optimization (before)
536 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
537 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
538 /// CHECK-DAG: Return [<<Phi1>>] loop:none
539 //
540 /// CHECK-START: int Main.closedLargeUp() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800541 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700542 //
543 /// CHECK-START: int Main.closedLargeUp() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800544 /// CHECK-DAG: <<Int:i\d+>> IntConstant -10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700545 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700546 private static int closedLargeUp() {
547 int closed = 0;
548 for (int i = 0; i < 10; i++) {
549 closed += 0x7fffffff;
550 }
551 return closed;
552 }
553
554 /// CHECK-START: int Main.closedLargeDown() loop_optimization (before)
555 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
556 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
557 /// CHECK-DAG: Return [<<Phi1>>] loop:none
558 //
559 /// CHECK-START: int Main.closedLargeDown() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800560 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700561 //
562 /// CHECK-START: int Main.closedLargeDown() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800563 /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700564 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700565 private static int closedLargeDown() {
566 int closed = 0;
567 for (int i = 0; i < 10; i++) {
568 closed -= 0x7fffffff;
569 }
570 return closed;
571 }
572
Aart Bik8c4a8542016-10-06 11:36:57 -0700573 /// CHECK-START: int Main.waterFall() loop_optimization (before)
574 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
575 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
576 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none
577 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none
578 /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none
579 /// CHECK-DAG: Return [<<Phi5>>] loop:none
580 //
581 /// CHECK-START: int Main.waterFall() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800582 /// CHECK-NOT: Phi
Aart Bik9abf8942016-10-14 09:49:42 -0700583 //
584 /// CHECK-START: int Main.waterFall() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800585 /// CHECK-DAG: <<Int:i\d+>> IntConstant 50 loop:none
Aart Bik9abf8942016-10-14 09:49:42 -0700586 /// CHECK-DAG: Return [<<Int>>] loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700587 private static int waterFall() {
588 int i = 0;
589 for (; i < 10; i++);
590 for (; i < 20; i++);
591 for (; i < 30; i++);
592 for (; i < 40; i++);
593 for (; i < 50; i++);
594 return i; // this should become just 50
595 }
596
Aart Bik639cc8c2016-10-18 13:03:31 -0700597 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (before)
598 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
599 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
600 /// CHECK-DAG: Return [<<Phi2>>] loop:none
601 //
602 /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800603 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700604 //
605 /// CHECK-START: boolean Main.periodicBoolIdiom1() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800606 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700607 /// CHECK-DAG: Return [<<Int>>] loop:none
608 private static boolean periodicBoolIdiom1() {
609 boolean x = true;
610 for (int i = 0; i < 7; i++) {
611 x = !x;
612 }
613 return x;
614 }
615
616 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (before)
617 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
618 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
619 /// CHECK-DAG: Return [<<Phi2>>] loop:none
620 //
621 /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800622 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700623 //
624 /// CHECK-START: boolean Main.periodicBoolIdiom2() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800625 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700626 /// CHECK-DAG: Return [<<Int>>] loop:none
627 private static boolean periodicBoolIdiom2() {
628 boolean x = true;
629 for (int i = 0; i < 7; i++) {
630 x = (x != true);
631 }
632 return x;
633 }
634
635 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (before)
636 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
637 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
638 /// CHECK-DAG: Return [<<Phi2>>] loop:none
639 //
640 /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800641 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700642 //
643 /// CHECK-START: boolean Main.periodicBoolIdiom3() instruction_simplifier$after_bce (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800644 /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none
Aart Bik639cc8c2016-10-18 13:03:31 -0700645 /// CHECK-DAG: Return [<<Int>>] loop:none
646 private static boolean periodicBoolIdiom3() {
647 boolean x = true;
648 for (int i = 0; i < 7; i++) {
649 x = (x == false);
650 }
651 return x;
652 }
653
654 /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (before)
655 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
656 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
657 /// CHECK-DAG: Return [<<Phi2>>] loop:none
658 //
659 /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800660 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700661 private static boolean periodicBoolIdiom1N(boolean x, int n) {
662 for (int i = 0; i < n; i++) {
663 x = !x;
664 }
665 return x;
666 }
667
668 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (before)
669 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
670 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
671 /// CHECK-DAG: Return [<<Phi2>>] loop:none
672 //
673 /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800674 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700675 private static boolean periodicBoolIdiom2N(boolean x, int n) {
676 for (int i = 0; i < n; i++) {
677 x = (x != true);
678 }
679 return x;
680 }
681
682 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (before)
683 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
684 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
685 /// CHECK-DAG: Return [<<Phi2>>] loop:none
686 //
687 /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (after)
Aart Bikdf7822e2016-12-06 10:05:30 -0800688 /// CHECK-NOT: Phi
Aart Bik639cc8c2016-10-18 13:03:31 -0700689 private static boolean periodicBoolIdiom3N(boolean x, int n) {
690 for (int i = 0; i < n; i++) {
691 x = (x == false);
692 }
693 return x;
694 }
695
Aart Bik281c6812016-08-26 11:31:48 -0700696 private static int exceptionExitBeforeAdd() {
697 int k = 0;
698 try {
699 for (int i = 0; i < 10; i++) {
700 a[i] = 0;
701 k += 10; // increment last
702 }
703 } catch(Exception e) {
704 // Flag error by returning current
705 // value of k negated.
706 return -k-1;
707 }
708 return k;
709 }
710
711 private static int exceptionExitAfterAdd() {
712 int k = 0;
713 try {
714 for (int i = 0; i < 10; i++) {
715 k += 10; // increment first
716 a[i] = 0;
717 }
718 } catch(Exception e) {
719 // Flag error by returning current
720 // value of k negated.
721 return -k-1;
722 }
723 return k;
724 }
725
726 public static void main(String[] args) {
727 deadSingleLoop();
Aart Bik9abf8942016-10-14 09:49:42 -0700728 deadSingleLoopN(4);
729 potentialInfiniteLoop(4);
Aart Bik281c6812016-08-26 11:31:48 -0700730 deadNestedLoops();
731 deadNestedAndFollowingLoops();
Aart Bike3dedc52016-11-02 17:50:27 -0700732 deadConditional(4);
733 deadConditionalCycle(4);
Aart Bik281c6812016-08-26 11:31:48 -0700734
735 deadInduction();
736 for (int i = 0; i < a.length; i++) {
737 expectEquals(1, a[i]);
738 }
739 deadManyInduction();
740 for (int i = 0; i < a.length; i++) {
741 expectEquals(2, a[i]);
742 }
743 deadSequence();
744 for (int i = 0; i < a.length; i++) {
745 expectEquals(3, a[i]);
746 }
747 try {
748 deadCycleWithException(-1);
749 throw new Error("Expected: IOOB exception");
750 } catch (IndexOutOfBoundsException e) {
751 }
752 for (int i = 0; i < a.length; i++) {
753 expectEquals(i == 0 ? 4 : 3, a[i]);
754 }
755 deadCycleWithException(0);
756 for (int i = 0; i < a.length; i++) {
757 expectEquals(4, a[i]);
758 }
759
Aart Bik8c4a8542016-10-06 11:36:57 -0700760 expectEquals(12395, closedFormInductionUp());
761 expectEquals(12295, closedFormInductionInAndDown(12345));
Aart Bikd0a022d2016-12-13 11:22:31 -0800762 expectEquals(81, closedFormInductionTrivialIf());
Aart Bik8c4a8542016-10-06 11:36:57 -0700763 expectEquals(10 * 10, closedFormNested());
Aart Bik482095d2016-10-10 15:39:10 -0700764 expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
Aart Bik281c6812016-08-26 11:31:48 -0700765 for (int n = -4; n < 10; n++) {
766 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700767 expectEquals(12345 + tc * 5, closedFormInductionUpN(n));
768 expectEquals(12345 - tc * 5, closedFormInductionInAndDownN(12345, n));
769 expectEquals(tc * 10, closedFormNestedN(n));
Aart Bik482095d2016-10-10 15:39:10 -0700770 expectEquals(12345 + tc * 23 * 7, closedFormNestedNAlt(n));
771 expectEquals(tc * (tc + 1), closedFormNestedMN(n, n + 1));
772 expectEquals(12345 + tc * (tc + 1) * 7, closedFormNestedMNAlt(n, n + 1));
Aart Bik281c6812016-08-26 11:31:48 -0700773 }
774
Aart Bik8c4a8542016-10-06 11:36:57 -0700775 expectEquals(10, mainIndexReturned());
Aart Bik9abf8942016-10-14 09:49:42 -0700776 expectEquals(1, periodicReturned9());
777 expectEquals(0, periodicReturned10());
Aart Bik8c4a8542016-10-06 11:36:57 -0700778 expectEquals(21, getSum21());
Aart Bik281c6812016-08-26 11:31:48 -0700779 for (int n = -4; n < 4; n++) {
780 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700781 expectEquals(tc, mainIndexReturnedN(n));
782 expectEquals(tc & 1, periodicReturnedN(n));
783 expectEquals((tc * (tc + 1)) / 2, getSumN(n));
Aart Bik281c6812016-08-26 11:31:48 -0700784 }
Aart Bik8c4a8542016-10-06 11:36:57 -0700785
Aart Bik281c6812016-08-26 11:31:48 -0700786 expectEquals(10, closedTwice());
787 expectEquals(20, closedFeed());
788 expectEquals(-10, closedLargeUp());
789 expectEquals(10, closedLargeDown());
Aart Bik8c4a8542016-10-06 11:36:57 -0700790 expectEquals(50, waterFall());
Aart Bik281c6812016-08-26 11:31:48 -0700791
Aart Bik639cc8c2016-10-18 13:03:31 -0700792 expectEquals(false, periodicBoolIdiom1());
793 expectEquals(false, periodicBoolIdiom2());
794 expectEquals(false, periodicBoolIdiom3());
795 for (int n = -4; n < 10; n++) {
796 int tc = (n <= 0) ? 0 : n;
797 boolean even = (tc & 1) == 0;
798 expectEquals(even, periodicBoolIdiom1N(true, n));
799 expectEquals(!even, periodicBoolIdiom1N(false, n));
800 expectEquals(even, periodicBoolIdiom2N(true, n));
801 expectEquals(!even, periodicBoolIdiom2N(false, n));
802 expectEquals(even, periodicBoolIdiom3N(true, n));
803 expectEquals(!even, periodicBoolIdiom3N(false, n));
804 }
805
Aart Bik281c6812016-08-26 11:31:48 -0700806 expectEquals(100, exceptionExitBeforeAdd());
807 expectEquals(100, exceptionExitAfterAdd());
808 a = null;
809 expectEquals(-1, exceptionExitBeforeAdd());
810 expectEquals(-11, exceptionExitAfterAdd());
811 a = new int[4];
812 expectEquals(-41, exceptionExitBeforeAdd());
813 expectEquals(-51, exceptionExitAfterAdd());
814
815 System.out.println("passed");
816 }
817
818 private static void expectEquals(int expected, int result) {
819 if (expected != result) {
820 throw new Error("Expected: " + expected + ", found: " + result);
821 }
822 }
Aart Bik639cc8c2016-10-18 13:03:31 -0700823
824 private static void expectEquals(boolean expected, boolean result) {
825 if (expected != result) {
826 throw new Error("Expected: " + expected + ", found: " + result);
827 }
828 }
Aart Bik281c6812016-08-26 11:31:48 -0700829}