comparison graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java @ 19564:f53c6c8e2048

Refactorings in SchedulePhase.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 23 Feb 2015 17:57:58 +0100
parents fcefaa7f103d
children 08d94d9f0b0f
comparison
equal deleted inserted replaced
19563:fb32f2d8abf4 19564:f53c6c8e2048
669 } 669 }
670 earliest = earliestCache.get(node); 670 earliest = earliestCache.get(node);
671 if (earliest != null) { 671 if (earliest != null) {
672 return earliest; 672 return earliest;
673 } 673 }
674 return earliestBlockHelper(node, earliest);
675 }
676
677 private Block earliestBlockHelper(Node node, Block earliest) throws SchedulingError {
674 /* 678 /*
675 * All inputs must be in a dominating block, otherwise the graph cannot be scheduled. This 679 * All inputs must be in a dominating block, otherwise the graph cannot be scheduled. This
676 * implies that the inputs' blocks have a total ordering via their dominance relation. So in 680 * implies that the inputs' blocks have a total ordering via their dominance relation. So in
677 * order to find the earliest block placement for this node we need to find the input block 681 * order to find the earliest block placement for this node we need to find the input block
678 * that is dominated by all other input blocks. 682 * that is dominated by all other input blocks.
679 */ 683 */
680 684
681 if (node.predecessor() != null) { 685 if (node.predecessor() != null) {
682 throw new SchedulingError(); 686 throw new SchedulingError();
683 } 687 }
684 for (Node input : node.inputs().nonNull()) { 688 for (Node input : node.inputs()) {
685 assert input instanceof ValueNode; 689 if (input != null) {
686 Block inputEarliest; 690 assert input instanceof ValueNode;
687 if (input instanceof InvokeWithExceptionNode) { 691 Block inputEarliest;
688 inputEarliest = cfg.getNodeToBlock().get(((InvokeWithExceptionNode) input).next()); 692 if (input instanceof InvokeWithExceptionNode) {
689 } else { 693 inputEarliest = cfg.getNodeToBlock().get(((InvokeWithExceptionNode) input).next());
690 inputEarliest = earliestBlock(input); 694 } else {
691 } 695 inputEarliest = earliestBlock(input);
692 if (earliest == null) { 696 }
693 earliest = inputEarliest; 697 if (earliest == null) {
694 } else if (earliest != inputEarliest) { 698 earliest = inputEarliest;
695 // Find out whether earliest or inputEarliest is earlier. 699 } else if (earliest != inputEarliest) {
696 Block a = earliest.getDominator(); 700 earliest = findEarlierBlock(earliest, inputEarliest);
697 Block b = inputEarliest;
698 while (true) {
699 if (a == inputEarliest || b == null) {
700 // Nothing to change, the previous earliest block is still earliest.
701 break;
702 } else if (b == earliest || a == null) {
703 // New earliest is the earliest.
704 earliest = inputEarliest;
705 break;
706 }
707 a = a.getDominator();
708 b = b.getDominator();
709 } 701 }
710 } 702 }
711 } 703 }
712 if (earliest == null) { 704 if (earliest == null) {
713 earliest = cfg.getStartBlock(); 705 earliest = cfg.getStartBlock();
714 } 706 }
715 earliestCache.set(node, earliest); 707 earliestCache.set(node, earliest);
716 return earliest; 708 return earliest;
709 }
710
711 private static Block findEarlierBlock(Block earliest, Block inputEarliest) {
712 // Find out whether earliest or inputEarliest is earlier.
713 Block a = earliest.getDominator();
714 Block b = inputEarliest;
715 while (true) {
716 if (a == inputEarliest || b == null) {
717 // Nothing to change, the previous earliest block is still earliest.
718 return earliest;
719 } else if (b == earliest || a == null) {
720 // New earliest is the earliest.
721 return inputEarliest;
722 }
723 a = a.getDominator();
724 b = b.getDominator();
725 }
717 } 726 }
718 727
719 /** 728 /**
720 * Schedules a node out of loop based on its earliest schedule. Note that this movement is only 729 * Schedules a node out of loop based on its earliest schedule. Note that this movement is only
721 * valid if it's done for <b>every</b> other node in the schedule, otherwise this movement is 730 * valid if it's done for <b>every</b> other node in the schedule, otherwise this movement is
1069 ProxyNode proxyNode = (ProxyNode) i; 1078 ProxyNode proxyNode = (ProxyNode) i;
1070 addToLatestSorting(proxyNode.value(), state); 1079 addToLatestSorting(proxyNode.value(), state);
1071 return; 1080 return;
1072 } 1081 }
1073 1082
1083 addToLatestSortingHelper(i, state);
1084 }
1085
1086 private void addToLatestSortingHelper(ValueNode i, SortState state) {
1074 FrameState stateAfter = null; 1087 FrameState stateAfter = null;
1075 if (i instanceof StateSplit) { 1088 if (i instanceof StateSplit) {
1076 stateAfter = ((StateSplit) i).stateAfter(); 1089 stateAfter = ((StateSplit) i).stateAfter();
1077 } 1090 }
1078 1091
1079 for (Node input : i.inputs()) { 1092 addInputsToLatestSorting(i, state, stateAfter);
1080 if (input instanceof FrameState) {
1081 if (input != stateAfter) {
1082 addUnscheduledToLatestSorting((FrameState) input, state);
1083 }
1084 } else {
1085 addToLatestSorting((ValueNode) input, state);
1086 }
1087 }
1088 1093
1089 if (state.readsSize() != 0) { 1094 if (state.readsSize() != 0) {
1090 if (i instanceof MemoryCheckpoint.Single) { 1095 if (i instanceof MemoryCheckpoint.Single) {
1091 LocationIdentity identity = ((MemoryCheckpoint.Single) i).getLocationIdentity(); 1096 LocationIdentity identity = ((MemoryCheckpoint.Single) i).getLocationIdentity();
1092 processKillLocation(i, identity, state); 1097 processKillLocation(i, identity, state);
1110 if (state.readsSize() != 0 && i instanceof FloatingReadNode) { 1115 if (state.readsSize() != 0 && i instanceof FloatingReadNode) {
1111 state.removeRead(i); 1116 state.removeRead(i);
1112 } 1117 }
1113 } 1118 }
1114 1119
1120 private void addInputsToLatestSorting(ValueNode i, SortState state, FrameState stateAfter) {
1121 for (Node input : i.inputs()) {
1122 if (input instanceof FrameState) {
1123 if (input != stateAfter) {
1124 addUnscheduledToLatestSorting((FrameState) input, state);
1125 }
1126 } else {
1127 addToLatestSorting((ValueNode) input, state);
1128 }
1129 }
1130 }
1131
1115 /** 1132 /**
1116 * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over 1133 * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over
1117 * all usages. The resulting list is reversed to create an earliest-possible scheduling of 1134 * all usages. The resulting list is reversed to create an earliest-possible scheduling of
1118 * nodes. 1135 * nodes.
1119 */ 1136 */