1 /* 2 * Copyright (C) 2016 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 public class ExampleObj { 20 int n1; 21 int n2; 22 ExampleObj(int n1, int n2)23 public ExampleObj(int n1, int n2) { 24 this.n1 = n1; 25 this.n2 = n2; 26 } 27 } 28 29 static int static_variable = 0; 30 31 public ExampleObj my_obj; 32 public static int number1; 33 public static int number2; 34 public static volatile int number3; 35 36 /// CHECK-START-ARM64: int Main.arrayAccess() scheduler (before) 37 /// CHECK: <<Const1:i\d+>> IntConstant 1 38 /// CHECK: <<i0:i\d+>> Phi 39 /// CHECK: <<res0:i\d+>> Phi 40 /// CHECK: <<Array:i\d+>> IntermediateAddress 41 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<i0>>] 42 /// CHECK: <<res1:i\d+>> Add [<<res0>>,<<ArrayGet1>>] 43 /// CHECK: <<i1:i\d+>> Add [<<i0>>,<<Const1>>] 44 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<i1>>] 45 /// CHECK: Add [<<res1>>,<<ArrayGet2>>] 46 47 /// CHECK-START-ARM64: int Main.arrayAccess() scheduler (after) 48 /// CHECK: <<Const1:i\d+>> IntConstant 1 49 /// CHECK: <<i0:i\d+>> Phi 50 /// CHECK: <<res0:i\d+>> Phi 51 /// CHECK: <<Array:i\d+>> IntermediateAddress 52 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<i0>>] 53 /// CHECK: <<i1:i\d+>> Add [<<i0>>,<<Const1>>] 54 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<i1>>] 55 /// CHECK: <<res1:i\d+>> Add [<<res0>>,<<ArrayGet1>>] 56 /// CHECK: Add [<<res1>>,<<ArrayGet2>>] 57 arrayAccess()58 public static int arrayAccess() { 59 int res = 0; 60 int [] array = new int[10]; 61 for (int i = 0; i < 9; i++) { 62 res += array[i]; 63 res += array[i + 1]; 64 } 65 return res; 66 } 67 68 /// CHECK-START-ARM: void Main.arrayAccessVariable(int) scheduler (before) 69 /// CHECK: <<Param:i\d+>> ParameterValue 70 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 71 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 72 /// CHECK-DAG: <<Const3:i\d+>> IntConstant -1 73 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 74 /// CHECK: <<Add2:i\d+>> Add [<<Param>>,<<Const2>>] 75 /// CHECK: <<Add3:i\d+>> Add [<<Param>>,<<Const3>>] 76 /// CHECK: <<Array:i\d+>> IntermediateAddress 77 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 78 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const1>>] 79 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 80 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Add2>>] 81 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const1>>] 82 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Add2>>,<<AddArray2>>] 83 /// CHECK: <<ArrayGet3:i\d+>> ArrayGet [<<Array>>,<<Add3>>] 84 /// CHECK: <<AddArray3:i\d+>> Add [<<ArrayGet3>>,<<Const1>>] 85 /// CHECK: <<ArraySet3:v\d+>> ArraySet [<<Array>>,<<Add3>>,<<AddArray3>>] 86 87 /// CHECK-START-ARM: void Main.arrayAccessVariable(int) scheduler (after) 88 /// CHECK: <<Param:i\d+>> ParameterValue 89 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 90 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 91 /// CHECK-DAG: <<Const3:i\d+>> IntConstant -1 92 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 93 /// CHECK: <<Add2:i\d+>> Add [<<Param>>,<<Const2>>] 94 /// CHECK: <<Add3:i\d+>> Add [<<Param>>,<<Const3>>] 95 /// CHECK: <<Array:i\d+>> IntermediateAddress 96 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 97 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 98 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 99 /// CHECK: Add 100 /// CHECK: Add 101 /// CHECK: Add 102 /// CHECK: ArraySet 103 /// CHECK: ArraySet 104 /// CHECK: ArraySet 105 106 /// CHECK-START-ARM64: void Main.arrayAccessVariable(int) scheduler (before) 107 /// CHECK: <<Param:i\d+>> ParameterValue 108 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 109 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 110 /// CHECK-DAG: <<Const3:i\d+>> IntConstant -1 111 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 112 /// CHECK: <<Add2:i\d+>> Add [<<Param>>,<<Const2>>] 113 /// CHECK: <<Add3:i\d+>> Add [<<Param>>,<<Const3>>] 114 /// CHECK: <<Array:i\d+>> IntermediateAddress 115 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 116 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const1>>] 117 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 118 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Add2>>] 119 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const1>>] 120 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Add2>>,<<AddArray2>>] 121 /// CHECK: <<ArrayGet3:i\d+>> ArrayGet [<<Array>>,<<Add3>>] 122 /// CHECK: <<AddArray3:i\d+>> Add [<<ArrayGet3>>,<<Const1>>] 123 /// CHECK: <<ArraySet3:v\d+>> ArraySet [<<Array>>,<<Add3>>,<<AddArray3>>] 124 125 /// CHECK-START-ARM64: void Main.arrayAccessVariable(int) scheduler (after) 126 /// CHECK: <<Param:i\d+>> ParameterValue 127 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 128 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 129 /// CHECK-DAG: <<Const3:i\d+>> IntConstant -1 130 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 131 /// CHECK: <<Add2:i\d+>> Add [<<Param>>,<<Const2>>] 132 /// CHECK: <<Add3:i\d+>> Add [<<Param>>,<<Const3>>] 133 /// CHECK: <<Array:i\d+>> IntermediateAddress 134 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 135 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 136 /// CHECK: ArrayGet [<<Array>>,{{i\d+}}] 137 /// CHECK: Add 138 /// CHECK: Add 139 /// CHECK: Add 140 /// CHECK: ArraySet 141 /// CHECK: ArraySet 142 /// CHECK: ArraySet arrayAccessVariable(int i)143 public static void arrayAccessVariable(int i) { 144 int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 145 for (int j = 0; j < 100; j++) { 146 array[i + 1]++; 147 array[i + 2]++; 148 array[i - 1]++; 149 } 150 } 151 152 /// CHECK-START-ARM: void Main.arrayAccessSub(int) scheduler (before) 153 /// CHECK: <<Param:i\d+>> ParameterValue 154 /// CHECK-DAG: <<Const1:i\d+>> IntConstant -1 155 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 9 156 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 1 157 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 158 /// CHECK: <<Sub2:i\d+>> Sub [<<Const2>>,<<Param>>] 159 /// CHECK: <<Array:i\d+>> IntermediateAddress 160 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 161 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const3>>] 162 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 163 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Sub2>>] 164 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const3>>] 165 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>] 166 167 /// CHECK-START-ARM: void Main.arrayAccessSub(int) scheduler (after) 168 /// CHECK: <<Param:i\d+>> ParameterValue 169 /// CHECK-DAG: <<Const1:i\d+>> IntConstant -1 170 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 9 171 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 1 172 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 173 /// CHECK: <<Sub2:i\d+>> Sub [<<Const2>>,<<Param>>] 174 /// CHECK: <<Array:i\d+>> IntermediateAddress 175 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 176 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const3>>] 177 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 178 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Sub2>>] 179 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const3>>] 180 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>] 181 182 /// CHECK-START-ARM64: void Main.arrayAccessSub(int) scheduler (before) 183 /// CHECK: <<Param:i\d+>> ParameterValue 184 /// CHECK-DAG: <<Const1:i\d+>> IntConstant -1 185 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 9 186 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 1 187 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 188 /// CHECK: <<Sub2:i\d+>> Sub [<<Const2>>,<<Param>>] 189 /// CHECK: <<Array:i\d+>> IntermediateAddress 190 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 191 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const3>>] 192 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 193 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Sub2>>] 194 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const3>>] 195 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>] 196 197 /// CHECK-START-ARM64: void Main.arrayAccessSub(int) scheduler (after) 198 /// CHECK: <<Param:i\d+>> ParameterValue 199 /// CHECK-DAG: <<Const1:i\d+>> IntConstant -1 200 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 9 201 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 1 202 /// CHECK: <<Add1:i\d+>> Add [<<Param>>,<<Const1>>] 203 /// CHECK: <<Sub2:i\d+>> Sub [<<Const2>>,<<Param>>] 204 /// CHECK: <<Array:i\d+>> IntermediateAddress 205 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<Array>>,<<Add1>>] 206 /// CHECK: <<AddArray1:i\d+>> Add [<<ArrayGet1>>,<<Const3>>] 207 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Array>>,<<Add1>>,<<AddArray1>>] 208 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<Array>>,<<Sub2>>] 209 /// CHECK: <<AddArray2:i\d+>> Add [<<ArrayGet2>>,<<Const3>>] 210 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Array>>,<<Sub2>>,<<AddArray2>>] arrayAccessSub(int i)211 public static void arrayAccessSub(int i) { 212 int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 213 for (int j = 0; j < 100; j++) { 214 // These two accesses MAY ALIAS 215 array[i - 1]++; 216 array[9 - i]++; 217 } 218 } 219 220 /// CHECK-START-ARM: void Main.arrayAccessLoopVariable() scheduler (before) 221 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 222 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 223 /// CHECK: <<Phi:i\d+>> Phi 224 /// CHECK: <<Array:i\d+>> IntermediateAddress 225 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet 226 /// CHECK: <<AddArray1:i\d+>> Add 227 /// CHECK: <<ArraySet1:v\d+>> ArraySet 228 /// CHECK: <<AddVar:i\d+>> Add 229 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet 230 /// CHECK: <<AddArray2:i\d+>> Add 231 /// CHECK: <<ArraySet2:v\d+>> ArraySet 232 233 /// CHECK-START-ARM: void Main.arrayAccessLoopVariable() scheduler (after) 234 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 235 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 236 /// CHECK: <<Phi:i\d+>> Phi 237 /// CHECK: <<Array:i\d+>> IntermediateAddress 238 /// CHECK: <<AddVar:i\d+>> Add 239 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet 240 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet 241 /// CHECK: <<AddArray1:i\d+>> Add 242 /// CHECK: <<AddArray2:i\d+>> Add 243 /// CHECK: <<ArraySet1:v\d+>> ArraySet 244 /// CHECK: <<ArraySet2:v\d+>> ArraySet 245 246 /// CHECK-START-ARM64: void Main.arrayAccessLoopVariable() scheduler (before) 247 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 248 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 249 /// CHECK: <<Phi:i\d+>> Phi 250 /// CHECK: <<Array:i\d+>> IntermediateAddress 251 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet 252 /// CHECK: <<AddArray1:i\d+>> Add 253 /// CHECK: <<ArraySet1:v\d+>> ArraySet 254 /// CHECK: <<AddVar:i\d+>> Add 255 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet 256 /// CHECK: <<AddArray2:i\d+>> Add 257 /// CHECK: <<ArraySet2:v\d+>> ArraySet 258 259 /// CHECK-START-ARM64: void Main.arrayAccessLoopVariable() scheduler (after) 260 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 261 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 262 /// CHECK: <<Phi:i\d+>> Phi 263 /// CHECK: <<Array:i\d+>> IntermediateAddress 264 /// CHECK: <<AddVar:i\d+>> Add 265 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet 266 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet 267 /// CHECK: <<AddArray1:i\d+>> Add 268 /// CHECK: <<AddArray2:i\d+>> Add 269 /// CHECK: <<ArraySet1:v\d+>> ArraySet 270 /// CHECK: <<ArraySet2:v\d+>> ArraySet arrayAccessLoopVariable()271 public static void arrayAccessLoopVariable() { 272 int [] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 273 for (int j = 0; j < 9; j++) { 274 array[j]++; 275 array[j + 1]++; 276 } 277 } 278 279 // This case tests a bug found in LSA where LSA doesn't understand IntermediateAddress, 280 // and incorrectly reported no alias between ArraySet1 and ArrayGet2, 281 // thus ArrayGet2 is scheduled above ArraySet1 incorrectly. 282 283 /// CHECK-START-ARM64: void Main.CrossOverLoop(int[], int[]) scheduler (before) 284 /// CHECK: <<ParamA:l\d+>> ParameterValue loop:none 285 /// CHECK: <<ParamB:l\d+>> ParameterValue loop:none 286 /// CHECK: <<NullB:l\d+>> NullCheck [<<ParamB>>] loop:none 287 /// CHECK: <<NullA:l\d+>> NullCheck [<<ParamA>>] loop:none 288 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 289 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<NullB>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 290 /// CHECK: Add loop:<<Loop>> outer_loop:none 291 /// CHECK: <<Addr1:i\d+>> IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 292 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Addr1>>,{{i\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none 293 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<NullB>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 294 /// CHECK: Add loop:<<Loop>> outer_loop:none 295 /// CHECK: <<Addr2:i\d+>> IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 296 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Addr2>>,{{i\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none 297 /// CHECK: Add loop:<<Loop>> outer_loop:none 298 299 /// CHECK-START-ARM64: void Main.CrossOverLoop(int[], int[]) scheduler (after) 300 /// CHECK: <<ParamA:l\d+>> ParameterValue loop:none 301 /// CHECK: <<ParamB:l\d+>> ParameterValue loop:none 302 /// CHECK: <<NullB:l\d+>> NullCheck [<<ParamB>>] loop:none 303 /// CHECK: <<NullA:l\d+>> NullCheck [<<ParamA>>] loop:none 304 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 305 /// CHECK: <<ArrayGet1:i\d+>> ArrayGet [<<NullB>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 306 /// CHECK: Add loop:<<Loop>> outer_loop:none 307 /// CHECK: <<Addr1:i\d+>> IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 308 /// CHECK: <<ArraySet1:v\d+>> ArraySet [<<Addr1>>,{{i\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none 309 /// CHECK: <<ArrayGet2:i\d+>> ArrayGet [<<NullB>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 310 /// CHECK: Add loop:<<Loop>> outer_loop:none 311 /// CHECK: <<Addr2:i\d+>> IntermediateAddress [<<NullA>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 312 /// CHECK: <<ArraySet2:v\d+>> ArraySet [<<Addr2>>,{{i\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none 313 /// CHECK: Add loop:<<Loop>> outer_loop:none CrossOverLoop(int a[], int b[])314 private static void CrossOverLoop(int a[], int b[]) { 315 b[20] = 99; 316 for (int i = 0; i < a.length; i++) { 317 a[i] = b[20] - 7; 318 i++; 319 a[i] = b[20] - 7; 320 } 321 } 322 323 // This test case is similar to above cross over loop, 324 // but has more complex chains of transforming the original references: 325 // ParameterValue --> BoundType --> NullCheck --> ArrayGet. 326 // ParameterValue --> BoundType --> NullCheck --> IntermediateAddress --> ArraySet. 327 // After using LSA to analyze the orginal references, the scheduler should be able 328 // to find out that 'a' and 'b' may alias, hence unable to schedule these ArraGet/Set. 329 330 /// CHECK-START-ARM64: void Main.CrossOverLoop2(java.lang.Object, java.lang.Object) scheduler (before) 331 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 332 /// CHECK: ArrayGet loop:<<Loop>> outer_loop:none 333 /// CHECK: Add loop:<<Loop>> outer_loop:none 334 /// CHECK: ArraySet loop:<<Loop>> outer_loop:none 335 /// CHECK: ArrayGet loop:<<Loop>> outer_loop:none 336 /// CHECK: Add loop:<<Loop>> outer_loop:none 337 /// CHECK: ArraySet loop:<<Loop>> outer_loop:none 338 339 /// CHECK-START-ARM64: void Main.CrossOverLoop2(java.lang.Object, java.lang.Object) scheduler (after) 340 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 341 /// CHECK: ArrayGet loop:<<Loop>> outer_loop:none 342 /// CHECK: Add loop:<<Loop>> outer_loop:none 343 /// CHECK: ArraySet loop:<<Loop>> outer_loop:none 344 /// CHECK: ArrayGet loop:<<Loop>> outer_loop:none 345 /// CHECK: Add loop:<<Loop>> outer_loop:none 346 /// CHECK: ArraySet loop:<<Loop>> outer_loop:none CrossOverLoop2(Object a, Object b)347 private static void CrossOverLoop2(Object a, Object b) { 348 ((int[])b)[20] = 99; 349 for (int i = 0; i < ((int[])a).length; i++) { 350 ((int[])a)[i] = ((int[])b)[20] - 7; 351 i++; 352 ((int[])a)[i] = ((int[])b)[20] - 7; 353 } 354 } 355 356 /// CHECK-START-ARM: void Main.accessFields() scheduler (before) 357 /// CHECK: InstanceFieldGet 358 /// CHECK: Add 359 /// CHECK: InstanceFieldSet 360 /// CHECK: InstanceFieldGet 361 /// CHECK: Add 362 /// CHECK: InstanceFieldSet 363 /// CHECK: StaticFieldGet 364 /// CHECK: Add 365 /// CHECK: StaticFieldSet 366 /// CHECK: StaticFieldGet 367 /// CHECK: Add 368 /// CHECK: StaticFieldSet 369 370 /// CHECK-START-ARM: void Main.accessFields() scheduler (after) 371 /// CHECK-DAG: InstanceFieldGet 372 /// CHECK-DAG: InstanceFieldGet 373 /// CHECK-DAG: StaticFieldGet 374 /// CHECK-DAG: StaticFieldGet 375 /// CHECK: Add 376 /// CHECK: Add 377 /// CHECK: Add 378 /// CHECK: Add 379 /// CHECK-DAG: InstanceFieldSet 380 /// CHECK-DAG: InstanceFieldSet 381 /// CHECK-DAG: StaticFieldSet 382 /// CHECK-DAG: StaticFieldSet 383 384 /// CHECK-START-ARM64: void Main.accessFields() scheduler (before) 385 /// CHECK: InstanceFieldGet 386 /// CHECK: Add 387 /// CHECK: InstanceFieldSet 388 /// CHECK: InstanceFieldGet 389 /// CHECK: Add 390 /// CHECK: InstanceFieldSet 391 /// CHECK: StaticFieldGet 392 /// CHECK: Add 393 /// CHECK: StaticFieldSet 394 /// CHECK: StaticFieldGet 395 /// CHECK: Add 396 /// CHECK: StaticFieldSet 397 398 /// CHECK-START-ARM64: void Main.accessFields() scheduler (after) 399 /// CHECK-DAG: InstanceFieldGet 400 /// CHECK-DAG: InstanceFieldGet 401 /// CHECK-DAG: StaticFieldGet 402 /// CHECK-DAG: StaticFieldGet 403 /// CHECK: Add 404 /// CHECK: Add 405 /// CHECK: Add 406 /// CHECK: Add 407 /// CHECK-DAG: InstanceFieldSet 408 /// CHECK-DAG: InstanceFieldSet 409 /// CHECK-DAG: StaticFieldSet 410 /// CHECK-DAG: StaticFieldSet accessFields()411 public void accessFields() { 412 my_obj = new ExampleObj(1, 2); 413 for (int i = 0; i < 10; i++) { 414 my_obj.n1++; 415 my_obj.n2++; 416 number1++; 417 number2++; 418 } 419 } 420 421 /// CHECK-START-ARM: void Main.accessFieldsVolatile() scheduler (before) 422 /// CHECK-START-ARM64: void Main.accessFieldsVolatile() scheduler (before) 423 /// CHECK: InstanceFieldGet 424 /// CHECK: Add 425 /// CHECK: InstanceFieldSet 426 /// CHECK: InstanceFieldGet 427 /// CHECK: Add 428 /// CHECK: InstanceFieldSet 429 /// CHECK: StaticFieldGet 430 /// CHECK: Add 431 /// CHECK: StaticFieldSet 432 /// CHECK: StaticFieldGet 433 /// CHECK: Add 434 /// CHECK: StaticFieldSet 435 436 /// CHECK-START-ARM: void Main.accessFieldsVolatile() scheduler (after) 437 /// CHECK-START-ARM64: void Main.accessFieldsVolatile() scheduler (after) 438 /// CHECK: InstanceFieldGet 439 /// CHECK: Add 440 /// CHECK: InstanceFieldSet 441 /// CHECK: InstanceFieldGet 442 /// CHECK: Add 443 /// CHECK: InstanceFieldSet 444 /// CHECK: StaticFieldGet 445 /// CHECK: Add 446 /// CHECK: StaticFieldSet 447 /// CHECK: StaticFieldGet 448 /// CHECK: Add 449 /// CHECK: StaticFieldSet 450 accessFieldsVolatile()451 public void accessFieldsVolatile() { 452 my_obj = new ExampleObj(1, 2); 453 for (int i = 0; i < 10; i++) { 454 my_obj.n1++; 455 my_obj.n2++; 456 number1++; 457 number3++; 458 } 459 } 460 461 /// CHECK-START-ARM: void Main.accessFieldsUnresolved() scheduler (before) 462 /// CHECK-START-ARM64: void Main.accessFieldsUnresolved() scheduler (before) 463 /// CHECK: InstanceFieldGet 464 /// CHECK: Add 465 /// CHECK: InstanceFieldSet 466 /// CHECK: InstanceFieldGet 467 /// CHECK: Add 468 /// CHECK: InstanceFieldSet 469 /// CHECK: UnresolvedInstanceFieldGet 470 /// CHECK: Add 471 /// CHECK: UnresolvedInstanceFieldSet 472 /// CHECK: UnresolvedStaticFieldGet 473 /// CHECK: Add 474 /// CHECK: UnresolvedStaticFieldSet 475 476 /// CHECK-START-ARM: void Main.accessFieldsUnresolved() scheduler (after) 477 /// CHECK-START-ARM64: void Main.accessFieldsUnresolved() scheduler (after) 478 /// CHECK: InstanceFieldGet 479 /// CHECK: Add 480 /// CHECK: InstanceFieldSet 481 /// CHECK: InstanceFieldGet 482 /// CHECK: Add 483 /// CHECK: InstanceFieldSet 484 /// CHECK: UnresolvedInstanceFieldGet 485 /// CHECK: Add 486 /// CHECK: UnresolvedInstanceFieldSet 487 /// CHECK: UnresolvedStaticFieldGet 488 /// CHECK: Add 489 /// CHECK: UnresolvedStaticFieldSet 490 accessFieldsUnresolved()491 public void accessFieldsUnresolved() { 492 my_obj = new ExampleObj(1, 2); 493 UnresolvedClass unresolved_obj = new UnresolvedClass(); 494 for (int i = 0; i < 10; i++) { 495 my_obj.n1++; 496 my_obj.n2++; 497 unresolved_obj.instanceInt++; 498 UnresolvedClass.staticInt++; 499 } 500 } 501 502 /// CHECK-START-ARM64: int Main.intDiv(int) scheduler (before) 503 /// CHECK: Sub 504 /// CHECK: DivZeroCheck 505 /// CHECK: Div 506 /// CHECK: StaticFieldSet 507 508 /// CHECK-START-ARM64: int Main.intDiv(int) scheduler (after) 509 /// CHECK: Sub 510 /// CHECK-NOT: StaticFieldSet 511 /// CHECK: DivZeroCheck 512 /// CHECK-NOT: Sub 513 /// CHECK: Div intDiv(int arg)514 public static int intDiv(int arg) { 515 int res = 0; 516 int tmp = arg; 517 for (int i = 1; i < arg; i++) { 518 tmp -= i; 519 res = res / i; // div-zero check barrier. 520 static_variable++; 521 } 522 res += tmp; 523 return res; 524 } 525 expectEquals(int expected, int result)526 private static void expectEquals(int expected, int result) { 527 if (expected != result) { 528 throw new Error("Expected: " + expected + ", found: " + result); 529 } 530 } 531 532 private static final int ARRAY_SIZE = 32; 533 534 // Check that VecReplicateScalar is not reordered. 535 /// CHECK-START-ARM64: void Main.testVecReplicateScalar() scheduler (before) 536 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 537 /// CHECK: NewArray loop:<<Loop>> outer_loop:none 538 /// CHECK: VecReplicateScalar loop:<<Loop>> outer_loop:none 539 540 /// CHECK-START-ARM64: void Main.testVecReplicateScalar() scheduler (after) 541 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 542 /// CHECK: NewArray loop:<<Loop>> outer_loop:none 543 /// CHECK: VecReplicateScalar loop:<<Loop>> outer_loop:none testVecReplicateScalar()544 private static void testVecReplicateScalar() { 545 for (int j = 0; j <= 8; j++) { 546 int[] a = new int[ARRAY_SIZE]; 547 for (int i = 0; i < a.length; i++) { 548 a[i] += 1; 549 } 550 for (int i = 0; i < a.length; i++) { 551 expectEquals(1, a[i]); 552 } 553 } 554 } 555 556 // Check that VecSetScalars, VecReduce, VecExtractScalar are not reordered. 557 /// CHECK-START-ARM64: void Main.testVecSetScalars() scheduler (before) 558 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 559 /// CHECK: NewArray loop:<<Loop>> outer_loop:none 560 /// CHECK: VecSetScalars loop:<<Loop>> outer_loop:none 561 // 562 /// CHECK: VecReduce loop:<<Loop>> outer_loop:none 563 /// CHECK: VecExtractScalar loop:<<Loop>> outer_loop:none 564 /// CHECK: InvokeStaticOrDirect loop:<<Loop>> outer_loop:none 565 /// CHECK: InvokeStaticOrDirect loop:<<Loop>> outer_loop:none 566 567 /// CHECK-START-ARM64: void Main.testVecSetScalars() scheduler (after) 568 /// CHECK: Phi loop:<<Loop:B\d+>> outer_loop:none 569 /// CHECK: NewArray loop:<<Loop>> outer_loop:none 570 /// CHECK: VecSetScalars loop:<<Loop>> outer_loop:none 571 // 572 /// CHECK: VecReduce loop:<<Loop>> outer_loop:none 573 /// CHECK: VecExtractScalar loop:<<Loop>> outer_loop:none 574 /// CHECK: InvokeStaticOrDirect loop:<<Loop>> outer_loop:none 575 /// CHECK: InvokeStaticOrDirect loop:<<Loop>> outer_loop:none testVecSetScalars()576 private static void testVecSetScalars() { 577 for (int j = 0; j <= 8; j++) { 578 int[] a = new int[ARRAY_SIZE]; 579 int s = 5; 580 for (int i = 0; i < ARRAY_SIZE; i++) { 581 s+=a[i]; 582 } 583 expectEquals(a[0], 0); 584 expectEquals(s, 5); 585 } 586 } 587 main(String[] args)588 public static void main(String[] args) { 589 testVecSetScalars(); 590 testVecReplicateScalar(); 591 if ((arrayAccess() + intDiv(10)) != -35) { 592 System.out.println("FAIL"); 593 } 594 } 595 } 596