# HG changeset patch # User Bernhard Urban # Date 1398775851 -7200 # Node ID 81eee524bbec22300eb9b2a4345a09d287fb6097 # Parent ab87fc35196bc76e982fecab21b7419a53315410 SchedulePhase: refactoring diff -r ab87fc35196b -r 81eee524bbec graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Apr 29 11:40:29 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Apr 29 14:50:51 2014 +0200 @@ -888,40 +888,114 @@ return true; } + private static class SortState { + private Block block; + private NodeBitMap visited; + private NodeBitMap beforeLastLocation; + private List sortedInstructions; + private List reads; + + SortState(Block block, NodeBitMap visited, NodeBitMap beforeLastLocation, List sortedInstructions) { + this.block = block; + this.visited = visited; + this.beforeLastLocation = beforeLastLocation; + this.sortedInstructions = sortedInstructions; + this.reads = null; + } + + public Block currentBlock() { + return block; + } + + void markVisited(Node n) { + visited.mark(n); + } + + boolean isVisited(Node n) { + return visited.isMarked(n); + } + + void markBeforeLastLocation(FloatingReadNode n) { + beforeLastLocation.mark(n); + } + + void clearBeforeLastLocation(FloatingReadNode frn) { + beforeLastLocation.clear(frn); + } + + boolean isBeforeLastLocation(FloatingReadNode n) { + return beforeLastLocation.isMarked(n); + } + + void addRead(FloatingReadNode n) { + if (reads == null) { + reads = new ArrayList<>(); + } + reads.add(n); + } + + int readsSize() { + if (reads == null) { + return 0; + } + return reads.size(); + } + + void removeRead(ScheduledNode i) { + assert reads != null; + reads.remove(i); + } + + List readsSnapshot() { + assert reads != null; + return new ArrayList<>(reads); + } + + List getSortedInstructions() { + return sortedInstructions; + } + + boolean containsInstruction(ScheduledNode i) { + return sortedInstructions.contains(i); + } + + void addInstruction(ScheduledNode i) { + sortedInstructions.add(i); + } + } + /** * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over * all inputs. This means that a node is added to the list after all its inputs have been * processed. */ private List sortNodesWithinBlockLatest(Block b, NodeBitMap visited, NodeBitMap beforeLastLocation) { + SortState state = new SortState(b, visited, beforeLastLocation, new ArrayList<>(blockToNodesMap.get(b).size() + 2)); List instructions = blockToNodesMap.get(b); - List sortedInstructions = new ArrayList<>(blockToNodesMap.get(b).size() + 2); - List reads = null; if (memsched == MemoryScheduling.OPTIMAL) { for (ScheduledNode i : instructions) { if (i instanceof FloatingReadNode) { FloatingReadNode frn = (FloatingReadNode) i; if (frn.location().getLocationIdentity() != FINAL_LOCATION) { - if (reads == null) { - reads = new ArrayList<>(); - } - reads.add(frn); + state.addRead(frn); if (nodesFor(b).contains(frn.getLastLocationAccess())) { - assert !beforeLastLocation.isMarked(frn); - beforeLastLocation.mark(frn); + assert !state.isBeforeLastLocation(frn); + state.markBeforeLastLocation(frn); } } } } } + for (ScheduledNode i : instructions) { - addToLatestSorting(b, i, sortedInstructions, visited, reads, beforeLastLocation); + addToLatestSorting(i, state); } - assert reads == null || reads.size() == 0 : "not all reads are scheduled"; + assert state.readsSize() == 0 : "not all reads are scheduled"; // Make sure that last node gets really last (i.e. when a frame state successor hangs off // it). + List sortedInstructions = state.getSortedInstructions(); Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1); if (lastSorted != b.getEndNode()) { int idx = sortedInstructions.indexOf(b.getEndNode()); @@ -947,40 +1021,39 @@ return sortedInstructions; } - private void processKillLocation(Block b, Node node, LocationIdentity identity, List sortedInstructions, NodeBitMap visited, List reads, - NodeBitMap beforeLastLocation) { - for (FloatingReadNode frn : new ArrayList<>(reads)) { + private void processKillLocation(Node node, LocationIdentity identity, SortState state) { + for (FloatingReadNode frn : state.readsSnapshot()) { LocationIdentity readLocation = frn.location().getLocationIdentity(); assert readLocation != FINAL_LOCATION; if (frn.getLastLocationAccess() == node) { assert identity == ANY_LOCATION || readLocation == identity : "location doesn't match: " + readLocation + ", " + identity; - beforeLastLocation.clear(frn); - } else if (!beforeLastLocation.isMarked(frn) && (readLocation == identity || (node != getCFG().graph.start() && ANY_LOCATION == identity))) { - reads.remove(frn); - addToLatestSorting(b, frn, sortedInstructions, visited, reads, beforeLastLocation); + state.clearBeforeLastLocation(frn); + } else if (!state.isBeforeLastLocation(frn) && (readLocation == identity || (node != getCFG().graph.start() && ANY_LOCATION == identity))) { + state.removeRead(frn); + addToLatestSorting(frn, state); } } } - private void addUnscheduledToLatestSorting(Block b, VirtualState state, List sortedInstructions, NodeBitMap visited, List reads, NodeBitMap beforeLastLocation) { + private void addUnscheduledToLatestSorting(VirtualState state, SortState sortState) { if (state != null) { // UnscheduledNodes should never be marked as visited. - if (visited.isMarked(state)) { + if (sortState.isVisited(state)) { throw new SchedulingError(); } for (Node input : state.inputs()) { if (input instanceof VirtualState) { - addUnscheduledToLatestSorting(b, (VirtualState) input, sortedInstructions, visited, reads, beforeLastLocation); + addUnscheduledToLatestSorting((VirtualState) input, sortState); } else { - addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); + addToLatestSorting((ScheduledNode) input, sortState); } } } } - private void addToLatestSorting(Block b, ScheduledNode i, List sortedInstructions, NodeBitMap visited, List reads, NodeBitMap beforeLastLocation) { - if (i == null || visited.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode) { + private void addToLatestSorting(ScheduledNode i, SortState state) { + if (i == null || state.isVisited(i) || cfg.getNodeToBlock().get(i) != state.currentBlock() || i instanceof PhiNode) { return; } @@ -991,45 +1064,45 @@ if (i instanceof LoopExitNode) { for (ProxyNode proxy : ((LoopExitNode) i).proxies()) { - addToLatestSorting(b, proxy, sortedInstructions, visited, reads, beforeLastLocation); + addToLatestSorting(proxy, state); } } for (Node input : i.inputs()) { if (input instanceof FrameState) { if (input != stateAfter) { - addUnscheduledToLatestSorting(b, (FrameState) input, sortedInstructions, visited, reads, beforeLastLocation); + addUnscheduledToLatestSorting((FrameState) input, state); } } else { if (!(i instanceof ProxyNode && input instanceof LoopExitNode)) { - addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); + addToLatestSorting((ScheduledNode) input, state); } } } - if (memsched == MemoryScheduling.OPTIMAL && reads != null) { + if (memsched == MemoryScheduling.OPTIMAL && state.readsSize() != 0) { if (i instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) i).getLocationIdentity(); - processKillLocation(b, i, identity, sortedInstructions, visited, reads, beforeLastLocation); + processKillLocation(i, identity, state); } else if (i instanceof MemoryCheckpoint.Multi) { for (LocationIdentity identity : ((MemoryCheckpoint.Multi) i).getLocationIdentities()) { - processKillLocation(b, i, identity, sortedInstructions, visited, reads, beforeLastLocation); + processKillLocation(i, identity, state); } } assert MemoryCheckpoint.TypeAssertion.correctType(i); } - addToLatestSorting(b, (ScheduledNode) i.predecessor(), sortedInstructions, visited, reads, beforeLastLocation); - visited.mark(i); - addUnscheduledToLatestSorting(b, stateAfter, sortedInstructions, visited, reads, beforeLastLocation); + addToLatestSorting((ScheduledNode) i.predecessor(), state); + state.markVisited(i); + addUnscheduledToLatestSorting(stateAfter, state); // Now predecessors and inputs are scheduled => we can add this node. - if (!sortedInstructions.contains(i)) { - sortedInstructions.add(i); + if (!state.containsInstruction(i)) { + state.addInstruction(i); } - if (i instanceof FloatingReadNode) { - reads.remove(i); + if (state.readsSize() != 0 && i instanceof FloatingReadNode) { + state.removeRead(i); } }