1/*
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.div() licm (before)
20  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
21
22  // CHECK-START: int Main.div() licm (after)
23  // CHECK-NOT: Div ( loop_header:{{B\d+}} )
24
25  // CHECK-START: int Main.div() licm (after)
26  // CHECK-DAG: Div ( loop_header:null )
27
28  public static int div() {
29    int result = 0;
30    for (int i = 0; i < 10; ++i) {
31      result += staticField / 42;
32    }
33    return result;
34  }
35
36  // CHECK-START: int Main.innerDiv() licm (before)
37  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
38
39  // CHECK-START: int Main.innerDiv() licm (after)
40  // CHECK-NOT: Div ( loop_header:{{B\d+}} )
41
42  // CHECK-START: int Main.innerDiv() licm (after)
43  // CHECK-DAG: Div ( loop_header:null )
44
45  public static int innerDiv() {
46    int result = 0;
47    for (int i = 0; i < 10; ++i) {
48      for (int j = 0; j < 10; ++j) {
49        result += staticField / 42;
50      }
51    }
52    return result;
53  }
54
55  // CHECK-START: int Main.innerDiv2() licm (before)
56  // CHECK-DAG: Mul ( loop_header:{{B4}} )
57
58  // CHECK-START: int Main.innerDiv2() licm (after)
59  // CHECK-DAG: Mul ( loop_header:{{B2}} )
60
61  public static int innerDiv2() {
62    int result = 0;
63    for (int i = 0; i < 10; ++i) {
64      for (int j = 0; j < 10; ++j) {
65        // The operation has been hoisted out of the inner loop.
66        // Note that we depend on the compiler's block numbering to
67        // check if it has been moved.
68        result += staticField * i;
69      }
70    }
71    return result;
72  }
73
74  // CHECK-START: int Main.innerDiv3(int, int) licm (before)
75  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
76
77  // CHECK-START: int Main.innerDiv3(int, int) licm (after)
78  // CHECK-DAG: Div ( loop_header:{{B\d+}} )
79
80  public static int innerDiv3(int a, int b) {
81    int result = 0;
82    while (b < 5) {
83      // a might be null, so we can't hoist the operation.
84      result += staticField / a;
85      b++;
86    }
87    return result;
88  }
89
90  // CHECK-START: int Main.arrayLength(int[]) licm (before)
91  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck ( loop_header:{{B\d+}} )
92  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] ( loop_header:{{B\d+}} )
93
94  // CHECK-START: int Main.arrayLength(int[]) licm (after)
95  // CHECK-NOT:                    NullCheck ( loop_header:{{B\d+}} )
96  // CHECK-NOT:                    ArrayLength ( loop_header:{{B\d+}} )
97
98  // CHECK-START: int Main.arrayLength(int[]) licm (after)
99  // CHECK-DAG: [[NullCheck:l\d+]] NullCheck ( loop_header:null )
100  // CHECK-DAG:                    ArrayLength [ [[NullCheck]] ] ( loop_header:null )
101
102  public static int arrayLength(int[] array) {
103    int result = 0;
104    for (int i = 0; i < array.length; ++i) {
105      result += array[i];
106    }
107    return result;
108  }
109
110  public static int staticField = 42;
111
112  public static void assertEquals(int expected, int actual) {
113    if (expected != actual) {
114      throw new Error("Expected " + expected + ", got " + actual);
115    }
116  }
117
118  public static void main(String[] args) {
119    assertEquals(10, div());
120    assertEquals(100, innerDiv());
121    assertEquals(12, arrayLength(new int[] { 4, 8 }));
122  }
123}
124