changeset 11669:a625d254e137

Avoid allocation of replacement hashmap in addDuplicates and also in InliningUtil.inline.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 16 Sep 2013 19:54:36 +0200
parents 05230c6c8d52
children 891fa65ef9ec
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java
diffstat 4 files changed, 60 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon Sep 16 19:54:00 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon Sep 16 19:54:36 2013 +0200
@@ -969,7 +969,6 @@
 
     static Map<Node, Node> addGraphDuplicate(Graph graph, Iterable<Node> nodes, DuplicationReplacement replacements) {
         Map<Node, Node> newNodes = new IdentityHashMap<>();
-        Map<Node, Node> replacementsMap = new IdentityHashMap<>();
         // create node duplicates
         for (Node node : nodes) {
             if (node != null) {
@@ -998,16 +997,12 @@
                 Node target = newNodes.get(input);
                 NodeClass nodeClass = node.getNodeClass();
                 if (target == null) {
-                    target = replacementsMap.get(input);
-                    if (target == null) {
-                        Node replacement = replacements.replacement(input);
-                        if (replacement != input) {
-                            replacementsMap.put(input, replacement);
-                            assert isAssignable(nodeClass.fieldTypes.get(nodeClass.inputOffsets[pos.index]), replacement);
-                            target = replacement;
-                        } else if (input.graph() == graph) { // patch to the outer world
-                            target = input;
-                        }
+                    Node replacement = replacements.replacement(input);
+                    if (replacement != input) {
+                        assert isAssignable(nodeClass.fieldTypes.get(nodeClass.inputOffsets[pos.index]), replacement);
+                        target = replacement;
+                    } else if (input.graph() == graph) { // patch to the outer world
+                        target = input;
                     }
                 }
                 nodeClass.set(node, pos, target);
@@ -1026,14 +1021,10 @@
                 Node succ = oldNode.getNodeClass().get(oldNode, pos);
                 Node target = newNodes.get(succ);
                 if (target == null) {
-                    target = replacementsMap.get(succ);
-                    if (target == null) {
-                        Node replacement = replacements.replacement(succ);
-                        if (replacement != succ) {
-                            replacementsMap.put(succ, replacement);
-                            assert isAssignable(node.getNodeClass().fieldTypes.get(node.getNodeClass().successorOffsets[pos.index]), replacement);
-                            target = replacement;
-                        }
+                    Node replacement = replacements.replacement(succ);
+                    if (replacement != succ) {
+                        assert isAssignable(node.getNodeClass().fieldTypes.get(node.getNodeClass().successorOffsets[pos.index]), replacement);
+                        target = replacement;
                     }
                 }
                 node.getNodeClass().set(node, pos, target);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Mon Sep 16 19:54:00 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Mon Sep 16 19:54:36 2013 +0200
@@ -125,16 +125,36 @@
         final StructuredGraph graph = graph();
         return new DuplicationReplacement() {
 
+            private HashMap<Node, Node> seenNode = new HashMap<>();
+
             @Override
             public Node replacement(Node original) {
                 if (original == loopBegin) {
-                    return graph.add(new BeginNode());
+                    Node value = seenNode.get(original);
+                    if (value != null) {
+                        return value;
+                    }
+                    BeginNode newValue = graph.add(new BeginNode());
+                    seenNode.put(original, newValue);
+                    return newValue;
                 }
                 if (original instanceof LoopExitNode && ((LoopExitNode) original).loopBegin() == loopBegin) {
-                    return graph.add(new BeginNode());
+                    Node value = seenNode.get(original);
+                    if (value != null) {
+                        return value;
+                    }
+                    BeginNode newValue = graph.add(new BeginNode());
+                    seenNode.put(original, newValue);
+                    return newValue;
                 }
                 if (original instanceof LoopEndNode && ((LoopEndNode) original).loopBegin() == loopBegin) {
-                    return graph.add(new EndNode());
+                    Node value = seenNode.get(original);
+                    if (value != null) {
+                        return value;
+                    }
+                    EndNode newValue = graph.add(new EndNode());
+                    seenNode.put(original, newValue);
+                    return newValue;
                 }
                 return original;
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Mon Sep 16 19:54:00 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Mon Sep 16 19:54:36 2013 +0200
@@ -68,10 +68,15 @@
         final Graph graph = this.graph();
         return new DuplicationReplacement() {
 
+            private EndNode endNode;
+
             @Override
             public Node replacement(Node o) {
                 if (o == entry) {
-                    return graph.add(new EndNode());
+                    if (endNode == null) {
+                        endNode = graph.add(new EndNode());
+                    }
+                    return endNode;
                 }
                 return o;
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Sep 16 19:54:00 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Sep 16 19:54:36 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -604,7 +605,7 @@
             ValueNode originalReceiver = ((MethodCallTargetNode) invoke.callTarget()).receiver();
             // setup merge and phi nodes for results and exceptions
             MergeNode returnMerge = graph.add(new MergeNode());
-            returnMerge.setStateAfter(invoke.stateAfter().duplicate(invoke.stateAfter().bci));
+            returnMerge.setStateAfter(invoke.stateAfter());
 
             PhiNode returnValuePhi = null;
             if (invoke.asNode().kind() != Kind.Void) {
@@ -1288,7 +1289,7 @@
      *            false if no such check is required
      */
     public static Map<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) {
-        NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
+        final NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
         StructuredGraph graph = invoke.asNode().graph();
 
         FrameState stateAfter = invoke.stateAfter();
@@ -1297,17 +1298,14 @@
             nonNullReceiver(invoke);
         }
 
-        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
-        ArrayList<Node> nodes = new ArrayList<>();
+        ArrayList<Node> nodes = new ArrayList<>(inlineGraph.getNodes().count());
         ReturnNode returnNode = null;
         UnwindNode unwindNode = null;
-        StartNode entryPointNode = inlineGraph.start();
+        final StartNode entryPointNode = inlineGraph.start();
         FixedNode firstCFGNode = entryPointNode.next();
         for (Node node : inlineGraph.getNodes()) {
-            if (node == entryPointNode || node == entryPointNode.stateAfter()) {
+            if (node == entryPointNode || node == entryPointNode.stateAfter() || node instanceof LocalNode) {
                 // Do nothing.
-            } else if (node instanceof LocalNode) {
-                replacements.put(node, parameters.get(((LocalNode) node).index()));
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
@@ -1319,13 +1317,24 @@
                 }
             }
         }
-        // ensure proper anchoring of things that were anchored to the StartNode
-        replacements.put(entryPointNode, AbstractBeginNode.prevBegin(invoke.asNode()));
+
+        final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invoke.asNode());
+        DuplicationReplacement localReplacement = new DuplicationReplacement() {
+
+            public Node replacement(Node node) {
+                if (node instanceof LocalNode) {
+                    return parameters.get(((LocalNode) node).index());
+                } else if (node == entryPointNode) {
+                    return prevBegin;
+                }
+                return node;
+            }
+        };
 
         assert invoke.asNode().successors().first() != null : invoke;
         assert invoke.asNode().predecessor() != null;
 
-        Map<Node, Node> duplicates = graph.addDuplicates(nodes, replacements);
+        Map<Node, Node> duplicates = graph.addDuplicates(nodes, localReplacement);
         FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
         invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate);
 
@@ -1410,7 +1419,7 @@
         Node returnValue = null;
         if (returnNode != null) {
             if (returnNode.result() instanceof LocalNode) {
-                returnValue = replacements.get(returnNode.result());
+                returnValue = localReplacement.replacement(returnNode.result());
             } else {
                 returnValue = duplicates.get(returnNode.result());
             }