changeset 11653:64a9ed9f1e8d

Introduce NodeClass.isLeafNode(). Avoid cloning of leaf nodes if equal node is found in destination graph.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 16 Sep 2013 01:14:33 +0200
parents f091e0d6f4f3
children 317036da1f29
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java
diffstat 4 files changed, 61 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- 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 extends Node> 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 extends Node> 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;
         }
     }
--- 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;
     }
 
--- 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;
     }
--- 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);