# HG changeset patch # User Doug Simon # Date 1404222179 -7200 # Node ID a415b39908118eac3ff475ada89435da81ff94d6 # Parent e17a0f85e0af347a8f266f3def767a4ff11a0fd1 made FloatingReadNode clean up dead nodes it creates diff -r e17a0f85e0af -r a415b3990811 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Jul 01 12:10:37 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Jul 01 15:42:59 2014 +0200 @@ -23,14 +23,20 @@ package com.oracle.graal.phases.common; import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.graph.Graph.NodeEvent.*; import static com.oracle.graal.graph.util.CollectionsAccess.*; import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Graph.NodeEventScope; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantNodeIterator.LoopInfo; import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; @@ -94,11 +100,42 @@ this.execmode = execmode; } + /** + * Removes nodes from a given set that (transitively) have a usage outside the set. + */ + private static Set removeExternallyUsedNodes(Set set) { + boolean change; + do { + change = false; + for (Iterator iter = set.iterator(); iter.hasNext();) { + Node node = iter.next(); + for (Node usage : node.usages()) { + if (!set.contains(usage)) { + change = true; + iter.remove(); + break; + } + } + } + } while (change); + return set; + } + @Override protected void run(StructuredGraph graph) { Map> modifiedInLoops = newNodeIdentityMap(); ReentrantNodeIterator.apply(new CollectMemoryCheckpointsClosure(modifiedInLoops), graph.start(), new HashSet()); - ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, execmode), graph.start(), new MemoryMapImpl(graph.start())); + HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES)); + try (NodeEventScope nes = graph.trackNodeEvents(listener)) { + ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, execmode), graph.start(), new MemoryMapImpl(graph.start())); + } + + for (Node n : removeExternallyUsedNodes(listener.getNodes())) { + if (n.isAlive() && n instanceof FloatingNode) { + n.replaceAtUsages(null); + GraphUtil.killWithUnusedFloatingInputs(n); + } + } if (execmode == ExecutionMode.CREATE_FLOATING_READS) { assert !graph.isAfterFloatingReadPhase(); graph.setAfterFloatingReadPhase(true);