# HG changeset patch # User Gilles Duboscq # Date 1338564451 -7200 # Node ID 4a99bfc329f0aecd341987cc4ecc504cba74fd0d # Parent a7c79bcf55acb278d9c939d8be302205ec2e48ea Add posibility to provide a replacement function instead of map for duplication. Also added validity check so that only valid slots (Position) get patched when replacing during duplication diff -r a7c79bcf55ac -r 4a99bfc329f0 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Jun 01 17:22:59 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Jun 01 17:27:31 2012 +0200 @@ -520,10 +520,44 @@ * @param replacements the replacement map (can be null if no replacement is to be performed) * @return a map which associates the original nodes from {@code nodes} to their duplicates */ + public Map addDuplicates(Iterable newNodes, Map replacementsMap) { + DuplicationReplacement replacements; + if (replacementsMap == null) { + replacements = null; + } else { + replacements = new MapReplacement(replacementsMap); + } + return addDuplicates(newNodes, replacements); + } + + public interface DuplicationReplacement { + Node replacement(Node original); + } + + private static final class MapReplacement implements DuplicationReplacement { + private final Map map; + public MapReplacement(Map map) { + this.map = map; + } + @Override + public Node replacement(Node original) { + Node replacement = map.get(original); + return replacement != null ? replacement : original; + } + + } + + private static final DuplicationReplacement NO_REPLACEMENT = new DuplicationReplacement() { + @Override + public Node replacement(Node original) { + return original; + } + }; + @SuppressWarnings("all") - public Map addDuplicates(Iterable newNodes, Map replacements) { + public Map addDuplicates(Iterable newNodes, DuplicationReplacement replacements) { if (replacements == null) { - replacements = Collections.emptyMap(); + replacements = NO_REPLACEMENT; } return NodeClass.addGraphDuplicate(this, newNodes, replacements); } diff -r a7c79bcf55ac -r 4a99bfc329f0 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Jun 01 17:22:59 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Jun 01 17:27:31 2012 +0200 @@ -27,6 +27,8 @@ import java.util.Map.*; import java.util.concurrent.ConcurrentHashMap; +import com.oracle.graal.graph.Graph.DuplicationReplacement; + import sun.misc.Unsafe; public class NodeClass { @@ -910,15 +912,21 @@ return directSuccessorCount; } - static Map addGraphDuplicate(Graph graph, Iterable nodes, Map replacements) { + static Map addGraphDuplicate(Graph graph, Iterable nodes, DuplicationReplacement replacements) { Map newNodes = new IdentityHashMap<>(); + Map replacementsMap = new IdentityHashMap<>(); // create node duplicates for (Node node : nodes) { - if (node != null && !replacements.containsKey(node)) { + if (node != null) { assert !node.isDeleted() : "trying to duplicate deleted node"; - Node newNode = node.clone(graph); - assert newNode.getClass() == node.getClass(); - newNodes.put(node, newNode); + Node replacement = replacements.replacement(node); + if (replacement != node) { + replacementsMap.put(node, replacement); + } else { + Node newNode = node.clone(graph); + assert newNode.getClass() == node.getClass(); + newNodes.put(node, newNode); + } } } // re-wire inputs @@ -928,24 +936,29 @@ for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) { Position pos = iter.nextPosition(); Node input = oldNode.getNodeClass().get(oldNode, pos); - Node target = replacements.get(input); + Node target = replacementsMap.get(input); if (target == null) { - target = newNodes.get(input); + Node replacement = replacements.replacement(input); + if (replacement != input) { + replacementsMap.put(input, replacement); + target = replacement; + } else { + target = newNodes.get(input); + } } node.getNodeClass().set(node, pos, target); } } - for (Entry entry : replacements.entrySet()) { + for (Entry entry : replacementsMap.entrySet()) { Node oldNode = entry.getKey(); Node node = entry.getValue(); - if (oldNode == node) { - continue; - } for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) { Position pos = iter.nextPosition(); - Node input = oldNode.getNodeClass().get(oldNode, pos); - if (newNodes.containsKey(input)) { - node.getNodeClass().set(node, pos, newNodes.get(input)); + if (pos.isValidFor(node, oldNode)) { + Node input = oldNode.getNodeClass().get(oldNode, pos); + if (newNodes.containsKey(input)) { + node.getNodeClass().set(node, pos, newNodes.get(input)); + } } } } @@ -957,24 +970,27 @@ for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) { Position pos = iter.nextPosition(); Node succ = oldNode.getNodeClass().get(oldNode, pos); - Node target = replacements.get(succ); - if (target == null) { + Node target = replacementsMap.get(succ); + Node replacement = replacements.replacement(succ); + if (replacement != succ) { + replacementsMap.put(succ, replacement); + target = replacement; + } else { target = newNodes.get(succ); } node.getNodeClass().set(node, pos, target); } } - for (Entry entry : replacements.entrySet()) { + for (Entry entry : replacementsMap.entrySet()) { Node oldNode = entry.getKey(); Node node = entry.getValue(); - if (oldNode == node) { - continue; - } for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) { Position pos = iter.nextPosition(); - Node succ = oldNode.getNodeClass().get(oldNode, pos); - if (newNodes.containsKey(succ)) { - node.getNodeClass().set(node, pos, newNodes.get(succ)); + if (pos.isValidFor(node, oldNode)) { + Node succ = oldNode.getNodeClass().get(oldNode, pos); + if (newNodes.containsKey(succ)) { + node.getNodeClass().set(node, pos, newNodes.get(succ)); + } } } }