# HG changeset patch # User Thomas Wuerthinger # Date 1379354214 -7200 # Node ID 891fa65ef9ec846deb056a4dba879c287a50eaa2 # Parent a625d254e13752470641e9c4f32a4f87ffe407da# Parent 929a03fbbbafd8001d2e35b81bee7bca8bc35097 Merge. diff -r 929a03fbbbaf -r 891fa65ef9ec 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 Mon Sep 16 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Sep 16 19:56:54 2013 +0200 @@ -83,7 +83,7 @@ if (obj instanceof CacheEntry) { CacheEntry other = (CacheEntry) obj; NodeClass nodeClass = node.getNodeClass(); - if (other.node.getNodeClass() == nodeClass) { + if (other.node.getClass() == node.getClass()) { return nodeClass.valueEqual(node, other.node); } } @@ -188,8 +188,7 @@ */ public Graph copy(String newName) { Graph copy = new Graph(newName); - Map emptyMap = Collections.emptyMap(); - copy.addDuplicates(getNodes(), emptyMap); + copy.addDuplicates(getNodes(), (Map) null); return copy; } @@ -344,7 +343,7 @@ } if (minCountNode != null) { for (Node usage : minCountNode.usages()) { - if (usage != node && nodeClass == usage.getNodeClass() && nodeClass.valueEqual(node, usage) && node.getNodeClass().edgesEqual(node, usage)) { + if (usage != node && nodeClass == usage.getNodeClass() && nodeClass.valueEqual(node, usage) && nodeClass.edgesEqual(node, usage)) { return usage; } } diff -r 929a03fbbbaf -r 891fa65ef9ec 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 Mon Sep 16 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Sep 16 19:56:54 2013 +0200 @@ -800,6 +800,7 @@ boolean neighborsAlternate = ((flags & FormattableFlags.LEFT_JUSTIFY) == FormattableFlags.LEFT_JUSTIFY); int neighborsFlags = (neighborsAlternate ? FormattableFlags.ALTERNATE | FormattableFlags.LEFT_JUSTIFY : 0); + NodeClass nodeClass = getNodeClass(); if (width > 0) { if (this.predecessor != null) { formatter.format(" pred={"); @@ -810,10 +811,10 @@ NodeClassIterator inputIter = inputs().iterator(); while (inputIter.hasNext()) { Position position = inputIter.nextPosition(); - Node input = getNodeClass().get(this, position); + Node input = nodeClass.get(this, position); if (input != null) { formatter.format(" "); - formatter.format(getNodeClass().getName(position)); + formatter.format(nodeClass.getName(position)); formatter.format("={"); input.formatTo(formatter, neighborsFlags, width - 1, 0); formatter.format("}"); @@ -838,10 +839,10 @@ NodeClassIterator succIter = successors().iterator(); while (succIter.hasNext()) { Position position = succIter.nextPosition(); - Node successor = getNodeClass().get(this, position); + Node successor = nodeClass.get(this, position); if (successor != null) { formatter.format(" "); - formatter.format(getNodeClass().getName(position)); + formatter.format(nodeClass.getName(position)); formatter.format("={"); successor.formatTo(formatter, neighborsFlags, 0, precision - 1); formatter.format("}"); diff -r 929a03fbbbaf -r 891fa65ef9ec 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 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Sep 16 19:56:54 2013 +0200 @@ -427,6 +427,7 @@ */ public static final class NodeClassIterator implements Iterator { + private final NodeClass nodeClass; private final Node node; private final int modCount; private final int directCount; @@ -444,6 +445,7 @@ */ private NodeClassIterator(Node node, long[] offsets, int directCount) { this.node = node; + this.nodeClass = node.getNodeClass(); this.modCount = MODIFICATION_COUNTS_ENABLED ? node.modCount() : 0; this.offsets = offsets; this.directCount = directCount; @@ -510,9 +512,9 @@ public Position nextPosition() { try { if (index < directCount) { - return new Position(offsets == node.getNodeClass().inputOffsets, index, NOT_ITERABLE); + return new Position(offsets == nodeClass.inputOffsets, index, NOT_ITERABLE); } else { - return new Position(offsets == node.getNodeClass().inputOffsets, index, subIndex); + return new Position(offsets == nodeClass.inputOffsets, index, subIndex); } } finally { forward(); @@ -591,7 +593,7 @@ } public boolean valueEqual(Node a, Node b) { - if (!canGVN || a.getNodeClass() != b.getNodeClass()) { + if (!canGVN || a.getClass() != b.getClass()) { return a == b; } for (int i = 0; i < dataOffsets.length; ++i) { @@ -967,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) { @@ -994,20 +995,17 @@ } Node input = oldNode.getNodeClass().get(oldNode, pos); 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(node.getNodeClass().fieldTypes.get(node.getNodeClass().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; } } - node.getNodeClass().set(node, pos, target); + nodeClass.set(node, pos, target); } } @@ -1023,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 929a03fbbbaf -r 891fa65ef9ec 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 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Mon Sep 16 19:56:54 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 929a03fbbbaf -r 891fa65ef9ec 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 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java Mon Sep 16 19:56:54 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 929a03fbbbaf -r 891fa65ef9ec graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Mon Sep 16 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Mon Sep 16 19:56:54 2013 +0200 @@ -103,7 +103,6 @@ public FrameState(ResolvedJavaMethod method, int bci, List values, int localsSize, int stackSize, boolean rethrowException, boolean duringCall, List virtualObjectMappings) { assert stackSize >= 0; - assert (bci >= 0 && method != null) || (bci < 0 && method == null && values.isEmpty()); this.method = method; this.bci = bci; this.localsSize = localsSize; @@ -125,29 +124,24 @@ } public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, List stack, ValueNode[] locks, boolean rethrowException, boolean duringCall) { - this.method = method; - this.bci = bci; - this.localsSize = locals.length; - this.stackSize = stack.size(); - final ValueNode[] newValues = new ValueNode[locals.length + stack.size() + locks.length]; - int pos = 0; + this(method, bci, createValues(locals, stack, locks), locals.length, stack.size(), rethrowException, duringCall, Collections. emptyList()); + } + + private static List createValues(ValueNode[] locals, List stack, ValueNode[] locks) { + List newValues = new ArrayList<>(locals.length + stack.size() + locks.length); for (ValueNode value : locals) { - newValues[pos++] = value; + newValues.add(value); + assert value == null || value.isAlive(); } for (ValueNode value : stack) { - newValues[pos++] = value; + newValues.add(value); + assert value == null || value.isAlive(); } for (ValueNode value : locks) { - newValues[pos++] = value; - } - for (ValueNode value : newValues) { + newValues.add(value); assert value == null || value.isAlive(); } - this.values = new NodeInputList<>(this, newValues); - this.virtualObjectMappings = new NodeInputList<>(this); - this.rethrowException = rethrowException; - this.duringCall = duringCall; - assert !rethrowException || stackSize == 1 : "must have exception on top of the stack"; + return newValues; } public NodeInputList values() { diff -r 929a03fbbbaf -r 891fa65ef9ec 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 Mon Sep 16 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Mon Sep 16 19:56:54 2013 +0200 @@ -215,7 +215,8 @@ } public static boolean tryGlobalValueNumbering(Node node) { - if (node.getNodeClass().valueNumberable() && !node.getNodeClass().isLeafNode()) { + NodeClass nodeClass = node.getNodeClass(); + if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { assert !(node instanceof FixedNode || newNode instanceof FixedNode); diff -r 929a03fbbbaf -r 891fa65ef9ec 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 17:15:31 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Mon Sep 16 19:56:54 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()); }