blob: 9391533411b79e9bae07276d70bdd28a14f4d991 [file] [log] [blame]
Mingyao Yang0304e182015-01-30 16:41:29 -08001/*
2* Copyright (C) 2015 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17public class Main {
18
19 // CHECK-START: int Main.sieve(int) BCE (before)
20 // CHECK: BoundsCheck
21 // CHECK: ArraySet
22 // CHECK: BoundsCheck
23 // CHECK: ArrayGet
24 // CHECK: BoundsCheck
25 // CHECK: ArraySet
26
27 // CHECK-START: int Main.sieve(int) BCE (after)
28 // CHECK-NOT: BoundsCheck
29 // CHECK: ArraySet
30 // CHECK-NOT: BoundsCheck
31 // CHECK: ArrayGet
32 // CHECK: BoundsCheck
33 // CHECK: ArraySet
34
35 static int sieve(int size) {
36 int primeCount = 0;
37 boolean[] flags = new boolean[size + 1];
38 for (int i = 1; i < size; i++) flags[i] = true; // Can eliminate.
39 for (int i = 2; i < size; i++) {
40 if (flags[i]) { // Can eliminate.
41 primeCount++;
42 for (int k = i + 1; k <= size; k += i)
43 flags[k - 1] = false; // Can't eliminate yet due to (k+i) may overflow.
44 }
45 }
46 return primeCount;
47 }
48
Mingyao Yang8c8bad82015-02-09 18:13:26 -080049
Mingyao Yang0304e182015-01-30 16:41:29 -080050 // CHECK-START: void Main.narrow(int[], int) BCE (before)
51 // CHECK: BoundsCheck
52 // CHECK: ArraySet
53 // CHECK: BoundsCheck
54 // CHECK: ArraySet
55 // CHECK: BoundsCheck
56 // CHECK: ArraySet
57
58 // CHECK-START: void Main.narrow(int[], int) BCE (after)
59 // CHECK-NOT: BoundsCheck
60 // CHECK: ArraySet
61 // CHECK-NOT: BoundsCheck
62 // CHECK: ArraySet
63 // CHECK: BoundsCheck
64 // CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -080065 // CHECK-NOT: BoundsCheck
66 // CHECK: ArraySet
67 // CHECK: BoundsCheck
68 // CHECK: ArraySet
Mingyao Yang0304e182015-01-30 16:41:29 -080069
Mingyao Yang8c8bad82015-02-09 18:13:26 -080070 static void narrow(int[] array, int offset) {
Mingyao Yang0304e182015-01-30 16:41:29 -080071 if (offset < 0) {
72 return;
73 }
74 if (offset < array.length) {
75 // offset is in range [0, array.length-1].
76 // Bounds check can be eliminated.
77 array[offset] = 1;
78
79 int biased_offset1 = offset + 1;
80 // biased_offset1 is in range [1, array.length].
81 if (biased_offset1 < array.length) {
82 // biased_offset1 is in range [1, array.length-1].
83 // Bounds check can be eliminated.
84 array[biased_offset1] = 1;
85 }
86
87 int biased_offset2 = offset + 0x70000000;
88 // biased_offset2 is in range [0x70000000, array.length-1+0x70000000].
89 // It may overflow and be negative.
90 if (biased_offset2 < array.length) {
91 // Even with this test, biased_offset2 can be negative so we can't
92 // eliminate this bounds check.
93 array[biased_offset2] = 1;
94 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -080095
96 // offset_sub1 won't underflow since offset is no less than 0.
97 int offset_sub1 = offset - Integer.MAX_VALUE;
98 if (offset_sub1 >= 0) {
99 array[offset_sub1] = 1; // Bounds check can be eliminated.
100 }
101
102 // offset_sub2 can underflow.
103 int offset_sub2 = offset_sub1 - Integer.MAX_VALUE;
104 if (offset_sub2 >= 0) {
105 array[offset_sub2] = 1; // Bounds check can't be eliminated.
106 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800107 }
108 }
109
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800110
111 // CHECK-START: void Main.constantIndexing(int[]) BCE (before)
112 // CHECK: BoundsCheck
113 // CHECK: ArraySet
114 // CHECK: BoundsCheck
115 // CHECK: ArraySet
116 // CHECK: BoundsCheck
117 // CHECK: ArraySet
118
119 // CHECK-START: void Main.constantIndexing(int[]) BCE (after)
120 // CHECK: BoundsCheck
121 // CHECK: ArraySet
122 // CHECK-NOT: BoundsCheck
123 // CHECK: ArraySet
124 // CHECK: BoundsCheck
125 // CHECK: ArraySet
126
127 static void constantIndexing(int[] array) {
128 array[5] = 1;
129 array[4] = 1;
130 array[6] = 1;
131 }
132
133
134 // CHECK-START: void Main.loopPattern1(int[]) BCE (before)
135 // CHECK: BoundsCheck
136 // CHECK: ArraySet
137 // CHECK: BoundsCheck
138 // CHECK: ArraySet
139 // CHECK: BoundsCheck
140 // CHECK: ArraySet
141 // CHECK: BoundsCheck
142 // CHECK: ArraySet
143 // CHECK: BoundsCheck
144 // CHECK: ArraySet
145 // CHECK: BoundsCheck
146 // CHECK: ArraySet
147 // CHECK: BoundsCheck
148 // CHECK: ArraySet
149
150 // CHECK-START: void Main.loopPattern1(int[]) BCE (after)
151 // CHECK-NOT: BoundsCheck
152 // CHECK: ArraySet
153 // CHECK-NOT: BoundsCheck
154 // CHECK: ArraySet
155 // CHECK-NOT: BoundsCheck
156 // CHECK: ArraySet
157 // CHECK: BoundsCheck
158 // CHECK: ArraySet
159 // CHECK: BoundsCheck
160 // CHECK: ArraySet
161 // CHECK: BoundsCheck
162 // CHECK: ArraySet
163 // CHECK-NOT: BoundsCheck
164 // CHECK: ArraySet
165
166 static void loopPattern1(int[] array) {
167 for (int i = 0; i < array.length; i++) {
168 array[i] = 1; // Bounds check can be eliminated.
169 }
170
171 for (int i = 1; i < array.length; i++) {
172 array[i] = 1; // Bounds check can be eliminated.
173 }
174
175 for (int i = 1; i < array.length - 1; i++) {
176 array[i] = 1; // Bounds check can be eliminated.
177 }
178
179 for (int i = -1; i < array.length; i++) {
180 array[i] = 1; // Bounds check can't be eliminated.
181 }
182
183 for (int i = 0; i <= array.length; i++) {
184 array[i] = 1; // Bounds check can't be eliminated.
185 }
186
187 for (int i = 0; i < array.length; i += 2) {
188 // We don't have any assumption on max array length yet.
189 // Bounds check can't be eliminated due to overflow concern.
190 array[i] = 1;
191 }
192
193 for (int i = 1; i < array.length; i += 2) {
194 // Bounds check can be eliminated since i is odd so the last
195 // i that's less than array.length is at most (Integer.MAX_VALUE - 2).
196 array[i] = 1;
197 }
198 }
199
200
201 // CHECK-START: void Main.loopPattern2(int[]) BCE (before)
202 // CHECK: BoundsCheck
203 // CHECK: ArraySet
204 // CHECK: BoundsCheck
205 // CHECK: ArraySet
206 // CHECK: BoundsCheck
207 // CHECK: ArraySet
208 // CHECK: BoundsCheck
209 // CHECK: ArraySet
210 // CHECK: BoundsCheck
211 // CHECK: ArraySet
212 // CHECK: BoundsCheck
213 // CHECK: ArraySet
214
215 // CHECK-START: void Main.loopPattern2(int[]) BCE (after)
216 // CHECK-NOT: BoundsCheck
217 // CHECK: ArraySet
218 // CHECK-NOT: BoundsCheck
219 // CHECK: ArraySet
220 // CHECK-NOT: BoundsCheck
221 // CHECK: ArraySet
222 // CHECK: BoundsCheck
223 // CHECK: ArraySet
224 // CHECK: BoundsCheck
225 // CHECK: ArraySet
226 // CHECK-NOT: BoundsCheck
227 // CHECK: ArraySet
228
229 static void loopPattern2(int[] array) {
230 for (int i = array.length - 1; i >= 0; i--) {
231 array[i] = 1; // Bounds check can be eliminated.
232 }
233
234 for (int i = array.length; i > 0; i--) {
235 array[i - 1] = 1; // Bounds check can be eliminated.
236 }
237
238 for (int i = array.length - 1; i > 0; i--) {
239 array[i] = 1; // Bounds check can be eliminated.
240 }
241
242 for (int i = array.length; i >= 0; i--) {
243 array[i] = 1; // Bounds check can't be eliminated.
244 }
245
246 for (int i = array.length; i >= 0; i--) {
247 array[i - 1] = 1; // Bounds check can't be eliminated.
248 }
249
250 for (int i = array.length; i > 0; i -= 20) {
251 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow.
252 array[i - 1] = 1; // Bounds check can be eliminated.
253 }
254 }
255
256
257 // CHECK-START: void Main.loopPattern3(int[]) BCE (before)
258 // CHECK: BoundsCheck
259 // CHECK: ArraySet
260
261 // CHECK-START: void Main.loopPattern3(int[]) BCE (after)
262 // CHECK: BoundsCheck
263 // CHECK: ArraySet
264
265 static void loopPattern3(int[] array) {
266 java.util.Random random = new java.util.Random();
267 for (int i = 0; ; i++) {
268 if (random.nextInt() % 1000 == 0 && i < array.length) {
269 // Can't eliminate the bound check since not every i++ is
270 // matched with a array length check, so there is some chance that i
271 // overflows and is negative.
272 array[i] = 1;
273 }
274 }
275 }
276
277
278 // CHECK-START: void Main.constantNewArray() BCE (before)
279 // CHECK: BoundsCheck
280 // CHECK: ArraySet
281 // CHECK: BoundsCheck
282 // CHECK: ArraySet
283 // CHECK: BoundsCheck
284 // CHECK: ArraySet
285 // CHECK: BoundsCheck
286 // CHECK: ArraySet
287 // CHECK: BoundsCheck
288 // CHECK: ArraySet
289
290 // CHECK-START: void Main.constantNewArray() BCE (after)
291 // CHECK-NOT: BoundsCheck
292 // CHECK: ArraySet
293 // CHECK: BoundsCheck
294 // CHECK: ArraySet
295 // CHECK-NOT: BoundsCheck
296 // CHECK: ArraySet
297 // CHECK-NOT: BoundsCheck
298 // CHECK: ArraySet
299 // CHECK: BoundsCheck
300 // CHECK: ArraySet
301
302 static void constantNewArray() {
303 int[] array = new int[10];
304 for (int i = 0; i < 10; i++) {
305 array[i] = 1; // Bounds check can be eliminated.
306 }
307
308 for (int i = 0; i <= 10; i++) {
309 array[i] = 1; // Bounds check can't be eliminated.
310 }
311
312 array[0] = 1; // Bounds check can be eliminated.
313 array[9] = 1; // Bounds check can be eliminated.
314 array[10] = 1; // Bounds check can't be eliminated.
315 }
316
317 // CHECK-START: void Main.pyramid1(int[]) BCE (before)
318 // CHECK: BoundsCheck
319 // CHECK: ArraySet
320 // CHECK: BoundsCheck
321 // CHECK: ArraySet
322
323 // CHECK-START: void Main.pyramid1(int[]) BCE (after)
324 // CHECK-NOT: BoundsCheck
325 // CHECK: ArraySet
326 // CHECK-NOT: BoundsCheck
327 // CHECK: ArraySet
328
329 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
330 static void pyramid1(int[] array) {
331 for (int i = 0; i < (array.length + 1) / 2; i++) {
332 array[i] = i;
333 array[array.length - 1 - i] = i;
334 }
335 }
336
337
338 // CHECK-START: void Main.pyramid2(int[]) BCE (before)
339 // CHECK: BoundsCheck
340 // CHECK: ArraySet
341 // CHECK: BoundsCheck
342 // CHECK: ArraySet
343
344 // CHECK-START: void Main.pyramid2(int[]) BCE (after)
345 // CHECK-NOT: BoundsCheck
346 // CHECK: ArraySet
347 // CHECK-NOT: BoundsCheck
348 // CHECK: ArraySet
349
350 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
351 static void pyramid2(int[] array) {
352 for (int i = 0; i < (array.length + 1) >> 1; i++) {
353 array[i] = i;
354 array[array.length - 1 - i] = i;
355 }
356 }
357
358
359 // CHECK-START: void Main.pyramid3(int[]) BCE (before)
360 // CHECK: BoundsCheck
361 // CHECK: ArraySet
362 // CHECK: BoundsCheck
363 // CHECK: ArraySet
364
365 // CHECK-START: void Main.pyramid3(int[]) BCE (after)
366 // CHECK-NOT: BoundsCheck
367 // CHECK: ArraySet
368 // CHECK-NOT: BoundsCheck
369 // CHECK: ArraySet
370
371 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
372 static void pyramid3(int[] array) {
373 for (int i = 0; i < (array.length + 1) >>> 1; i++) {
374 array[i] = i;
375 array[array.length - 1 - i] = i;
376 }
377 }
378
379
Mingyao Yang57e04752015-02-09 18:13:26 -0800380 // CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
381 // CHECK: BoundsCheck
382 // CHECK: ArrayGet
383 // CHECK: BoundsCheck
384 // CHECK: ArrayGet
385
386 // CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
387 // CHECK-NOT: BoundsCheck
388 // CHECK: ArrayGet
389 // CHECK-NOT: BoundsCheck
390 // CHECK: ArrayGet
391
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800392 static boolean isPyramid(int[] array) {
393 int i = 0;
394 int j = array.length - 1;
395 while (i <= j) {
396 if (array[i] != i) {
397 return false;
398 }
399 if (array[j] != i) {
400 return false;
401 }
402 i++; j--;
403 }
404 return true;
405 }
406
407
408 // CHECK-START: void Main.bubbleSort(int[]) GVN (before)
409 // CHECK: BoundsCheck
410 // CHECK: ArrayGet
411 // CHECK: BoundsCheck
412 // CHECK: ArrayGet
413 // CHECK: BoundsCheck
414 // CHECK: ArrayGet
415 // CHECK: BoundsCheck
416 // CHECK: ArrayGet
417 // CHECK: BoundsCheck
418 // CHECK: ArraySet
419 // CHECK: BoundsCheck
420 // CHECK: ArraySet
421
422 // CHECK-START: void Main.bubbleSort(int[]) GVN (after)
423 // CHECK: BoundsCheck
424 // CHECK: ArrayGet
425 // CHECK: BoundsCheck
426 // CHECK: ArrayGet
427 // CHECK-NOT: ArrayGet
428 // CHECK-NOT: ArrayGet
429 // CHECK-NOT: BoundsCheck
430 // CHECK: ArraySet
431 // CHECK-NOT: BoundsCheck
432 // CHECK: ArraySet
433
434 // CHECK-START: void Main.bubbleSort(int[]) BCE (after)
435 // CHECK-NOT: BoundsCheck
436 // CHECK: ArrayGet
437 // CHECK-NOT: BoundsCheck
438 // CHECK: ArrayGet
439 // CHECK-NOT: ArrayGet
440 // CHECK-NOT: ArrayGet
441 // CHECK-NOT: BoundsCheck
442 // CHECK: ArraySet
443 // CHECK-NOT: BoundsCheck
444 // CHECK: ArraySet
445
446 static void bubbleSort(int[] array) {
447 for (int i = 0; i < array.length - 1; i++) {
448 for (int j = 0; j < array.length - i - 1; j++) {
449 if (array[j] > array[j + 1]) {
450 int temp = array[j + 1];
451 array[j + 1] = array[j];
452 array[j] = temp;
453 }
454 }
455 }
456 }
457
458
Mingyao Yang0304e182015-01-30 16:41:29 -0800459 public static void main(String[] args) {
460 sieve(20);
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800461
462 int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
463 bubbleSort(array);
464 for (int i = 0; i < 8; i++) {
465 if (array[i] != i) {
466 System.out.println("bubble sort failed!");
467 }
468 }
469
470 array = new int[7];
471 pyramid1(array);
472 if (!isPyramid(array)) {
473 System.out.println("pyramid1 failed!");
474 }
475
476 array = new int[8];
477 pyramid2(array);
478 if (!isPyramid(array)) {
479 System.out.println("pyramid2 failed!");
480 }
481
482 java.util.Arrays.fill(array, -1);
483 pyramid3(array);
484 if (!isPyramid(array)) {
485 System.out.println("pyramid3 failed!");
486 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800487 }
488}