1 /* 2 * Copyright (C) 2022 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 class TestClass { TestClass()18 TestClass() {} 19 int i; 20 int j; 21 volatile int vi; 22 } 23 24 public class Main { main(String[] args)25 public static void main(String[] args) { 26 // Volatile accesses. 27 assertEquals(3, $noinline$testVolatileAccessesMustBeKept(new TestClass())); 28 assertEquals(3, $noinline$testSingletonVolatileAccessesCanBeRemoved()); 29 30 // Volatile loads - Different fields shouldn't alias. 31 assertEquals(3, $noinline$testVolatileLoadDifferentFields(new TestClass(), new TestClass())); 32 assertEquals( 33 3, $noinline$testVolatileLoadDifferentFieldsBlocking(new TestClass(), new TestClass())); 34 35 // Volatile loads - Redundant store. 36 assertEquals(2, $noinline$testVolatileLoadRedundantStore(new TestClass())); 37 assertEquals(2, $noinline$testVolatileLoadRedundantStoreBlocking(new TestClass())); 38 assertEquals(2, $noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(new TestClass())); 39 40 // Volatile loads - Set and merge values. 41 assertEquals(1, $noinline$testVolatileLoadSetAndMergeValues(new TestClass(), true)); 42 assertEquals(2, $noinline$testVolatileLoadSetAndMergeValues(new TestClass(), false)); 43 assertEquals(1, $noinline$testVolatileLoadSetAndMergeValuesBlocking(new TestClass(), true)); 44 assertEquals(2, $noinline$testVolatileLoadSetAndMergeValuesBlocking(new TestClass(), false)); 45 46 // Volatile loads - Removal - Different fields shouldn't alias. 47 assertEquals(3, 48 $noinline$testVolatileLoadDifferentFieldsRemovedSynchronization( 49 new TestClass(), new TestClass())); 50 51 // Volatile loads - Removal - Redundant store. 52 assertEquals( 53 2, $noinline$testVolatileLoadRedundantStoreRemovedSynchronization(new TestClass())); 54 55 // Volatile loads - Removal - Set and merge values. 56 assertEquals(1, 57 $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization( 58 new TestClass(), true)); 59 assertEquals(2, 60 $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization( 61 new TestClass(), false)); 62 63 // Volatile loads - Removal - with inlining 64 assertEquals(2, $noinline$testVolatileLoadInlineMethodWithSynchronizedScope(new TestClass())); 65 66 // Volatile stores - Different fields shouldn't alias. 67 assertEquals(3, $noinline$testVolatileStoreDifferentFields(new TestClass(), new TestClass())); 68 assertEquals(3, 69 $noinline$testVolatileStoreDifferentFieldsBlocking(new TestClass(), new TestClass())); 70 71 // Volatile stores - Redundant store. 72 assertEquals(2, $noinline$testVolatileStoreRedundantStore(new TestClass())); 73 assertEquals(2, $noinline$testVolatileStoreRedundantStoreBlocking(new TestClass())); 74 assertEquals(2, $noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(new TestClass())); 75 76 // Volatile stores - Set and merge values. 77 assertEquals(1, $noinline$testVolatileStoreSetAndMergeValues(new TestClass(), true)); 78 assertEquals(2, $noinline$testVolatileStoreSetAndMergeValues(new TestClass(), false)); 79 assertEquals(1, $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(new TestClass(), true)); 80 assertEquals( 81 2, $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(new TestClass(), false)); 82 83 // Volatile stores - Removal - Different fields shouldn't alias. 84 assertEquals(3, 85 $noinline$testVolatileStoreDifferentFieldsRemovedSynchronization( 86 new TestClass(), new TestClass())); 87 88 // Volatile stores - Removal - Redundant store. 89 assertEquals( 90 2, $noinline$testVolatileStoreRedundantStoreRemovedSynchronization(new TestClass())); 91 92 // Volatile stores - Removal - Set and merge values. 93 assertEquals(1, 94 $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization( 95 new TestClass(), true)); 96 assertEquals(2, 97 $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization( 98 new TestClass(), false)); 99 100 // Volatile stores - Removal - with inlining 101 assertEquals(2, $noinline$testVolatileStoreInlineMethodWithSynchronizedScope(new TestClass())); 102 103 // Monitor Operations - Different fields shouldn't alias. 104 // Make sure the static variable used for synchronization is non-null. 105 classForSync = new TestClass(); 106 107 assertEquals( 108 3, $noinline$testMonitorOperationDifferentFields(new TestClass(), new TestClass())); 109 assertEquals(3, 110 $noinline$testMonitorOperationDifferentFieldsBlocking( 111 new TestClass(), new TestClass())); 112 113 // Monitor Operations - Redundant store. 114 assertEquals(2, $noinline$testMonitorOperationRedundantStore(new TestClass())); 115 assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlocking(new TestClass())); 116 assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(new TestClass())); 117 assertEquals(2, $noinline$testMonitorOperationRedundantStoreBlockingExit(new TestClass())); 118 119 // Monitor Operations - Set and merge values. 120 assertEquals(1, $noinline$testMonitorOperationSetAndMergeValues(new TestClass(), true)); 121 assertEquals(2, $noinline$testMonitorOperationSetAndMergeValues(new TestClass(), false)); 122 assertEquals(1, $noinline$testMonitorOperationSetAndMergeValuesBlocking(new TestClass(), true)); 123 assertEquals( 124 2, $noinline$testMonitorOperationSetAndMergeValuesBlocking(new TestClass(), false)); 125 126 // Monitor Operations - Removal - Different fields shouldn't alias. 127 assertEquals(3, 128 $noinline$testMonitorOperationDifferentFieldsRemovedSynchronization( 129 new TestClass(), new TestClass())); 130 131 // Monitor Operations - Removal - Redundant store. 132 assertEquals( 133 2, $noinline$testMonitorOperationRedundantStoreRemovedSynchronization(new TestClass())); 134 135 // Monitor Operations - Removal - Set and merge values. 136 assertEquals(1, 137 $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization( 138 new TestClass(), true)); 139 assertEquals(2, 140 $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization( 141 new TestClass(), false)); 142 143 // Monitor Operations - Removal - with inlining 144 assertEquals(2, $noinline$testMonitorOperationInlineSynchronizedMethod(new TestClass())); 145 assertEquals( 146 2, $noinline$testMonitorOperationInlineMethodWithSynchronizedScope(new TestClass())); 147 } 148 assertEquals(int expected, int result)149 public static void assertEquals(int expected, int result) { 150 if (expected != result) { 151 throw new Error("Expected: " + expected + ", found: " + result); 152 } 153 } 154 155 /// CHECK-START: int Main.$noinline$testVolatileAccessesMustBeKept(TestClass) load_store_elimination (before) 156 /// CHECK: InstanceFieldSet 157 /// CHECK: InstanceFieldGet 158 /// CHECK: InstanceFieldGet 159 /// CHECK: InstanceFieldSet 160 /// CHECK: InstanceFieldGet 161 162 /// CHECK-START: int Main.$noinline$testVolatileAccessesMustBeKept(TestClass) load_store_elimination (after) 163 /// CHECK: InstanceFieldSet 164 /// CHECK: InstanceFieldGet 165 /// CHECK: InstanceFieldGet 166 /// CHECK: InstanceFieldSet 167 /// CHECK: InstanceFieldGet $noinline$testVolatileAccessesMustBeKept(TestClass obj1)168 static int $noinline$testVolatileAccessesMustBeKept(TestClass obj1) { 169 int result; 170 obj1.vi = 3; 171 // Redundant load that has to be kept. 172 result = obj1.vi; 173 result = obj1.vi; 174 // Redundant store that has to be kept. 175 obj1.vi = 3; 176 result = obj1.vi; 177 return result; 178 } 179 180 /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (before) 181 /// CHECK: InstanceFieldSet 182 /// CHECK: InstanceFieldGet 183 /// CHECK: InstanceFieldGet 184 /// CHECK: InstanceFieldSet 185 /// CHECK: InstanceFieldGet 186 187 /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (after) 188 /// CHECK-NOT: InstanceFieldSet 189 190 /// CHECK-START: int Main.$noinline$testSingletonVolatileAccessesCanBeRemoved() load_store_elimination (after) 191 /// CHECK-NOT: InstanceFieldGet $noinline$testSingletonVolatileAccessesCanBeRemoved()192 static int $noinline$testSingletonVolatileAccessesCanBeRemoved() { 193 Main m = new Main(); 194 int result; 195 m.vi = 3; 196 // Redundant load can be removed. 197 result = m.vi; 198 result = m.vi; 199 // Redundant store can be removed. 200 m.vi = 3; 201 result = m.vi; 202 return result; 203 } 204 205 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (before) 206 /// CHECK: InstanceFieldGet field_name:TestClass.vi 207 /// CHECK: InstanceFieldSet 208 /// CHECK: InstanceFieldSet 209 /// CHECK: InstanceFieldGet field_name:TestClass.i 210 /// CHECK: InstanceFieldGet field_name:TestClass.j 211 /// CHECK: InstanceFieldGet field_name:TestClass.vi 212 213 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after) 214 /// CHECK: InstanceFieldGet field_name:TestClass.vi 215 /// CHECK: InstanceFieldSet 216 /// CHECK: InstanceFieldSet 217 /// CHECK: InstanceFieldGet field_name:TestClass.vi 218 219 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after) 220 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i 221 222 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFields(TestClass, TestClass) load_store_elimination (after) 223 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j 224 225 // Unrelated volatile loads shouldn't block LSE. $noinline$testVolatileLoadDifferentFields(TestClass obj1, TestClass obj2)226 static int $noinline$testVolatileLoadDifferentFields(TestClass obj1, TestClass obj2) { 227 int unused = obj1.vi; 228 obj1.i = 1; 229 obj2.j = 2; 230 int result = obj1.i + obj2.j; 231 unused = obj1.vi; 232 return result; 233 } 234 235 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before) 236 /// CHECK: InstanceFieldSet 237 /// CHECK: InstanceFieldSet 238 /// CHECK: InstanceFieldGet 239 /// CHECK: InstanceFieldGet 240 /// CHECK: InstanceFieldGet 241 242 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after) 243 /// CHECK: InstanceFieldSet 244 /// CHECK: InstanceFieldSet 245 /// CHECK: InstanceFieldGet 246 /// CHECK: InstanceFieldGet 247 /// CHECK: InstanceFieldGet 248 249 // A volatile load blocks load elimination. $noinline$testVolatileLoadDifferentFieldsBlocking(TestClass obj1, TestClass obj2)250 static int $noinline$testVolatileLoadDifferentFieldsBlocking(TestClass obj1, TestClass obj2) { 251 obj1.i = 1; 252 obj2.j = 2; 253 int unused = obj1.vi; 254 return obj1.i + obj2.j; 255 } 256 257 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (before) 258 /// CHECK: InstanceFieldGet field_name:TestClass.vi 259 /// CHECK: InstanceFieldSet field_name:TestClass.j 260 /// CHECK: InstanceFieldSet field_name:TestClass.j 261 /// CHECK: InstanceFieldGet field_name:TestClass.j 262 263 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after) 264 /// CHECK: InstanceFieldGet field_name:TestClass.vi 265 266 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after) 267 /// CHECK: InstanceFieldSet field_name:TestClass.j 268 /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j 269 270 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStore(TestClass) load_store_elimination (after) 271 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j $noinline$testVolatileLoadRedundantStore(TestClass obj)272 static int $noinline$testVolatileLoadRedundantStore(TestClass obj) { 273 int unused = obj.vi; 274 obj.j = 1; 275 obj.j = 2; 276 return obj.j; 277 } 278 279 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (before) 280 /// CHECK: InstanceFieldSet 281 /// CHECK: InstanceFieldGet 282 /// CHECK: InstanceFieldSet 283 /// CHECK: InstanceFieldGet 284 285 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (after) 286 /// CHECK: InstanceFieldSet 287 /// CHECK: InstanceFieldGet field_name:TestClass.vi 288 /// CHECK: InstanceFieldSet 289 290 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlocking(TestClass) load_store_elimination (after) 291 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j $noinline$testVolatileLoadRedundantStoreBlocking(TestClass obj)292 static int $noinline$testVolatileLoadRedundantStoreBlocking(TestClass obj) { 293 // This store must be kept due to the volatile load. 294 obj.j = 1; 295 int unused = obj.vi; 296 obj.j = 2; 297 return obj.j; 298 } 299 300 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before) 301 /// CHECK: InstanceFieldSet 302 /// CHECK: InstanceFieldSet 303 /// CHECK: InstanceFieldGet 304 /// CHECK: InstanceFieldGet 305 306 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 307 /// CHECK: InstanceFieldSet 308 /// CHECK-NOT: InstanceFieldSet 309 310 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 311 /// CHECK: InstanceFieldGet 312 /// CHECK: InstanceFieldGet $noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass obj)313 static int $noinline$testVolatileLoadRedundantStoreBlockingOnlyLoad(TestClass obj) { 314 // This store can be safely removed. 315 obj.j = 1; 316 obj.j = 2; 317 int unused = obj.vi; 318 // This load remains due to the volatile load in the middle. 319 return obj.j; 320 } 321 322 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (before) 323 /// CHECK-DAG: InstanceFieldSet 324 /// CHECK-DAG: InstanceFieldSet 325 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.i 326 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 327 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 328 329 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 330 /// CHECK-DAG: InstanceFieldSet 331 /// CHECK-DAG: InstanceFieldSet 332 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 333 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 334 335 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 336 /// CHECK: Phi 337 338 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 339 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i 340 $noinline$testVolatileLoadSetAndMergeValues(TestClass obj, boolean b)341 static int $noinline$testVolatileLoadSetAndMergeValues(TestClass obj, boolean b) { 342 if (b) { 343 int unused = obj.vi; 344 obj.i = 1; 345 } else { 346 int unused = obj.vi; 347 obj.i = 2; 348 } 349 return obj.i; 350 } 351 352 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before) 353 /// CHECK-DAG: InstanceFieldSet 354 /// CHECK-DAG: InstanceFieldSet 355 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.i 356 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 357 358 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 359 /// CHECK-DAG: InstanceFieldSet 360 /// CHECK-DAG: InstanceFieldSet 361 /// CHECK-DAG: InstanceFieldGet field_name:TestClass.vi 362 363 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 364 /// CHECK-NOT: Phi 365 366 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 367 /// CHECK: InstanceFieldGet 368 $noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass obj, boolean b)369 static int $noinline$testVolatileLoadSetAndMergeValuesBlocking(TestClass obj, boolean b) { 370 if (b) { 371 obj.i = 1; 372 } else { 373 obj.i = 2; 374 } 375 int unused = obj.vi; 376 return obj.i; 377 } 378 379 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before) 380 /// CHECK: InstanceFieldSet 381 /// CHECK: InstanceFieldSet 382 /// CHECK: InstanceFieldGet field_name:Main.vi 383 /// CHECK: InstanceFieldGet 384 /// CHECK: InstanceFieldGet 385 386 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 387 /// CHECK-NOT: InstanceFieldGet field_name:Main.vi 388 389 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 390 /// CHECK: InstanceFieldSet 391 /// CHECK: InstanceFieldSet 392 393 /// CHECK-START: int Main.$noinline$testVolatileLoadDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 394 /// CHECK-NOT: InstanceFieldGet 395 $noinline$testVolatileLoadDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)396 static int $noinline$testVolatileLoadDifferentFieldsRemovedSynchronization( 397 TestClass obj1, TestClass obj2) { 398 Main m = new Main(); 399 400 obj1.i = 1; 401 obj2.j = 2; 402 int unused = m.vi; 403 404 return obj1.i + obj2.j; 405 } 406 407 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before) 408 /// CHECK: InstanceFieldSet 409 /// CHECK: InstanceFieldGet field_name:Main.vi 410 /// CHECK: InstanceFieldSet 411 /// CHECK: InstanceFieldGet field_name:Main.vi 412 /// CHECK: InstanceFieldGet 413 414 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 415 /// CHECK-NOT: InstanceFieldGet field_name:Main.vi 416 417 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 418 /// CHECK: InstanceFieldSet 419 /// CHECK-NOT: InstanceFieldSet 420 421 /// CHECK-START: int Main.$noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 422 /// CHECK-NOT: InstanceFieldGet 423 $noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass obj)424 static int $noinline$testVolatileLoadRedundantStoreRemovedSynchronization(TestClass obj) { 425 Main m = new Main(); 426 427 obj.j = 1; 428 int unused = m.vi; 429 obj.j = 2; 430 unused = m.vi; 431 432 return obj.j; 433 } 434 435 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before) 436 /// CHECK-DAG: InstanceFieldSet 437 /// CHECK-DAG: InstanceFieldSet 438 /// CHECK-DAG: InstanceFieldGet field_name:Main.vi 439 /// CHECK-DAG: InstanceFieldGet 440 /// CHECK-DAG: Return 441 442 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 443 /// CHECK-DAG: InstanceFieldSet 444 /// CHECK-DAG: InstanceFieldSet 445 /// CHECK-DAG: Return 446 447 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 448 /// CHECK-NOT: InstanceFieldGet field_name:Main.vi 449 450 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 451 /// CHECK: Phi 452 453 /// CHECK-START: int Main.$noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 454 /// CHECK-NOT: InstanceFieldGet 455 $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)456 static int $noinline$testVolatileLoadSetAndMergeValuesRemovedSynchronization( 457 TestClass obj, boolean b) { 458 Main m = new Main(); 459 460 if (b) { 461 obj.i = 1; 462 } else { 463 obj.i = 2; 464 } 465 int unused = m.vi; 466 return obj.i; 467 } 468 469 // Can't eliminate the setters, or volatile getters in this method. 470 471 /// CHECK-START: int Main.$inline$SetterWithVolatileLoads(TestClass) load_store_elimination (before) 472 /// CHECK: InstanceFieldSet field_name:TestClass.j 473 /// CHECK: InstanceFieldGet field_name:Main.vi 474 /// CHECK: InstanceFieldSet field_name:TestClass.j 475 /// CHECK: InstanceFieldGet field_name:Main.vi 476 477 /// CHECK-START: int Main.$inline$SetterWithVolatileLoads(TestClass) load_store_elimination (after) 478 /// CHECK: InstanceFieldSet field_name:TestClass.j 479 /// CHECK: InstanceFieldGet field_name:Main.vi 480 /// CHECK: InstanceFieldSet field_name:TestClass.j 481 /// CHECK: InstanceFieldGet field_name:Main.vi $inline$SetterWithVolatileLoads(TestClass obj)482 int $inline$SetterWithVolatileLoads(TestClass obj) { 483 obj.j = 1; 484 int unused = this.vi; 485 obj.j = 2; 486 unused = this.vi; 487 return obj.j; 488 } 489 490 // But we can eliminate once inlined. 491 492 /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before) 493 /// CHECK: InstanceFieldSet field_name:TestClass.j 494 /// CHECK: InstanceFieldGet field_name:Main.vi 495 /// CHECK: InstanceFieldSet field_name:TestClass.j 496 /// CHECK: InstanceFieldGet field_name:Main.vi 497 498 /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 499 /// CHECK-NOT: InstanceFieldGet field_name:Main.vi 500 501 /// CHECK-START: int Main.$noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 502 /// CHECK: InstanceFieldSet field_name:TestClass.j 503 /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j $noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass obj)504 static int $noinline$testVolatileLoadInlineMethodWithSynchronizedScope(TestClass obj) { 505 Main m = new Main(); 506 return m.$inline$SetterWithVolatileLoads(obj); 507 } 508 509 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (before) 510 /// CHECK: InstanceFieldSet field_name:TestClass.vi 511 /// CHECK: InstanceFieldSet 512 /// CHECK: InstanceFieldSet 513 /// CHECK: InstanceFieldGet field_name:TestClass.i 514 /// CHECK: InstanceFieldGet field_name:TestClass.j 515 /// CHECK: InstanceFieldSet field_name:TestClass.vi 516 517 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after) 518 /// CHECK: InstanceFieldSet field_name:TestClass.vi 519 /// CHECK: InstanceFieldSet 520 /// CHECK: InstanceFieldSet 521 /// CHECK: InstanceFieldSet field_name:TestClass.vi 522 523 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after) 524 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.i 525 526 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFields(TestClass, TestClass) load_store_elimination (after) 527 /// CHECK-NOT: InstanceFieldGet field_name:TestClass.j 528 529 // Unrelated volatile stores shouldn't block LSE. $noinline$testVolatileStoreDifferentFields(TestClass obj1, TestClass obj2)530 static int $noinline$testVolatileStoreDifferentFields(TestClass obj1, TestClass obj2) { 531 obj1.vi = 123; 532 obj1.i = 1; 533 obj2.j = 2; 534 int result = obj1.i + obj2.j; 535 obj1.vi = 123; 536 return result; 537 } 538 539 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before) 540 /// CHECK: InstanceFieldSet 541 /// CHECK: InstanceFieldSet 542 /// CHECK: InstanceFieldSet 543 /// CHECK: InstanceFieldGet 544 /// CHECK: InstanceFieldGet 545 546 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after) 547 /// CHECK: InstanceFieldSet 548 /// CHECK: InstanceFieldSet 549 /// CHECK: InstanceFieldSet 550 551 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after) 552 /// CHECK-NOT: InstanceFieldGet 553 554 // A volatile store doesn't block load elimination, as it doesn't clobber existing values. $noinline$testVolatileStoreDifferentFieldsBlocking(TestClass obj1, TestClass obj2)555 static int $noinline$testVolatileStoreDifferentFieldsBlocking(TestClass obj1, TestClass obj2) { 556 obj1.i = 1; 557 obj2.j = 2; 558 obj1.vi = 123; 559 return obj1.i + obj2.j; 560 } 561 562 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (before) 563 /// CHECK: InstanceFieldSet field_name:TestClass.vi 564 /// CHECK: InstanceFieldSet field_name:TestClass.j 565 /// CHECK: InstanceFieldSet field_name:TestClass.j 566 /// CHECK: InstanceFieldGet 567 568 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (after) 569 /// CHECK: InstanceFieldSet field_name:TestClass.vi 570 /// CHECK: InstanceFieldSet field_name:TestClass.j 571 /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j 572 573 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStore(TestClass) load_store_elimination (after) 574 /// CHECK-NOT: InstanceFieldGet $noinline$testVolatileStoreRedundantStore(TestClass obj)575 static int $noinline$testVolatileStoreRedundantStore(TestClass obj) { 576 obj.vi = 123; 577 obj.j = 1; 578 obj.j = 2; 579 return obj.j; 580 } 581 582 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (before) 583 /// CHECK: InstanceFieldSet 584 /// CHECK: InstanceFieldSet 585 /// CHECK: InstanceFieldSet 586 /// CHECK: InstanceFieldGet 587 588 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (after) 589 /// CHECK: InstanceFieldSet 590 /// CHECK: InstanceFieldSet 591 /// CHECK: InstanceFieldSet 592 593 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlocking(TestClass) load_store_elimination (after) 594 /// CHECK-NOT: InstanceFieldGet $noinline$testVolatileStoreRedundantStoreBlocking(TestClass obj)595 static int $noinline$testVolatileStoreRedundantStoreBlocking(TestClass obj) { 596 // This store must be kept due to the volatile store. 597 obj.j = 1; 598 obj.vi = 123; 599 obj.j = 2; 600 return obj.j; 601 } 602 603 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before) 604 /// CHECK: InstanceFieldSet field_name:TestClass.j 605 /// CHECK: InstanceFieldSet field_name:TestClass.j 606 /// CHECK: InstanceFieldSet field_name:TestClass.vi 607 /// CHECK: InstanceFieldGet 608 609 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 610 /// CHECK: InstanceFieldSet field_name:TestClass.j 611 /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j 612 613 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 614 /// CHECK: InstanceFieldSet field_name:TestClass.vi 615 616 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 617 /// CHECK-NOT: InstanceFieldGet $noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass obj)618 static int $noinline$testVolatileStoreRedundantStoreBlockingOnlyLoad(TestClass obj) { 619 // This store can be safely removed. 620 obj.j = 1; 621 obj.j = 2; 622 obj.vi = 123; 623 // This load can also be safely eliminated as the volatile store doesn't clobber values. 624 return obj.j; 625 } 626 627 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (before) 628 /// CHECK-DAG: InstanceFieldSet 629 /// CHECK-DAG: InstanceFieldSet 630 /// CHECK-DAG: InstanceFieldSet 631 /// CHECK-DAG: InstanceFieldSet 632 /// CHECK-DAG: InstanceFieldGet 633 634 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 635 /// CHECK-DAG: InstanceFieldSet 636 /// CHECK-DAG: InstanceFieldSet 637 /// CHECK-DAG: InstanceFieldSet 638 /// CHECK-DAG: InstanceFieldSet 639 640 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 641 /// CHECK: Phi 642 643 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 644 /// CHECK-NOT: InstanceFieldGet $noinline$testVolatileStoreSetAndMergeValues(TestClass obj, boolean b)645 static int $noinline$testVolatileStoreSetAndMergeValues(TestClass obj, boolean b) { 646 if (b) { 647 obj.vi = 123; 648 obj.i = 1; 649 } else { 650 obj.vi = 123; 651 obj.i = 2; 652 } 653 return obj.i; 654 } 655 656 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass, boolean) load_store_elimination (before) 657 /// CHECK-DAG: InstanceFieldSet 658 /// CHECK-DAG: InstanceFieldSet 659 /// CHECK-DAG: InstanceFieldSet 660 /// CHECK-DAG: InstanceFieldGet 661 662 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass, boolean) load_store_elimination (after) 663 /// CHECK-DAG: InstanceFieldSet 664 /// CHECK-DAG: InstanceFieldSet 665 /// CHECK-DAG: InstanceFieldSet 666 667 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 668 /// CHECK: Phi 669 670 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 671 /// CHECK-NOT: InstanceFieldGet $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass obj, boolean b)672 static int $noinline$testVolatileStoreSetAndMergeValuesNotBlocking(TestClass obj, boolean b) { 673 if (b) { 674 obj.i = 1; 675 } else { 676 obj.i = 2; 677 } 678 // This volatile store doesn't block the load elimination 679 obj.vi = 123; 680 return obj.i; 681 } 682 683 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before) 684 /// CHECK: InstanceFieldSet 685 /// CHECK: InstanceFieldSet 686 /// CHECK: InstanceFieldSet field_name:Main.vi 687 /// CHECK: InstanceFieldGet 688 /// CHECK: InstanceFieldGet 689 690 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 691 /// CHECK-NOT: InstanceFieldSet field_name:Main.vi 692 693 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 694 /// CHECK: InstanceFieldSet 695 /// CHECK: InstanceFieldSet 696 697 /// CHECK-START: int Main.$noinline$testVolatileStoreDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 698 /// CHECK-NOT: InstanceFieldGet 699 $noinline$testVolatileStoreDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)700 static int $noinline$testVolatileStoreDifferentFieldsRemovedSynchronization( 701 TestClass obj1, TestClass obj2) { 702 Main m = new Main(); 703 704 obj1.i = 1; 705 obj2.j = 2; 706 m.vi = 123; 707 708 return obj1.i + obj2.j; 709 } 710 711 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before) 712 /// CHECK: InstanceFieldSet 713 /// CHECK: InstanceFieldSet 714 /// CHECK: InstanceFieldSet 715 /// CHECK: InstanceFieldSet 716 /// CHECK: InstanceFieldGet 717 718 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 719 /// CHECK-NOT: InstanceFieldSet field_name:Main.vi 720 721 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 722 /// CHECK: InstanceFieldSet 723 /// CHECK-NOT: InstanceFieldSet 724 725 /// CHECK-START: int Main.$noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 726 /// CHECK-NOT: InstanceFieldGet 727 $noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass obj)728 static int $noinline$testVolatileStoreRedundantStoreRemovedSynchronization(TestClass obj) { 729 Main m = new Main(); 730 731 obj.j = 1; 732 m.vi = 123; 733 obj.j = 2; 734 m.vi = 123; 735 736 return obj.j; 737 } 738 739 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before) 740 /// CHECK-DAG: InstanceFieldSet 741 /// CHECK-DAG: InstanceFieldSet 742 /// CHECK-DAG: InstanceFieldSet 743 /// CHECK-DAG: InstanceFieldGet 744 /// CHECK-DAG: Return 745 746 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 747 /// CHECK-DAG: InstanceFieldSet 748 /// CHECK-DAG: InstanceFieldSet 749 /// CHECK-DAG: Return 750 751 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 752 /// CHECK-NOT: InstanceFieldSet field_name:Main.vi 753 754 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 755 /// CHECK: Phi 756 757 /// CHECK-START: int Main.$noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 758 /// CHECK-NOT: InstanceFieldGet 759 $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)760 static int $noinline$testVolatileStoreSetAndMergeValuesRemovedSynchronization( 761 TestClass obj, boolean b) { 762 Main m = new Main(); 763 764 if (b) { 765 obj.i = 1; 766 } else { 767 obj.i = 2; 768 } 769 m.vi = 123; 770 return obj.i; 771 } 772 773 // Can't eliminate the setters in this method. 774 775 /// CHECK-START: int Main.$inline$SetterWithVolatileStores(TestClass) load_store_elimination (before) 776 /// CHECK: InstanceFieldSet field_name:TestClass.j 777 /// CHECK: InstanceFieldSet field_name:Main.vi 778 /// CHECK: InstanceFieldSet field_name:TestClass.j 779 /// CHECK: InstanceFieldSet field_name:Main.vi 780 781 /// CHECK-START: int Main.$inline$SetterWithVolatileStores(TestClass) load_store_elimination (after) 782 /// CHECK: InstanceFieldSet field_name:TestClass.j 783 /// CHECK: InstanceFieldSet field_name:Main.vi 784 /// CHECK: InstanceFieldSet field_name:TestClass.j 785 /// CHECK: InstanceFieldSet field_name:Main.vi $inline$SetterWithVolatileStores(TestClass obj)786 int $inline$SetterWithVolatileStores(TestClass obj) { 787 obj.j = 1; 788 this.vi = 123; 789 obj.j = 2; 790 this.vi = 123; 791 return obj.j; 792 } 793 794 // But we can eliminate once inlined. 795 796 /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before) 797 /// CHECK: InstanceFieldSet field_name:TestClass.j 798 /// CHECK: InstanceFieldSet field_name:Main.vi 799 /// CHECK: InstanceFieldSet field_name:TestClass.j 800 /// CHECK: InstanceFieldSet field_name:Main.vi 801 802 /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 803 /// CHECK-NOT: InstanceFieldSet field_name:Main.vi 804 805 /// CHECK-START: int Main.$noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 806 /// CHECK: InstanceFieldSet field_name:TestClass.j 807 /// CHECK-NOT: InstanceFieldSet field_name:TestClass.j $noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass obj)808 static int $noinline$testVolatileStoreInlineMethodWithSynchronizedScope(TestClass obj) { 809 Main m = new Main(); 810 return m.$inline$SetterWithVolatileStores(obj); 811 } 812 813 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (before) 814 /// CHECK: InstanceFieldSet 815 /// CHECK: InstanceFieldSet 816 /// CHECK: InstanceFieldGet 817 /// CHECK: InstanceFieldGet 818 819 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (before) 820 /// CHECK: MonitorOperation kind:enter 821 /// CHECK: MonitorOperation kind:exit 822 /// CHECK: MonitorOperation kind:enter 823 /// CHECK: MonitorOperation kind:exit 824 825 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (after) 826 /// CHECK: InstanceFieldSet 827 /// CHECK: InstanceFieldSet 828 829 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFields(TestClass, TestClass) load_store_elimination (after) 830 /// CHECK-NOT: InstanceFieldGet 831 832 // Unrelated monitor operations shouldn't block LSE. $noinline$testMonitorOperationDifferentFields(TestClass obj1, TestClass obj2)833 static int $noinline$testMonitorOperationDifferentFields(TestClass obj1, TestClass obj2) { 834 synchronized (classForSync) {} 835 obj1.i = 1; 836 obj2.j = 2; 837 int result = obj1.i + obj2.j; 838 synchronized (classForSync) {} 839 return result; 840 } 841 842 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before) 843 /// CHECK: InstanceFieldSet 844 /// CHECK: InstanceFieldSet 845 /// CHECK: InstanceFieldGet 846 /// CHECK: InstanceFieldGet 847 848 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (before) 849 /// CHECK: MonitorOperation kind:enter 850 /// CHECK: MonitorOperation kind:exit 851 852 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsBlocking(TestClass, TestClass) load_store_elimination (after) 853 /// CHECK: InstanceFieldSet 854 /// CHECK: InstanceFieldSet 855 /// CHECK: InstanceFieldGet 856 /// CHECK: InstanceFieldGet 857 858 // A synchronized operation blocks loads. $noinline$testMonitorOperationDifferentFieldsBlocking(TestClass obj1, TestClass obj2)859 static int $noinline$testMonitorOperationDifferentFieldsBlocking(TestClass obj1, TestClass obj2) { 860 obj1.i = 1; 861 obj2.j = 2; 862 synchronized (classForSync) { 863 return obj1.i + obj2.j; 864 } 865 } 866 867 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (before) 868 /// CHECK: InstanceFieldSet 869 /// CHECK: InstanceFieldSet 870 /// CHECK: InstanceFieldGet 871 872 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (before) 873 /// CHECK: MonitorOperation kind:enter 874 /// CHECK: MonitorOperation kind:exit 875 876 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (after) 877 /// CHECK: InstanceFieldSet 878 /// CHECK-NOT: InstanceFieldSet 879 880 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStore(TestClass) load_store_elimination (after) 881 /// CHECK-NOT: InstanceFieldGet 882 $noinline$testMonitorOperationRedundantStore(TestClass obj)883 static int $noinline$testMonitorOperationRedundantStore(TestClass obj) { 884 synchronized (classForSync) { 885 obj.j = 1; 886 obj.j = 2; 887 } 888 return obj.j; 889 } 890 891 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (before) 892 /// CHECK: InstanceFieldSet 893 /// CHECK: InstanceFieldSet 894 /// CHECK: InstanceFieldGet 895 896 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (before) 897 /// CHECK: MonitorOperation kind:enter 898 /// CHECK: MonitorOperation kind:exit 899 900 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (after) 901 /// CHECK: InstanceFieldSet 902 /// CHECK: InstanceFieldSet 903 904 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlocking(TestClass) load_store_elimination (after) 905 /// CHECK-NOT: InstanceFieldGet 906 $noinline$testMonitorOperationRedundantStoreBlocking(TestClass obj)907 static int $noinline$testMonitorOperationRedundantStoreBlocking(TestClass obj) { 908 // This store must be kept due to the monitor operation. 909 obj.j = 1; 910 synchronized (classForSync) {} 911 obj.j = 2; 912 return obj.j; 913 } 914 915 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before) 916 /// CHECK: InstanceFieldSet 917 /// CHECK: InstanceFieldSet 918 /// CHECK: InstanceFieldGet 919 920 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (before) 921 /// CHECK: MonitorOperation kind:enter 922 /// CHECK: MonitorOperation kind:exit 923 924 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 925 /// CHECK: InstanceFieldSet 926 /// CHECK-NOT: InstanceFieldSet 927 928 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass) load_store_elimination (after) 929 /// CHECK: InstanceFieldGet 930 $noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass obj)931 static int $noinline$testMonitorOperationRedundantStoreBlockingOnlyLoad(TestClass obj) { 932 // This store can be safely removed. 933 obj.j = 1; 934 obj.j = 2; 935 synchronized (classForSync) {} 936 // This load remains due to the monitor operation. 937 return obj.j; 938 } 939 940 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (before) 941 /// CHECK: InstanceFieldSet 942 /// CHECK: InstanceFieldSet 943 /// CHECK: InstanceFieldSet 944 /// CHECK: InstanceFieldGet 945 946 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (before) 947 /// CHECK: MonitorOperation kind:enter 948 /// CHECK: MonitorOperation kind:exit 949 950 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (after) 951 /// CHECK: InstanceFieldSet 952 /// CHECK: InstanceFieldSet 953 /// CHECK-NOT: InstanceFieldSet 954 955 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass) load_store_elimination (after) 956 /// CHECK-NOT: InstanceFieldGet 957 $noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass obj)958 static int $noinline$testMonitorOperationRedundantStoreBlockingExit(TestClass obj) { 959 synchronized (classForSync) { 960 // This store can be removed. 961 obj.j = 0; 962 // This store must be kept due to the monitor exit operation. 963 obj.j = 1; 964 } 965 obj.j = 2; 966 return obj.j; 967 } 968 969 970 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (before) 971 /// CHECK-DAG: InstanceFieldSet 972 /// CHECK-DAG: InstanceFieldSet 973 /// CHECK-DAG: InstanceFieldGet 974 975 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 976 /// CHECK-DAG: InstanceFieldSet 977 /// CHECK-DAG: InstanceFieldSet 978 979 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (before) 980 /// CHECK-DAG: MonitorOperation kind:enter 981 /// CHECK-DAG: MonitorOperation kind:exit 982 /// CHECK-DAG: MonitorOperation kind:enter 983 /// CHECK-DAG: MonitorOperation kind:exit 984 985 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 986 /// CHECK: Phi 987 988 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValues(TestClass, boolean) load_store_elimination (after) 989 /// CHECK-NOT: InstanceFieldGet 990 $noinline$testMonitorOperationSetAndMergeValues(TestClass obj, boolean b)991 static int $noinline$testMonitorOperationSetAndMergeValues(TestClass obj, boolean b) { 992 if (b) { 993 synchronized (classForSync) {} 994 obj.i = 1; 995 } else { 996 synchronized (classForSync) {} 997 obj.i = 2; 998 } 999 return obj.i; 1000 } 1001 1002 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before) 1003 /// CHECK-DAG: InstanceFieldSet 1004 /// CHECK-DAG: InstanceFieldSet 1005 /// CHECK-DAG: InstanceFieldGet 1006 1007 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 1008 /// CHECK-DAG: InstanceFieldSet 1009 /// CHECK-DAG: InstanceFieldSet 1010 1011 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (before) 1012 /// CHECK-DAG: MonitorOperation kind:enter 1013 /// CHECK-DAG: MonitorOperation kind:exit 1014 1015 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 1016 /// CHECK-NOT: Phi 1017 1018 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass, boolean) load_store_elimination (after) 1019 /// CHECK: InstanceFieldGet 1020 $noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass obj, boolean b)1021 static int $noinline$testMonitorOperationSetAndMergeValuesBlocking(TestClass obj, boolean b) { 1022 if (b) { 1023 obj.i = 1; 1024 } else { 1025 obj.i = 2; 1026 } 1027 synchronized (classForSync) {} 1028 return obj.i; 1029 } 1030 1031 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before) 1032 /// CHECK: InstanceFieldSet 1033 /// CHECK: InstanceFieldSet 1034 /// CHECK: InstanceFieldGet 1035 /// CHECK: InstanceFieldGet 1036 1037 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (before) 1038 /// CHECK: MonitorOperation kind:enter 1039 /// CHECK: MonitorOperation kind:exit 1040 1041 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 1042 /// CHECK-NOT: MonitorOperation 1043 1044 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 1045 /// CHECK: InstanceFieldSet 1046 /// CHECK: InstanceFieldSet 1047 1048 /// CHECK-START: int Main.$noinline$testMonitorOperationDifferentFieldsRemovedSynchronization(TestClass, TestClass) load_store_elimination (after) 1049 /// CHECK-NOT: InstanceFieldGet 1050 $noinline$testMonitorOperationDifferentFieldsRemovedSynchronization( TestClass obj1, TestClass obj2)1051 static int $noinline$testMonitorOperationDifferentFieldsRemovedSynchronization( 1052 TestClass obj1, TestClass obj2) { 1053 Main m = new Main(); 1054 1055 obj1.i = 1; 1056 obj2.j = 2; 1057 synchronized (m) {} 1058 1059 return obj1.i + obj2.j; 1060 } 1061 1062 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before) 1063 /// CHECK: InstanceFieldSet 1064 /// CHECK: InstanceFieldSet 1065 /// CHECK: InstanceFieldGet 1066 1067 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (before) 1068 /// CHECK: MonitorOperation kind:enter 1069 /// CHECK: MonitorOperation kind:exit 1070 /// CHECK: MonitorOperation kind:enter 1071 /// CHECK: MonitorOperation kind:exit 1072 1073 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 1074 /// CHECK-NOT: MonitorOperation 1075 1076 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 1077 /// CHECK: InstanceFieldSet 1078 /// CHECK-NOT: InstanceFieldSet 1079 1080 /// CHECK-START: int Main.$noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass) load_store_elimination (after) 1081 /// CHECK-NOT: InstanceFieldGet $noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass obj)1082 static int $noinline$testMonitorOperationRedundantStoreRemovedSynchronization(TestClass obj) { 1083 Main m = new Main(); 1084 1085 obj.j = 1; 1086 synchronized (m) {} 1087 obj.j = 2; 1088 synchronized (m) {} 1089 1090 return obj.j; 1091 } 1092 1093 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before) 1094 /// CHECK-DAG: InstanceFieldSet 1095 /// CHECK-DAG: InstanceFieldSet 1096 /// CHECK-DAG: InstanceFieldGet 1097 /// CHECK-DAG: Return 1098 1099 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 1100 /// CHECK-DAG: InstanceFieldSet 1101 /// CHECK-DAG: InstanceFieldSet 1102 /// CHECK-DAG: Return 1103 1104 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (before) 1105 /// CHECK-DAG: MonitorOperation kind:enter 1106 /// CHECK-DAG: MonitorOperation kind:exit 1107 1108 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 1109 /// CHECK-NOT: MonitorOperation 1110 1111 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 1112 /// CHECK: Phi 1113 1114 /// CHECK-START: int Main.$noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization(TestClass, boolean) load_store_elimination (after) 1115 /// CHECK-NOT: InstanceFieldGet $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization( TestClass obj, boolean b)1116 static int $noinline$testMonitorOperationSetAndMergeValuesRemovedSynchronization( 1117 TestClass obj, boolean b) { 1118 Main m = new Main(); 1119 1120 if (b) { 1121 obj.i = 1; 1122 } else { 1123 obj.i = 2; 1124 } 1125 synchronized (m) {} 1126 return obj.i; 1127 } 1128 $inline$synchronizedSetter(TestClass obj)1129 synchronized int $inline$synchronizedSetter(TestClass obj) { 1130 obj.j = 1; 1131 obj.j = 2; 1132 return obj.j; 1133 } 1134 1135 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) inliner (before) 1136 /// CHECK-NOT: MonitorOperation 1137 1138 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) inliner (after) 1139 /// CHECK: MonitorOperation kind:enter 1140 /// CHECK: MonitorOperation kind:exit 1141 1142 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (before) 1143 /// CHECK: MonitorOperation kind:enter 1144 /// CHECK: MonitorOperation kind:exit 1145 1146 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (before) 1147 /// CHECK: InstanceFieldSet 1148 /// CHECK: InstanceFieldSet 1149 /// CHECK-NOT: InstanceFieldSet 1150 1151 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (after) 1152 /// CHECK-NOT: MonitorOperation 1153 1154 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineSynchronizedMethod(TestClass) load_store_elimination (after) 1155 /// CHECK: InstanceFieldSet 1156 /// CHECK-NOT: InstanceFieldSet $noinline$testMonitorOperationInlineSynchronizedMethod(TestClass obj)1157 static int $noinline$testMonitorOperationInlineSynchronizedMethod(TestClass obj) { 1158 Main m = new Main(); 1159 return m.$inline$synchronizedSetter(obj); 1160 } 1161 $inline$SetterWithSynchronizedScope(TestClass obj)1162 int $inline$SetterWithSynchronizedScope(TestClass obj) { 1163 synchronized (this) { 1164 obj.j = 1; 1165 obj.j = 2; 1166 return obj.j; 1167 } 1168 } 1169 1170 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) inliner (before) 1171 /// CHECK-NOT: MonitorOperation 1172 1173 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) inliner (after) 1174 /// CHECK: MonitorOperation kind:enter 1175 /// CHECK: MonitorOperation kind:exit 1176 1177 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before) 1178 /// CHECK: MonitorOperation kind:enter 1179 /// CHECK: MonitorOperation kind:exit 1180 1181 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (before) 1182 /// CHECK: InstanceFieldSet 1183 /// CHECK: InstanceFieldSet 1184 /// CHECK-NOT: InstanceFieldSet 1185 1186 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 1187 /// CHECK-NOT: MonitorOperation 1188 1189 /// CHECK-START: int Main.$noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass) load_store_elimination (after) 1190 /// CHECK: InstanceFieldSet 1191 /// CHECK-NOT: InstanceFieldSet $noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass obj)1192 static int $noinline$testMonitorOperationInlineMethodWithSynchronizedScope(TestClass obj) { 1193 Main m = new Main(); 1194 return m.$inline$SetterWithSynchronizedScope(obj); 1195 } 1196 1197 static TestClass classForSync; 1198 volatile int vi; 1199 } 1200