001/* 002 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.compiler.test; 024 025import static com.oracle.graal.compiler.common.GraalOptions.*; 026import static com.oracle.graal.graph.test.matchers.NodeIterableCount.*; 027import static org.hamcrest.core.IsInstanceOf.*; 028import static org.junit.Assert.*; 029 030import java.util.*; 031 032import com.oracle.graal.debug.*; 033import com.oracle.graal.debug.Debug.*; 034import jdk.internal.jvmci.options.*; 035import jdk.internal.jvmci.options.OptionValue.*; 036 037import org.junit.*; 038 039import com.oracle.graal.api.directives.*; 040import com.oracle.graal.graph.*; 041import com.oracle.graal.graph.iterators.*; 042import com.oracle.graal.nodes.*; 043import com.oracle.graal.nodes.StructuredGraph.*; 044import com.oracle.graal.nodes.cfg.*; 045import com.oracle.graal.nodes.memory.*; 046import com.oracle.graal.nodes.spi.*; 047import com.oracle.graal.nodes.util.*; 048import com.oracle.graal.phases.*; 049import com.oracle.graal.phases.common.*; 050import com.oracle.graal.phases.common.inlining.*; 051import com.oracle.graal.phases.schedule.*; 052import com.oracle.graal.phases.schedule.SchedulePhase.*; 053import com.oracle.graal.phases.tiers.*; 054 055/** 056 * In these test the FrameStates are explicitly cleared out, so that the scheduling of 057 * FloatingReadNodes depends solely on the scheduling algorithm. The FrameStates normally keep the 058 * FloatingReadNodes above a certain point, so that they (most of the time...) magically do the 059 * right thing. 060 * 061 * The scheduling shouldn't depend on FrameStates, which is tested by this class. 062 */ 063public class MemoryScheduleTest extends GraphScheduleTest { 064 065 private static enum TestMode { 066 WITH_FRAMESTATES, 067 WITHOUT_FRAMESTATES, 068 INLINED_WITHOUT_FRAMESTATES 069 } 070 071 public static class Container { 072 073 public int a; 074 public int b; 075 public int c; 076 077 public Object obj; 078 } 079 080 private static final Container container = new Container(); 081 private static final List<Container> containerList = new ArrayList<>(); 082 083 /** 084 * In this test the read should be scheduled before the write. 085 */ 086 public static int testSimpleSnippet() { 087 try { 088 return container.a; 089 } finally { 090 container.a = 15; 091 } 092 } 093 094 @Test 095 public void testSimple() { 096 for (TestMode mode : TestMode.values()) { 097 SchedulePhase schedule = getFinalSchedule("testSimpleSnippet", mode); 098 StructuredGraph graph = schedule.getCFG().graph; 099 assertReadAndWriteInSameBlock(schedule, true); 100 assertOrderedAfterSchedule(schedule, graph.getNodes().filter(FloatingReadNode.class).first(), graph.getNodes().filter(WriteNode.class).first()); 101 } 102 } 103 104 /** 105 * In this case the read should be scheduled in the first block. 106 */ 107 public static int testSplit1Snippet(int a) { 108 try { 109 return container.a; 110 } finally { 111 if (a < 0) { 112 container.a = 15; 113 } else { 114 container.b = 15; 115 } 116 } 117 } 118 119 @Test 120 public void testSplit1() { 121 for (TestMode mode : TestMode.values()) { 122 SchedulePhase schedule = getFinalSchedule("testSplit1Snippet", mode); 123 assertReadWithinStartBlock(schedule, true); 124 assertReadWithinAllReturnBlocks(schedule, false); 125 } 126 } 127 128 /** 129 * Here the read should float to the end. 130 */ 131 public static int testSplit2Snippet(int a) { 132 try { 133 return container.a; 134 } finally { 135 if (a < 0) { 136 container.c = 15; 137 } else { 138 container.b = 15; 139 } 140 container.obj = null; 141 } 142 } 143 144 @Test 145 public void testSplit2() { 146 SchedulePhase schedule = getFinalSchedule("testSplit2Snippet", TestMode.WITHOUT_FRAMESTATES); 147 assertReadWithinStartBlock(schedule, false); 148 assertReadWithinAllReturnBlocks(schedule, true); 149 } 150 151 /** 152 * Here the read should not float to the end. 153 */ 154 public static int testLoop1Snippet(int a, int b) { 155 try { 156 return container.a; 157 } finally { 158 for (int i = 0; i < a; i++) { 159 if (b < 0) { 160 container.b = 10; 161 } else { 162 container.a = 15; 163 } 164 } 165 } 166 } 167 168 @Test 169 public void testLoop1() { 170 SchedulePhase schedule = getFinalSchedule("testLoop1Snippet", TestMode.WITHOUT_FRAMESTATES); 171 assertDeepEquals(6, schedule.getCFG().getBlocks().size()); 172 assertReadWithinStartBlock(schedule, true); 173 assertReadWithinAllReturnBlocks(schedule, false); 174 } 175 176 /** 177 * Here the read should float to the end. 178 */ 179 public static int testLoop2Snippet(int a, int b) { 180 try { 181 return container.a; 182 } finally { 183 for (int i = 0; i < a; i++) { 184 if (b < 0) { 185 container.b = 10; 186 } else { 187 container.c = 15; 188 } 189 } 190 } 191 } 192 193 @Test 194 public void testLoop2() { 195 SchedulePhase schedule = getFinalSchedule("testLoop2Snippet", TestMode.WITHOUT_FRAMESTATES); 196 assertDeepEquals(6, schedule.getCFG().getBlocks().size()); 197 assertReadWithinStartBlock(schedule, false); 198 assertReadWithinAllReturnBlocks(schedule, true); 199 } 200 201 /** 202 * Here the read should float out of the loop. 203 */ 204 public static int testLoop3Snippet(int a) { 205 int j = 0; 206 for (int i = 0; i < a; i++) { 207 if (i - container.a == 0) { 208 break; 209 } 210 j++; 211 } 212 return j; 213 } 214 215 @Test 216 public void testLoop3() { 217 SchedulePhase schedule = getFinalSchedule("testLoop3Snippet", TestMode.WITHOUT_FRAMESTATES); 218 assertDeepEquals(6, schedule.getCFG().getBlocks().size()); 219 assertReadWithinStartBlock(schedule, true); 220 assertReadWithinAllReturnBlocks(schedule, false); 221 } 222 223 public String testStringReplaceSnippet(String input) { 224 return input.replace('a', 'b'); 225 } 226 227 @Test 228 public void testStringReplace() { 229 getFinalSchedule("testStringReplaceSnippet", TestMode.INLINED_WITHOUT_FRAMESTATES); 230 test("testStringReplaceSnippet", "acbaaa"); 231 } 232 233 /** 234 * Here the read should float out of the loop. 235 */ 236 public static int testLoop5Snippet(int a, int b, MemoryScheduleTest obj) { 237 int ret = 0; 238 int bb = b; 239 for (int i = 0; i < a; i++) { 240 ret = obj.hash; 241 if (a > 10) { 242 bb++; 243 } else { 244 bb--; 245 } 246 ret = ret / 10; 247 } 248 return ret + bb; 249 } 250 251 @Test 252 public void testLoop5() { 253 SchedulePhase schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES); 254 assertDeepEquals(10, schedule.getCFG().getBlocks().size()); 255 assertReadWithinStartBlock(schedule, false); 256 assertReadWithinAllReturnBlocks(schedule, false); 257 } 258 259 /** 260 * Here the read should not float out of the loop. 261 */ 262 public static int testLoop6Snippet(int a, int b, MemoryScheduleTest obj) { 263 int ret = 0; 264 int bb = b; 265 for (int i = 0; i < a; i++) { 266 ret = obj.hash; 267 if (a > 10) { 268 bb++; 269 } else { 270 bb--; 271 for (int j = 0; j < b; ++j) { 272 obj.hash = 3; 273 } 274 } 275 ret = ret / 10; 276 } 277 return ret + bb; 278 } 279 280 @Test 281 public void testLoop6() { 282 SchedulePhase schedule = getFinalSchedule("testLoop6Snippet", TestMode.WITHOUT_FRAMESTATES); 283 assertDeepEquals(13, schedule.getCFG().getBlocks().size()); 284 assertReadWithinStartBlock(schedule, false); 285 assertReadWithinAllReturnBlocks(schedule, false); 286 } 287 288 /** 289 * Here the read should not float out of the loop. 290 */ 291 public static int testLoop7Snippet(int a, int b, MemoryScheduleTest obj) { 292 int ret = 0; 293 int bb = b; 294 for (int i = 0; i < a; i++) { 295 ret = obj.hash; 296 if (a > 10) { 297 bb++; 298 } else { 299 bb--; 300 for (int k = 0; k < a; ++k) { 301 if (k % 2 == 1) { 302 for (int j = 0; j < b; ++j) { 303 obj.hash = 3; 304 } 305 } 306 } 307 } 308 ret = ret / 10; 309 } 310 return ret + bb; 311 } 312 313 @Test 314 public void testLoop7() { 315 SchedulePhase schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES); 316 assertDeepEquals(18, schedule.getCFG().getBlocks().size()); 317 assertReadWithinStartBlock(schedule, false); 318 assertReadWithinAllReturnBlocks(schedule, false); 319 } 320 321 /** 322 * Here the read should not float to the end. 323 */ 324 public static int testLoop8Snippet(int a, int b) { 325 int result = container.a; 326 for (int i = 0; i < a; i++) { 327 if (b < 0) { 328 container.b = 10; 329 break; 330 } else { 331 for (int j = 0; j < b; j++) { 332 container.a = 0; 333 } 334 } 335 } 336 GraalDirectives.controlFlowAnchor(); 337 return result; 338 } 339 340 @Test 341 public void testLoop8() { 342 SchedulePhase schedule = getFinalSchedule("testLoop8Snippet", TestMode.WITHOUT_FRAMESTATES); 343 assertDeepEquals(10, schedule.getCFG().getBlocks().size()); 344 assertReadWithinStartBlock(schedule, true); 345 assertReadWithinAllReturnBlocks(schedule, false); 346 } 347 348 /** 349 * Here the read should float after the loop. 350 */ 351 public static int testLoop9Snippet(int a, int b) { 352 container.a = b; 353 for (int i = 0; i < a; i++) { 354 container.a = i; 355 } 356 GraalDirectives.controlFlowAnchor(); 357 return container.a; 358 } 359 360 @Test 361 public void testLoop9() { 362 SchedulePhase schedule = getFinalSchedule("testLoop9Snippet", TestMode.WITHOUT_FRAMESTATES); 363 StructuredGraph graph = schedule.getCFG().getStartBlock().getBeginNode().graph(); 364 assertThat(graph.getNodes(ReturnNode.TYPE), hasCount(1)); 365 ReturnNode ret = graph.getNodes(ReturnNode.TYPE).first(); 366 assertThat(ret.result(), instanceOf(FloatingReadNode.class)); 367 Block readBlock = schedule.getNodeToBlockMap().get(ret.result()); 368 Assert.assertEquals(0, readBlock.getLoopDepth()); 369 } 370 371 /** 372 * Here the read should float to the end (into the same block as the return). 373 */ 374 public static int testArrayCopySnippet(Integer intValue, char[] a, char[] b, int len) { 375 System.arraycopy(a, 0, b, 0, len); 376 return intValue.intValue(); 377 } 378 379 @Test 380 public void testArrayCopy() { 381 SchedulePhase schedule = getFinalSchedule("testArrayCopySnippet", TestMode.INLINED_WITHOUT_FRAMESTATES); 382 StructuredGraph graph = schedule.getCFG().getStartBlock().getBeginNode().graph(); 383 assertDeepEquals(1, graph.getNodes(ReturnNode.TYPE).count()); 384 ReturnNode ret = graph.getNodes(ReturnNode.TYPE).first(); 385 assertTrue(ret.result() + " should be a FloatingReadNode", ret.result() instanceof FloatingReadNode); 386 assertDeepEquals(schedule.getCFG().blockFor(ret), schedule.getCFG().blockFor(ret.result())); 387 assertReadWithinAllReturnBlocks(schedule, true); 388 } 389 390 /** 391 * Here the read should not float to the end. 392 */ 393 public static int testIfRead1Snippet(int a) { 394 int res = container.a; 395 if (a < 0) { 396 container.a = 10; 397 } 398 return res; 399 } 400 401 @Test 402 public void testIfRead1() { 403 SchedulePhase schedule = getFinalSchedule("testIfRead1Snippet", TestMode.WITHOUT_FRAMESTATES); 404 assertDeepEquals(3, schedule.getCFG().getBlocks().size()); 405 assertReadWithinStartBlock(schedule, true); 406 assertReadAndWriteInSameBlock(schedule, false); 407 } 408 409 /** 410 * Here the read should float in the else block. 411 */ 412 public static int testIfRead2Snippet(int a) { 413 int res = 0; 414 if (a < 0) { 415 container.a = 10; 416 } else { 417 res = container.a; 418 } 419 return res; 420 } 421 422 @Test 423 public void testIfRead2() { 424 SchedulePhase schedule = getFinalSchedule("testIfRead2Snippet", TestMode.WITHOUT_FRAMESTATES); 425 assertDeepEquals(3, schedule.getCFG().getBlocks().size()); 426 assertDeepEquals(1, schedule.getCFG().graph.getNodes().filter(FloatingReadNode.class).count()); 427 assertReadWithinStartBlock(schedule, false); 428 assertReadWithinAllReturnBlocks(schedule, false); 429 assertReadAndWriteInSameBlock(schedule, false); 430 } 431 432 /** 433 * Here the read should float to the end, right before the write. 434 */ 435 public static int testIfRead3Snippet(int a) { 436 if (a < 0) { 437 container.a = 10; 438 } 439 int res = container.a; 440 container.a = 20; 441 return res; 442 } 443 444 @Test 445 public void testIfRead3() { 446 SchedulePhase schedule = getFinalSchedule("testIfRead3Snippet", TestMode.WITHOUT_FRAMESTATES); 447 assertDeepEquals(4, schedule.getCFG().getBlocks().size()); 448 assertReadWithinStartBlock(schedule, false); 449 assertReadWithinAllReturnBlocks(schedule, true); 450 } 451 452 /** 453 * Here the read should be just in the if branch (with the write). 454 */ 455 public static int testIfRead4Snippet(int a) { 456 if (a > 0) { 457 int res = container.a; 458 container.a = 0x20; 459 return res; 460 } else { 461 return 0x10; 462 } 463 } 464 465 @Test 466 public void testIfRead4() { 467 SchedulePhase schedule = getFinalSchedule("testIfRead4Snippet", TestMode.WITHOUT_FRAMESTATES); 468 assertDeepEquals(3, schedule.getCFG().getBlocks().size()); 469 assertReadWithinStartBlock(schedule, false); 470 assertReadWithinAllReturnBlocks(schedule, false); 471 assertReadAndWriteInSameBlock(schedule, true); 472 } 473 474 /** 475 * Here the read should float to the end. 476 */ 477 public static int testIfRead5Snippet(int a) { 478 if (a < 0) { 479 container.a = 10; 480 } 481 return container.a; 482 } 483 484 @Test 485 public void testIfRead5() { 486 SchedulePhase schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES); 487 assertDeepEquals(4, schedule.getCFG().getBlocks().size()); 488 assertReadWithinStartBlock(schedule, false); 489 assertReadWithinAllReturnBlocks(schedule, true); 490 assertReadAndWriteInSameBlock(schedule, false); 491 } 492 493 public static int testAntiDependencySnippet(int a) { 494 /* 495 * This read must not be scheduled after the following write. 496 */ 497 int res = container.a; 498 container.a = 10; 499 500 /* 501 * Add some more basic blocks. 502 */ 503 if (a < 0) { 504 container.b = 20; 505 } 506 container.c = 30; 507 return res; 508 } 509 510 @Test 511 public void testAntiDependency() { 512 SchedulePhase schedule = getFinalSchedule("testAntiDependencySnippet", TestMode.WITHOUT_FRAMESTATES); 513 assertDeepEquals(4, schedule.getCFG().getBlocks().size()); 514 assertReadBeforeAllWritesInStartBlock(schedule); 515 } 516 517 /** 518 * testing scheduling within a block. 519 */ 520 public static int testBlockScheduleSnippet() { 521 int res = 0; 522 container.a = 0x00; 523 container.a = 0x10; 524 container.a = 0x20; 525 container.a = 0x30; 526 container.a = 0x40; 527 res = container.a; 528 container.a = 0x50; 529 container.a = 0x60; 530 container.a = 0x70; 531 return res; 532 } 533 534 @Test 535 public void testBlockSchedule() { 536 SchedulePhase schedule = getFinalSchedule("testBlockScheduleSnippet", TestMode.WITHOUT_FRAMESTATES); 537 StructuredGraph graph = schedule.getCFG().graph; 538 NodeIterable<WriteNode> writeNodes = graph.getNodes().filter(WriteNode.class); 539 540 assertDeepEquals(1, schedule.getCFG().getBlocks().size()); 541 assertDeepEquals(8, writeNodes.count()); 542 assertDeepEquals(1, graph.getNodes().filter(FloatingReadNode.class).count()); 543 544 FloatingReadNode read = graph.getNodes().filter(FloatingReadNode.class).first(); 545 546 WriteNode[] writes = new WriteNode[8]; 547 int i = 0; 548 for (WriteNode n : writeNodes) { 549 writes[i] = n; 550 i++; 551 } 552 assertOrderedAfterSchedule(schedule, writes[4], read); 553 assertOrderedAfterSchedule(schedule, read, writes[5]); 554 for (int j = 0; j < 7; j++) { 555 assertOrderedAfterSchedule(schedule, writes[j], writes[j + 1]); 556 } 557 } 558 559 /** 560 * read should move inside the loop (out of loop is disabled). 561 */ 562 public static int testBlockSchedule2Snippet(int value) { 563 int res = 0; 564 565 container.a = value; 566 for (int i = 0; i < 100; i++) { 567 if (i == 10) { 568 return container.a; 569 } 570 res += i; 571 } 572 return res; 573 } 574 575 @Test 576 public void testBlockSchedule2() { 577 SchedulePhase schedule = getFinalSchedule("testBlockSchedule2Snippet", TestMode.WITHOUT_FRAMESTATES, SchedulingStrategy.LATEST); 578 assertReadWithinStartBlock(schedule, false); 579 assertReadWithinAllReturnBlocks(schedule, false); 580 assertReadAndWriteInSameBlock(schedule, false); 581 } 582 583 public static void testProxySnippet() { 584 while (container.a < container.b) { 585 List<Container> list = new ArrayList<>(containerList); 586 while (container.c < list.size()) { 587 if (container.obj != null) { 588 return; 589 } 590 container.c++; 591 } 592 container.a = 0; 593 container.b--; 594 } 595 container.b++; 596 } 597 598 @Test 599 public void testProxy() { 600 SchedulePhase schedule = getFinalSchedule("testProxySnippet", TestMode.WITHOUT_FRAMESTATES); 601 assertReadWithinStartBlock(schedule, false); 602 assertReadWithinAllReturnBlocks(schedule, false); 603 } 604 605 private int hash = 0; 606 private final char[] value = new char[3]; 607 608 public int testStringHashCodeSnippet() { 609 int h = hash; 610 if (h == 0 && value.length > 0) { 611 char[] val = value; 612 613 for (int i = 0; i < value.length; i++) { 614 h = 31 * h + val[i]; 615 } 616 hash = h; 617 } 618 return h; 619 } 620 621 @Test 622 public void testStringHashCode() { 623 SchedulePhase schedule = getFinalSchedule("testStringHashCodeSnippet", TestMode.WITHOUT_FRAMESTATES); 624 assertReadWithinStartBlock(schedule, true); 625 assertReadWithinAllReturnBlocks(schedule, false); 626 627 hash = 0x1337; 628 value[0] = 'a'; 629 value[1] = 'b'; 630 value[2] = 'c'; 631 test("testStringHashCodeSnippet"); 632 } 633 634 public static int testLoop4Snippet(int count) { 635 int[] a = new int[count]; 636 637 for (int i = 0; i < a.length; i++) { 638 a[i] = i; 639 } 640 641 int i = 0; 642 int iwrap = count - 1; 643 int sum = 0; 644 645 while (i < count) { 646 sum += (a[i] + a[iwrap]) / 2; 647 iwrap = i; 648 i++; 649 } 650 return sum; 651 } 652 653 @Test 654 public void testLoop4() { 655 SchedulePhase schedule = getFinalSchedule("testLoop4Snippet", TestMode.WITHOUT_FRAMESTATES); 656 assertReadWithinStartBlock(schedule, false); 657 assertReadWithinAllReturnBlocks(schedule, false); 658 } 659 660 private void assertReadWithinAllReturnBlocks(SchedulePhase schedule, boolean withinReturnBlock) { 661 StructuredGraph graph = schedule.getCFG().graph; 662 assertTrue(graph.getNodes(ReturnNode.TYPE).isNotEmpty()); 663 664 int withRead = 0; 665 int returnBlocks = 0; 666 for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) { 667 Block block = schedule.getCFG().getNodeToBlock().get(returnNode); 668 for (Node node : schedule.getBlockToNodesMap().get(block)) { 669 if (node instanceof FloatingReadNode) { 670 withRead++; 671 break; 672 } 673 } 674 returnBlocks++; 675 } 676 assertDeepEquals(withRead == returnBlocks, withinReturnBlock); 677 } 678 679 private void assertReadWithinStartBlock(SchedulePhase schedule, boolean withinStartBlock) { 680 boolean readEncountered = false; 681 for (Node node : schedule.getBlockToNodesMap().get(schedule.getCFG().getStartBlock())) { 682 if (node instanceof FloatingReadNode) { 683 readEncountered = true; 684 } 685 } 686 assertDeepEquals(withinStartBlock, readEncountered); 687 } 688 689 private static void assertReadAndWriteInSameBlock(SchedulePhase schedule, boolean inSame) { 690 StructuredGraph graph = schedule.getCFG().graph; 691 FloatingReadNode read = graph.getNodes().filter(FloatingReadNode.class).first(); 692 WriteNode write = graph.getNodes().filter(WriteNode.class).first(); 693 assertTrue(!(inSame ^ schedule.getCFG().blockFor(read) == schedule.getCFG().blockFor(write))); 694 } 695 696 private static void assertReadBeforeAllWritesInStartBlock(SchedulePhase schedule) { 697 boolean writeNodeFound = false; 698 boolean readNodeFound = false; 699 for (Node node : schedule.nodesFor(schedule.getCFG().getStartBlock())) { 700 if (node instanceof FloatingReadNode) { 701 assertTrue(!writeNodeFound); 702 readNodeFound = true; 703 } else if (node instanceof WriteNode) { 704 writeNodeFound = true; 705 } 706 } 707 assertTrue(readNodeFound); 708 } 709 710 private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode) { 711 return getFinalSchedule(snippet, mode, SchedulingStrategy.LATEST_OUT_OF_LOOPS); 712 } 713 714 private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final SchedulingStrategy schedulingStrategy) { 715 final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); 716 try (Scope d = Debug.scope("FloatingReadTest", graph)) { 717 try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { 718 HighTierContext context = getDefaultHighTierContext(); 719 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); 720 canonicalizer.apply(graph, context); 721 if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { 722 new InliningPhase(canonicalizer).apply(graph, context); 723 } 724 new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); 725 if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { 726 for (Node node : graph.getNodes()) { 727 if (node instanceof StateSplit) { 728 FrameState stateAfter = ((StateSplit) node).stateAfter(); 729 if (stateAfter != null) { 730 ((StateSplit) node).setStateAfter(null); 731 GraphUtil.killWithUnusedFloatingInputs(stateAfter); 732 } 733 } 734 } 735 } 736 Debug.dump(graph, "after removal of framestates"); 737 738 new FloatingReadPhase().apply(graph); 739 new RemoveValueProxyPhase().apply(graph); 740 741 MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo()); 742 new GuardLoweringPhase().apply(graph, midContext); 743 new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); 744 new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER).apply(graph, midContext); 745 746 SchedulePhase schedule = new SchedulePhase(schedulingStrategy); 747 schedule.apply(graph); 748 assertDeepEquals(1, graph.getNodes().filter(StartNode.class).count()); 749 return schedule; 750 } 751 } catch (Throwable e) { 752 throw Debug.handle(e); 753 } 754 } 755}