# HG changeset patch # User Thomas Wuerthinger # Date 1379354076 -7200 # Node ID a625d254e13752470641e9c4f32a4f87ffe407da # Parent 05230c6c8d52cd3769884387428902ff0000e5bd Avoid allocation of replacement hashmap in addDuplicates and also in InliningUtil.inline. diff -r 05230c6c8d52 -r a625d254e137 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 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 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) { @@ -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); diff -r 05230c6c8d52 -r a625d254e137 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- 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 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; } diff -r 05230c6c8d52 -r a625d254e137 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java --- 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; } diff -r 05230c6c8d52 -r a625d254e137 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- 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 inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) { - NodeInputList parameters = invoke.callTarget().arguments(); + final NodeInputList parameters = invoke.callTarget().arguments(); StructuredGraph graph = invoke.asNode().graph(); FrameState stateAfter = invoke.stateAfter(); @@ -1297,17 +1298,14 @@ nonNullReceiver(invoke); } - IdentityHashMap replacements = new IdentityHashMap<>(); - ArrayList nodes = new ArrayList<>(); + ArrayList 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 duplicates = graph.addDuplicates(nodes, replacements); + Map 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()); }