• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 public class Main {
18 
19   // CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (before)
20   // CHECK:         NullCheck
21   // CHECK:         InvokeStaticOrDirect
22 
23   // CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (after)
24   // CHECK:         NullCheck
25   // CHECK:         InvokeStaticOrDirect
keepTest(Main m)26   public Main keepTest(Main m) {
27     return m.g();
28   }
29 
30   // CHECK-START: Main Main.thisTest() instruction_simplifier (before)
31   // CHECK:         NullCheck
32   // CHECK:         InvokeStaticOrDirect
33 
34   // CHECK-START: Main Main.thisTest() instruction_simplifier (after)
35   // CHECK-NOT:     NullCheck
36   // CHECK:         InvokeStaticOrDirect
thisTest()37   public Main thisTest() {
38     return g();
39   }
40 
41   // CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (before)
42   // CHECK:         NewInstance
43   // CHECK:         NullCheck
44   // CHECK:         InvokeStaticOrDirect
45   // CHECK:         NullCheck
46   // CHECK:         InvokeStaticOrDirect
47 
48   // CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (after)
49   // CHECK-NOT:     NullCheck
newInstanceRemoveTest()50   public Main newInstanceRemoveTest() {
51     Main m = new Main();
52     return m.g();
53   }
54 
55   // CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (before)
56   // CHECK:         NewArray
57   // CHECK:         NullCheck
58   // CHECK:         ArrayGet
59 
60   // CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (after)
61   // CHECK:         NewArray
62   // CHECK-NOT:     NullCheck
63   // CHECK:         ArrayGet
newArrayRemoveTest()64   public Main newArrayRemoveTest() {
65     Main[] ms = new Main[1];
66     return ms[0];
67   }
68 
69   // CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (before)
70   // CHECK:         NewInstance
71   // CHECK:         NullCheck
72 
73   // CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (after)
74   // CHECK:         NewInstance
75   // CHECK-NOT:     NullCheck
ifRemoveTest(boolean flag)76   public Main ifRemoveTest(boolean flag) {
77     Main m = null;
78     if (flag) {
79       m = new Main();
80     } else {
81       m = new Main(1);
82     }
83     return m.g();
84   }
85 
86   // CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (before)
87   // CHECK:         NewInstance
88   // CHECK:         NullCheck
89 
90   // CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (after)
91   // CHECK:         NewInstance
92   // CHECK:         NullCheck
ifKeepTest(boolean flag)93   public Main ifKeepTest(boolean flag) {
94     Main m = null;
95     if (flag) {
96       m = new Main(1);
97     }
98     return m.g();
99   }
100 
101   // CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (before)
102   // CHECK:         NullCheck
103 
104   // CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (after)
105   // CHECK-NOT:     NullCheck
forRemoveTest(int count)106   public Main forRemoveTest(int count) {
107     Main a = new Main();
108     Main m = new Main();
109     for (int i = 0; i < count; i++) {
110       if (i % 2 == 0) {
111         m = a;
112       }
113     }
114     return m.g();
115   }
116 
117   // CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (before)
118   // CHECK:         NullCheck
119 
120   // CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (after)
121   // CHECK:         NullCheck
forKeepTest(int count)122   public Main forKeepTest(int count) {
123     Main a = new Main();
124     Main m = new Main();
125     for (int i = 0; i < count; i++) {
126       if (i % 2 == 0) {
127         m = a;
128       } else {
129         m = null;
130       }
131     }
132     return m.g();
133   }
134 
135   // CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (before)
136   // CHECK:         NullCheck
137 
138   // CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (after)
139   // CHECK-NOT:     NullCheck
phiFlowRemoveTest(int count)140   public Main phiFlowRemoveTest(int count) {
141     Main a = new Main();
142     Main m = new Main();
143     for (int i = 0; i < count; i++) {
144       if (i % 2 == 0) {
145         m = a;
146       }
147     }
148     Main n = new Main();
149     for (int i = 0; i < count; i++) {
150       if (i % 3 == 0) {
151         n = m;
152       }
153     }
154     return n.g();
155   }
156 
157   // CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (before)
158   // CHECK:         NullCheck
159 
160   // CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (after)
161   // CHECK:         NullCheck
phiFlowKeepTest(int count)162   public Main phiFlowKeepTest(int count) {
163     Main a = new Main();
164     Main m = new Main();
165     for (int i = 0; i < count; i++) {
166       if (i % 2 == 0) {
167         m = a;
168       } else {
169         m = null;
170       }
171     }
172     Main n = new Main();
173     for (int i = 0; i < count; i++) {
174       if (i % 3 == 0) {
175         n = m;
176       }
177     }
178     return n.g();
179   }
180 
181   // CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (before)
182   // CHECK:         NullCheck
183 
184   // CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (after)
185   // CHECK-NOT:     NullCheck
scopeRemoveTest(int count, Main a)186   public Main scopeRemoveTest(int count, Main a) {
187     Main m = null;
188     for (int i = 0; i < count; i++) {
189       if (i % 2 == 0) {
190         m = new Main();
191         m.g();
192       } else {
193         m = a;
194       }
195     }
196     return m;
197   }
198 
199   // CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (before)
200   // CHECK:         NullCheck
201 
202   // CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (after)
203   // CHECK:         NullCheck
scopeKeepTest(int count, Main a)204   public Main scopeKeepTest(int count, Main a) {
205     Main m = new Main();
206     for (int i = 0; i < count; i++) {
207       if (i % 2 == 0) {
208         m = a;
209       } else {
210         m = a;
211         m.g();
212       }
213     }
214     return m;
215   }
216 
217   // CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (before)
218   // CHECK:         NullCheck
219 
220   // CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (after)
221   // CHECK-NOT:     NullCheck
scopeIfNotNullRemove(Main m)222   public Main scopeIfNotNullRemove(Main m) {
223     if (m != null) {
224       return m.g();
225     }
226     return m;
227   }
228 
229   // CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (before)
230   // CHECK:         NullCheck
231 
232   // CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (after)
233   // CHECK:         NullCheck
scopeIfKeep(Main m)234   public Main scopeIfKeep(Main m) {
235     if (m == null) {
236       m = new Main();
237     }
238     return m.g();
239   }
240 
Main()241   public Main() {}
Main(int dummy)242   public Main(int dummy) {}
243 
g()244   private Main g() {
245     // avoids inlining
246     throw new RuntimeException();
247   }
248 
main(String[] args)249   public static void main(String[] args) {
250     new Main();
251   }
252 
253 }
254 
255 // Regression for when we created and kept equivalent phis with the same type.
256 // The phi used in comparison would be different then the one used for access
257 // so we could not safely discard it.
258 class ListElement {
259   private ListElement next;
260 
261   // CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (before)
262   // CHECK:         NullCheck
263   // CHECK:         NullCheck
264 
265   // CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (after)
266   // CHECK-NOT:     NullCheck
isShorter(ListElement x, ListElement y)267   static boolean isShorter(ListElement x, ListElement y) {
268     ListElement xTail = x;
269     ListElement yTail = y;
270     while (yTail != null) {
271       if (xTail == null) return true;
272       xTail = xTail.next;
273       yTail = yTail.next;
274     }
275     return false;
276   }
277 }
278