blob: 9785bdc58b776686bdb2591dcb7360292e1ad4f7 [file] [log] [blame]
Aart Bik6b69e0a2017-01-11 10:20:43 -08001/*
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// Test on loop unrolling. Removes loop control overhead (including suspend
19// checks) and exposes more opportunities for constant folding.
20//
21public class Main {
22
23 static int sA = 0;
24
25 /// CHECK-START: void Main.unroll() loop_optimization (before)
26 /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
27 /// CHECK-DAG: StaticFieldSet loop:<<Loop>>
28 //
29 /// CHECK-START: void Main.unroll() loop_optimization (after)
30 /// CHECK-DAG: StaticFieldSet loop:none
31 //
32 /// CHECK-START: void Main.unroll() instruction_simplifier$after_bce (after)
33 /// CHECK-DAG: <<Int:i\d+>> IntConstant 68 loop:none
34 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none
35 //
36 /// CHECK-START: void Main.unroll() loop_optimization (after)
37 /// CHECK-NOT: Phi
38 public static void unroll() {
39 for (int i = 4; i < 5; i++) {
40 sA = 17 * i;
41 }
42 }
43
44 /// CHECK-START: int Main.unrollLV() loop_optimization (before)
45 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>>
46 /// CHECK-DAG: StaticFieldSet loop:<<Loop>>
47 /// CHECK-DAG: Return [<<Phi>>] loop:none
48 //
49 /// CHECK-START: int Main.unrollLV() loop_optimization (after)
50 /// CHECK-DAG: StaticFieldSet loop:none
51 //
52 /// CHECK-START: int Main.unrollLV() instruction_simplifier$after_bce (after)
53 /// CHECK-DAG: <<Int1:i\d+>> IntConstant 187 loop:none
54 /// CHECK-DAG: <<Int2:i\d+>> IntConstant 12 loop:none
55 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int1>>] loop:none
56 /// CHECK-DAG: Return [<<Int2>>] loop:none
57 //
58 /// CHECK-START: int Main.unrollLV() loop_optimization (after)
59 /// CHECK-NOT: Phi
60 public static int unrollLV() {
61 int i;
62 for (i = 11; i < 12; i++) {
63 sA = 17 * i;
64 }
65 return i;
66 }
67
68 /// CHECK-START: void Main.unrollNest() loop_optimization (before)
69 /// CHECK-DAG: SuspendCheck loop:none
70 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
71 /// CHECK-DAG: SuspendCheck loop:<<Loop1>> outer_loop:none
72 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
73 /// CHECK-DAG: SuspendCheck loop:<<Loop2>> outer_loop:<<Loop1>>
74 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
75 /// CHECK-DAG: SuspendCheck loop:<<Loop3>> outer_loop:<<Loop2>>
76 /// CHECK-DAG: StaticFieldSet loop:<<Loop3>> outer_loop:<<Loop2>>
77 //
78 /// CHECK-START: void Main.unrollNest() loop_optimization (after)
79 /// CHECK-DAG: StaticFieldSet loop:none
80 /// CHECK-DAG: SuspendCheck loop:none
81 /// CHECK-NOT: SuspendCheck
82 //
83 /// CHECK-START: void Main.unrollNest() instruction_simplifier$after_bce (after)
84 /// CHECK-DAG: <<Int:i\d+>> IntConstant 6 loop:none
85 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none
86 //
87 /// CHECK-START: void Main.unrollNest() loop_optimization (after)
88 /// CHECK-NOT: Phi
89 public static void unrollNest() {
90 // Unrolling each loop in turn ultimately removes the complete nest!
91 for (int i = 4; i < 5; i++) {
92 for (int j = 5; j < 6; j++) {
93 for (int k = 6; k < 7; k++) {
94 sA = k;
95 }
96 }
97 }
98 }
99
100 //
101 // Verifier.
102 //
103
104 public static void main(String[] args) {
105 unroll();
106 expectEquals(68, sA);
107 expectEquals(12, unrollLV());
108 expectEquals(187, sA);
109 unrollNest();
110 expectEquals(6, sA);
111 System.out.println("passed");
112 }
113
114 private static void expectEquals(int expected, int result) {
115 if (expected != result) {
116 throw new Error("Expected: " + expected + ", found: " + result);
117 }
118 }
119}