1 /*
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 //
21 public 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
unroll()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
unrollLV()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
unrollNest()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 
main(String[] args)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 
expectEquals(int expected, int result)114   private static void expectEquals(int expected, int result) {
115     if (expected != result) {
116       throw new Error("Expected: " + expected + ", found: " + result);
117     }
118   }
119 }
120