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 
18 interface Interface {
f()19   void f();
20 }
21 
22 class Super implements Interface {
f()23   public void f() {
24     throw new RuntimeException();
25   }
26 }
27 
28 class SubclassA extends Super {
f()29   public void f() {
30     throw new RuntimeException();
31   }
32 
h()33   public String h() {
34     throw new RuntimeException();
35   }
36 
g()37   void g() {
38     throw new RuntimeException();
39   }
40 }
41 
42 class SubclassC extends SubclassA {
43 }
44 
45 class SubclassB extends Super {
f()46   public void f() {
47     throw new RuntimeException();
48   }
49 
g()50   void g() {
51     throw new RuntimeException();
52   }
53 }
54 
55 public class Main {
56 
57   // CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (before)
58   // CHECK:         CheckCast
59 
60   // CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (after)
61   // CHECK-NOT:     CheckCast
testSimpleRemove()62   public void testSimpleRemove() {
63     Super s = new SubclassA();
64     ((SubclassA)s).g();
65   }
66 
67   // CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (before)
68   // CHECK:         CheckCast
69 
70   // CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (after)
71   // CHECK:         CheckCast
testSimpleKeep(Super s)72   public void testSimpleKeep(Super s) {
73     ((SubclassA)s).f();
74   }
75 
76   // CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (before)
77   // CHECK:         CheckCast
78 
79   // CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (after)
80   // CHECK-NOT:     CheckCast
testClassRemove()81   public String testClassRemove() {
82     Object s = SubclassA.class;
83     return ((Class)s).getName();
84   }
85 
86   // CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (before)
87   // CHECK:         CheckCast
88 
89   // CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (after)
90   // CHECK:         CheckCast
testClassKeep()91   public String testClassKeep() {
92     Object s = SubclassA.class;
93     return ((SubclassA)s).h();
94   }
95 
96   // CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (before)
97   // CHECK:         CheckCast
98 
99   // CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (after)
100   // CHECK-NOT:     CheckCast
testIfRemove(int x)101   public void testIfRemove(int x) {
102     Super s;
103     if (x % 2 == 0) {
104       s = new SubclassA();
105     } else {
106       s = new SubclassC();
107     }
108     ((SubclassA)s).g();
109   }
110 
111   // CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (before)
112   // CHECK:         CheckCast
113 
114   // CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (after)
115   // CHECK:         CheckCast
testIfKeep(int x)116   public void testIfKeep(int x) {
117     Super s;
118     if (x % 2 == 0) {
119       s = new SubclassA();
120     } else {
121       s = new SubclassB();
122     }
123     ((SubclassA)s).g();
124   }
125 
126   // CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (before)
127   // CHECK:         CheckCast
128 
129   // CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (after)
130   // CHECK-NOT:     CheckCast
testForRemove(int x)131   public void testForRemove(int x) {
132     Super s = new SubclassA();
133     for (int i = 0 ; i < x; i++) {
134       if (x % 2 == 0) {
135         s = new SubclassC();
136       }
137     }
138     ((SubclassA)s).g();
139   }
140 
141   // CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (before)
142   // CHECK:         CheckCast
143 
144   // CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (after)
145   // CHECK:         CheckCast
testForKeep(int x)146   public void testForKeep(int x) {
147     Super s = new SubclassA();
148     for (int i = 0 ; i < x; i++) {
149       if (x % 2 == 0) {
150         s = new SubclassC();
151       }
152     }
153     ((SubclassC)s).g();
154   }
155 
156   // CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (before)
157   // CHECK:         CheckCast
158 
159   // CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (after)
160   // CHECK:         CheckCast
testPhiFromCall(int i)161   public void testPhiFromCall(int i) {
162     Object x;
163     if (i % 2 == 0) {
164       x = new SubclassC();
165     } else {
166       x = newObject();  // this one will have an unknown type.
167     }
168     ((SubclassC)x).g();
169   }
170 
171   // CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (before)
172   // CHECK:         CheckCast
173   // CHECK:         CheckCast
174 
175   // CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (after)
176   // CHECK-NOT:     CheckCast
testInstanceOf(Object o)177   public void testInstanceOf(Object o) {
178     if (o instanceof SubclassC) {
179       ((SubclassC)o).g();
180     }
181     if (o instanceof SubclassB) {
182       ((SubclassB)o).g();
183     }
184   }
185 
186   // CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (before)
187   // CHECK:         CheckCast
188   // CHECK:         CheckCast
189 
190   // CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (after)
191   // CHECK:         CheckCast
192   // CHECK:         CheckCast
testInstanceOfKeep(Object o)193   public void testInstanceOfKeep(Object o) {
194     if (o instanceof SubclassC) {
195       ((SubclassB)o).g();
196     }
197     if (o instanceof SubclassB) {
198       ((SubclassA)o).g();
199     }
200   }
201 
202   // CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (before)
203   // CHECK:         CheckCast
204   // CHECK:         CheckCast
205 
206   // CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (after)
207   // CHECK-NOT:     CheckCast
testInstanceOfNested(Object o)208   public void testInstanceOfNested(Object o) {
209     if (o instanceof SubclassC) {
210       if (o instanceof SubclassB) {
211         ((SubclassB)o).g();
212       } else {
213         ((SubclassC)o).g();
214       }
215     }
216   }
217 
218   // CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (before)
219   // CHECK:         CheckCast
220 
221   // CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (after)
222   // CHECK-NOT:     CheckCast
testInstanceOfWithPhi(int i)223   public void testInstanceOfWithPhi(int i) {
224     Object o;
225     if (i == 0) {
226       o = new SubclassA();
227     } else {
228       o = new SubclassB();
229     }
230 
231     if (o instanceof SubclassB) {
232       ((SubclassB)o).g();
233     }
234   }
235 
236   // CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (before)
237   // CHECK:         CheckCast
238 
239   // CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (after)
240   // CHECK-NOT:     CheckCast
testInstanceOfInFor(int n)241   public void testInstanceOfInFor(int n) {
242     Object o = new SubclassA();
243     for (int i = 0; i < n; i++) {
244       if (i / 2 == 0) {
245         o = new SubclassB();
246       }
247       if (o instanceof SubclassB) {
248         ((SubclassB)o).g();
249       }
250     }
251   }
252 
253   // CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (before)
254   // CHECK:         CheckCast
255 
256   // CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (after)
257   // CHECK-NOT:     CheckCast
testInstanceOfSubclass()258   public void testInstanceOfSubclass() {
259     Object o = new SubclassA();
260     if (o instanceof Super) {
261       ((SubclassA)o).g();
262     }
263   }
264 
265   // CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (before)
266   // CHECK:         CheckCast
267 
268   // CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (after)
269   // CHECK-NOT:     CheckCast
testInstanceOfWithPhiSubclass(int i)270   public void testInstanceOfWithPhiSubclass(int i) {
271     Object o;
272     if (i == 0) {
273       o = new SubclassA();
274     } else {
275       o = new SubclassC();
276     }
277 
278     if (o instanceof Super) {
279       ((SubclassA)o).g();
280     }
281   }
282 
283   // CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (before)
284   // CHECK:         CheckCast
285 
286   // CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (after)
287   // CHECK-NOT:     CheckCast
testInstanceOfWithPhiTop(int i)288   public void testInstanceOfWithPhiTop(int i) {
289     Object o;
290     if (i == 0) {
291       o = new Object();
292     } else {
293       o = new SubclassC();
294     }
295 
296     if (o instanceof Super) {
297       ((Super)o).f();
298     }
299   }
300 
301   // CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (before)
302   // CHECK:         CheckCast
303 
304   // CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (after)
305   // CHECK-NOT:     CheckCast
testInstanceOfSubclassInFor(int n)306   public void testInstanceOfSubclassInFor(int n) {
307     Object o = new SubclassA();
308     for (int i = 0; i < n; i++) {
309       if (o instanceof Super) {
310         ((SubclassA)o).g();
311       }
312       if (i / 2 == 0) {
313         o = new SubclassC();
314       }
315     }
316   }
317 
318   // CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (before)
319   // CHECK:         CheckCast
320 
321   // CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (after)
322   // CHECK-NOT:     CheckCast
testInstanceOfTopInFor(int n)323   public void testInstanceOfTopInFor(int n) {
324     Object o = new SubclassA();
325     for (int i = 0; i < n; i++) {
326       if (o instanceof Super) {
327         ((Super)o).f();
328       }
329       if (i / 2 == 0) {
330         o = new Object();
331       }
332     }
333   }
334 
newObject()335   public Object newObject() {
336     try {
337       return Object.class.newInstance();
338     } catch (Exception e) {
339       return null;
340     }
341   }
342 
main(String[] args)343   public static void main(String[] args) {
344   }
345 }
346