# HG changeset patch # User Thomas Wuerthinger # Date 1379286873 -7200 # Node ID 64a9ed9f1e8dd51342e62b2f12a84e560d6e25ba # Parent f091e0d6f4f399a6342f3104b92a4abc304a57e3 Introduce NodeClass.isLeafNode(). Avoid cloning of leaf nodes if equal node is found in destination graph. diff -r f091e0d6f4f3 -r 64a9ed9f1e8d 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 Sun Sep 15 22:33:09 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Sep 16 01:14:33 2013 +0200 @@ -65,6 +65,8 @@ private final Node node; public CacheEntry(Node node) { + assert node.getNodeClass().valueNumberable(); + assert node.getNodeClass().isLeafNode(); this.node = node; } @@ -82,7 +84,7 @@ CacheEntry other = (CacheEntry) obj; NodeClass nodeClass = node.getNodeClass(); if (other.node.getNodeClass() == nodeClass) { - return nodeClass.valueNumberable() && nodeClass.valueEqual(node, other.node) && nodeClass.edgesEqual(node, other.node); + return nodeClass.valueEqual(node, other.node); } } return false; @@ -284,30 +286,47 @@ } @SuppressWarnings("unchecked") - private T uniqueHelper(T node) { - - for (Node input : node.inputs()) { - if (input != null) { - for (Node usage : input.usages()) { - if (usage != node && node.getNodeClass().valueEqual(node, usage) && node.getNodeClass().edgesEqual(node, usage)) { - return (T) usage; - } - } - return addHelper(node); - } - } - Node cachedNode = cachedNodes.get(new CacheEntry(node)); - if (cachedNode != null && cachedNode.isAlive()) { - return (T) cachedNode; + T uniqueHelper(T node) { + assert node.getNodeClass().valueNumberable(); + Node other = this.findDuplicate(node); + if (other != null) { + return (T) other; } else { Node result = addHelper(node); - cachedNodes.put(new CacheEntry(node), result); + if (node.getNodeClass().isLeafNode()) { + putNodeIntoCache(result); + } return (T) result; } } + void putNodeIntoCache(Node node) { + assert node.graph() == this || node.graph() == null; + assert node.getNodeClass().valueNumberable(); + assert node.getNodeClass().isLeafNode() : node.getClass(); + cachedNodes.put(new CacheEntry(node), node); + } + + Node findNodeInCache(Node node) { + CacheEntry key = new CacheEntry(node); + Node result = cachedNodes.get(key); + if (result != null && result.isDeleted()) { + cachedNodes.remove(key); + return null; + } + return result; + } + public Node findDuplicate(Node node) { - if (node.getNodeClass().valueNumberable()) { + assert node.getNodeClass().valueNumberable(); + if (node.getNodeClass().isLeafNode()) { + Node cachedNode = findNodeInCache(node); + if (cachedNode != null) { + return cachedNode; + } else { + return null; + } + } else { for (Node input : node.inputs()) { if (input != null) { for (Node usage : input.usages()) { @@ -318,17 +337,6 @@ return null; } } - } - CacheEntry key = new CacheEntry(node); - Node cachedNode = cachedNodes.get(key); - if (cachedNode != null) { - if (!cachedNode.isAlive()) { - cachedNodes.remove(key); - return null; - } - return cachedNode != node ? cachedNode : null; - } else { - cachedNodes.put(key, node); return null; } } diff -r f091e0d6f4f3 -r 64a9ed9f1e8d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Sun Sep 15 22:33:09 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Sep 16 01:14:33 2013 +0200 @@ -581,15 +581,25 @@ return newNode; } + static int count = 0; + public Node clone(Graph into) { + NodeClass nodeClass = getNodeClass(); + if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) { + Node otherNode = into.findNodeInCache(this); + if (otherNode != null) { + return otherNode; + } + } + Node newNode = null; try { newNode = (Node) this.clone(); } catch (CloneNotSupportedException e) { throw new GraalInternalError(e).addContext(this); } - getNodeClass().clearInputs(newNode); - getNodeClass().clearSuccessors(newNode); + nodeClass.clearInputs(newNode); + nodeClass.clearSuccessors(newNode); newNode.graph = into; newNode.typeCacheNext = null; newNode.id = INITIAL_ID; @@ -598,6 +608,10 @@ newNode.usage1 = null; newNode.extraUsages = NO_NODES; newNode.predecessor = null; + + if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) { + into.putNodeIntoCache(newNode); + } return newNode; } diff -r f091e0d6f4f3 -r 64a9ed9f1e8d 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 Sun Sep 15 22:33:09 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Sep 16 01:14:33 2013 +0200 @@ -139,6 +139,7 @@ private final long[] successorOffsets; private final Class[] dataTypes; private final boolean canGVN; + private final boolean isLeafNode; private final int startGVNNumber; private final String shortName; private final String nameTemplate; @@ -212,6 +213,8 @@ this.iterableId = NOT_ITERABLE; this.iterableIds = null; } + + isLeafNode = (this.inputOffsets.length == 0 && this.successorOffsets.length == 0); } @Override @@ -250,6 +253,10 @@ return canGVN; } + public boolean isLeafNode() { + return isLeafNode; + } + public static int cacheSize() { return nextIterableId; } diff -r f091e0d6f4f3 -r 64a9ed9f1e8d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Sun Sep 15 22:33:09 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Mon Sep 16 01:14:33 2013 +0200 @@ -215,7 +215,7 @@ } public static boolean tryGlobalValueNumbering(Node node) { - if (node.getNodeClass().valueNumberable()) { + if (node.getNodeClass().valueNumberable() && !node.getNodeClass().isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { assert !(node instanceof FixedNode || newNode instanceof FixedNode);