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 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 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 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 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 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 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 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 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 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 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 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 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 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 234 public Main scopeIfKeep(Main m) { 235 if (m == null) { 236 m = new Main(); 237 } 238 return m.g(); 239 } 240 241 public Main() {} 242 public Main(int dummy) {} 243 244 private Main g() { 245 // avoids inlining 246 throw new RuntimeException(); 247 } 248 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 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