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