# HG changeset patch # User Doug Simon # Date 1383488872 -3600 # Node ID 2c4aa758ee1803e0c90a31e4bcc89b8627874178 # Parent 1c0261ebeeedecd3b846d1c58460bb365587a0f7 made ConstantNodes external to a Graph (GRAAL-508) diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Sun Nov 03 15:27:52 2013 +0100 @@ -144,8 +144,8 @@ StructuredGraph graph = parse("testNullnessSnippet"); new ConditionalEliminationPhase(getMetaAccess()).apply(graph); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); - for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { - if (ConstantNodeRecordsUsages || !constant.gatherUsages().isEmpty()) { + for (ConstantNode constant : getConstantNodes(graph)) { + if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } } @@ -178,8 +178,8 @@ new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); new ConditionalEliminationPhase(getMetaAccess()).apply(graph); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null)); - for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) { - if (ConstantNodeRecordsUsages || !constant.gatherUsages().isEmpty()) { + for (ConstantNode constant : getConstantNodes(graph)) { + if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) { assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Sun Nov 03 15:27:52 2013 +0100 @@ -119,9 +119,9 @@ protected int countUnusedConstants(StructuredGraph graph) { int total = 0; - for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { + for (ConstantNode node : getConstantNodes(graph)) { if (!ConstantNodeRecordsUsages) { - if (node.gatherUsages().isEmpty()) { + if (node.gatherUsages(graph).isEmpty()) { total++; } } else { @@ -520,7 +520,6 @@ if (cached.isValid()) { return cached; } - } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java Sun Nov 03 15:27:52 2013 +0100 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -59,12 +58,9 @@ new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); new DeadCodeEliminationPhase().apply(graph); - for (Node node : graph.getNodes()) { - if (node instanceof ConstantNode) { - ConstantNode constant = (ConstantNode) node; - if (constant.kind() == Kind.Object && " ".equals(constant.value.asObject())) { - constant.replace(ConstantNode.forObject("-", getMetaAccess(), graph)); - } + for (ConstantNode node : ConstantNode.getConstantNodes(graph)) { + if (node.kind() == Kind.Object && " ".equals(node.getValue().asObject())) { + node.replace(graph, ConstantNode.forObject("-", getMetaAccess(), graph)); } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Sun Nov 03 15:27:52 2013 +0100 @@ -187,7 +187,7 @@ } } else if (value instanceof ConstantNode) { Debug.metric("StateConstants").increment(); - return ((ConstantNode) value).value; + return ((ConstantNode) value).getValue(); } else if (value != null) { Debug.metric("StateVariables").increment(); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Sun Nov 03 15:27:52 2013 +0100 @@ -159,7 +159,7 @@ if (nodeOperands == null) { return null; } - Value operand = nodeOperands.get(node); + Value operand = !node.isExternal() ? nodeOperands.get(node) : null; if (operand == null) { return getConstantOperand(node); } @@ -171,7 +171,7 @@ Constant value = node.asConstant(); if (value != null) { if (canInlineConstant(value)) { - return setResult(node, value); + return !node.isExternal() ? setResult(node, value) : value; } else { Variable loadedValue; if (constantsLoadedInCurrentBlock == null) { diff -r 1c0261ebeeed -r 2c4aa758ee18 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 Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Sun Nov 03 15:27:52 2013 +0100 @@ -235,7 +235,7 @@ public T addOrUnique(T node) { if (node.getNodeClass().valueNumberable()) { - return uniqueHelper(node); + return uniqueHelper(node, true); } return add(node); } @@ -301,27 +301,38 @@ } /** - * Adds a new node to the graph, if a similar node already exists in the graph, the - * provided node will not be added to the graph but the similar node will be returned - * instead. + * Looks for a node similar to {@code node} and returns it if found. Otherwise + * {@code node} is added to this graph and returned. * - * @param node - * @return the node which was added to the graph or a similar which was already in the - * graph. + * @return a node similar to {@code node} if one exists, otherwise {@code node} */ public T unique(T node) { - assert checkValueNumberable(node); - return uniqueHelper(node); + return uniqueHelper(node, true); + } + + /** + * Looks for a node similar to {@code node}. If not found, {@code node} is added to the + * cache in this graph used to canonicalize nodes. + *

+ * Note that node must implement {@link ValueNumberable} and must be an + * {@linkplain Node#isExternal() external} node. + * + * @return a node similar to {@code node} if one exists, otherwise {@code node} + */ + public T uniqueWithoutAdd(T node) { + assert node.isExternal() : node; + assert node instanceof ValueNumberable : node; + return uniqueHelper(node, false); } @SuppressWarnings("unchecked") - T uniqueHelper(T node) { + T uniqueHelper(T node, boolean addIfMissing) { assert node.getNodeClass().valueNumberable(); Node other = this.findDuplicate(node); if (other != null) { return (T) other; } else { - Node result = addHelper(node); + Node result = addIfMissing ? addHelper(node) : node; if (node.getNodeClass().isLeafNode()) { putNodeIntoCache(result); } @@ -330,7 +341,7 @@ } void putNodeIntoCache(Node node) { - assert node.graph() == this || node.graph() == null; + assert node.isExternal() || node.graph() == this || node.graph() == null; assert node.getNodeClass().valueNumberable(); assert node.getNodeClass().isLeafNode() : node.getClass(); cachedNodes.put(new CacheEntry(node), node); @@ -383,13 +394,6 @@ } } - private static boolean checkValueNumberable(Node node) { - if (!node.getNodeClass().valueNumberable()) { - throw new VerificationError("node is not valueNumberable").addContext(node); - } - return true; - } - public boolean isNew(int mark, Node node) { return node.id >= mark; } @@ -650,6 +654,7 @@ } void register(Node node) { + assert !node.isExternal(); assert node.id() == Node.INITIAL_ID; int id = nodes.size(); nodes.add(id, node); diff -r 1c0261ebeeed -r 2c4aa758ee18 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 Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Sun Nov 03 15:27:52 2013 +0100 @@ -156,7 +156,12 @@ return id; } + /** + * Gets the graph context of this node. This must not be called for {@linkplain #isExternal() + * external} nodes. + */ public Graph graph() { + assert !isExternal() : "external node has no graph: " + this; return graph; } @@ -283,6 +288,15 @@ } /** + * Determines if this node has a {@linkplain #graph() graph} context or is external to any + * graph. The {@link #graph()} method must only be called on nodes for which this method returns + * true. + */ + public boolean isExternal() { + return false; + } + + /** * Finds the index of the last non-null entry in a node array. The search assumes that all * non-null entries precede the first null entry in the array. * @@ -517,7 +531,7 @@ assert assertFalse(other == this, "cannot replace a node with itself"); assert assertFalse(isDeleted(), "cannot replace deleted node"); assert assertTrue(other == null || !other.isDeleted(), "cannot replace with deleted node %s", other); - assert assertTrue(other == null || other.graph() == graph, "cannot replace with node in different graph: %s", other == null ? null : other.graph()); + assert assertTrue(other == null || other.isExternal() || other.graph() == graph, "cannot replace with node in different graph: %s", other == null || other.isExternal() ? null : other.graph()); return true; } @@ -574,7 +588,7 @@ assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); for (Node input : inputs()) { - if (input.recordsUsages()) { + if (input.recordsUsages() && !input.isExternal()) { removeThisFromUsages(input); if (input.usages().isEmpty()) { NodeChangedListener listener = graph.usagesDroppedToZeroListener; @@ -623,6 +637,7 @@ } public final Node copyWithInputs() { + assert !isExternal(); Node newNode = clone(graph); NodeClass clazz = getNodeClass(); clazz.copyInputs(this, newNode); @@ -661,6 +676,7 @@ } final Node clone(Graph into, boolean clearInputsAndSuccessors) { + assert !isExternal(); NodeClass nodeClass = getNodeClass(); if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) { Node otherNode = into.findNodeInCache(this); @@ -695,6 +711,23 @@ return newNode; } + /** + * Determines if a given node is {@linkplain Graph#uniqueWithoutAdd(Node) unique} within a given + * graph if the node is non-null and {@linkplain #isExternal() external}. + * + * @param node node to check + * @param graph graph context to use + * @return true if node is null, not external or unique within {@code graph} otherwise raises a + * {@link VerificationError} + */ + public static boolean verifyUniqueIfExternal(Node node, Graph graph) { + if (node != null && node.isExternal()) { + Node cached = graph.findNodeInCache(node); + node.assertTrue(cached == node, "external node does not match canonical node %s", cached); + } + return true; + } + protected void afterClone(@SuppressWarnings("unused") Node other) { } @@ -703,7 +736,8 @@ assertTrue(graph() != null, "null graph"); for (Node input : inputs()) { assertTrue(!input.recordsUsages() || input.usages().contains(this), "missing usage in input %s", input); - assertTrue(input.graph() == graph(), "mismatching graph in input %s", input); + assert verifyUniqueIfExternal(input, graph()); + assertTrue(input.isExternal() || input.graph() == graph(), "mismatching graph in input %s", input); } for (Node successor : successors()) { assertTrue(successor.predecessor() == this, "missing predecessor in %s (actual: %s)", successor, successor.predecessor()); @@ -757,17 +791,18 @@ } /** - * hashCode and equals should always rely on object identity alone, thus hashCode and equals are - * final. + * Nodes always use an {@linkplain System#identityHashCode(Object) identity} hash code. For this + * reason, {@linkplain #isExternal() external} nodes should still be {@link Graph#unique unique} + * within the context of a graph. */ @Override public final int hashCode() { - return super.hashCode(); + return System.identityHashCode(this); } /** - * hashCode and equals should always rely on object identity alone, thus hashCode and equals are - * final. + * Equality tests must rely solely on identity. For this reason, {@linkplain #isExternal() + * external} nodes should still be {@link Graph#unique unique} within the context of a graph. */ @Override public final boolean equals(Object obj) { diff -r 1c0261ebeeed -r 2c4aa758ee18 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 Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Sun Nov 03 15:27:52 2013 +0100 @@ -30,9 +30,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; -import com.oracle.graal.graph.Node.Input; -import com.oracle.graal.graph.Node.Successor; -import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.graph.Node.*; import com.oracle.graal.graph.spi.*; /** @@ -835,6 +833,7 @@ if (input != null) { Node newInput = duplicationReplacement.replacement(input, true); node.updateUsages(null, newInput); + assert Node.verifyUniqueIfExternal(newInput, node.graph()); putNode(node, inputOffsets[index], newInput); } index++; @@ -887,6 +886,7 @@ Node oldNode = list.get(i); if (oldNode != null) { Node newNode = duplicationReplacement.replacement(oldNode, true); + assert Node.verifyUniqueIfExternal(newNode, node.graph()); result.set(i, newNode); } } @@ -971,6 +971,7 @@ } public boolean replaceFirstInput(Node node, Node old, Node other) { + assert Node.verifyUniqueIfExternal(other, node.graph()); int index = 0; while (index < directInputCount) { Node input = getNode(node, inputOffsets[index]); @@ -1268,6 +1269,9 @@ InplaceUpdateClosure replacementClosure = new InplaceUpdateClosure() { public Node replacement(Node node, boolean isInput) { + if (node.isExternal() && node instanceof ValueNumberable) { + return graph.uniqueWithoutAdd(node); + } Node target = newNodes.get(node); if (target == null) { Node replacement = node; diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java Sun Nov 03 15:27:52 2013 +0100 @@ -160,4 +160,27 @@ } }; } + + @Override + public String toString() { + Iterator> i = entries().iterator(); + if (!i.hasNext()) { + return "{}"; + } + + StringBuilder sb = new StringBuilder(); + sb.append('{'); + while (true) { + Entry e = i.next(); + Node key = e.getKey(); + T value = e.getValue(); + sb.append(key); + sb.append('='); + sb.append(value); + if (!i.hasNext()) { + return sb.append('}').toString(); + } + sb.append(',').append(' '); + } + } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java Sun Nov 03 15:27:52 2013 +0100 @@ -60,7 +60,7 @@ public void addAll(Iterable nodes) { for (Node node : nodes) { - if (node.isAlive()) { + if (node.isAlive() && !node.isExternal()) { this.add(node); } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Sun Nov 03 15:27:52 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.test; import static com.oracle.graal.api.code.CodeUtil.*; +import static com.oracle.graal.nodes.ConstantNode.*; import static com.oracle.graal.phases.GraalOptions.*; import org.junit.*; @@ -64,8 +65,8 @@ @Test public void testStaticFinalObjectAOT() { StructuredGraph result = compile("getStaticFinalObject", true); - assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); - assertEquals(getCodeCache().getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind()); + assertEquals(1, getConstantNodes(result).count()); + assertEquals(getCodeCache().getTarget().wordKind, getConstantNodes(result).first().kind()); assertEquals(2, result.getNodes(FloatingReadNode.class).count()); assertEquals(0, result.getNodes().filter(ReadNode.class).count()); } @@ -73,8 +74,8 @@ @Test public void testStaticFinalObject() { StructuredGraph result = compile("getStaticFinalObject", false); - assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); - assertEquals(Kind.Object, result.getNodes().filter(ConstantNode.class).first().kind()); + assertEquals(1, getConstantNodes(result).count()); + assertEquals(Kind.Object, getConstantNodes(result).first().kind()); assertEquals(0, result.getNodes(FloatingReadNode.class).count()); assertEquals(0, result.getNodes().filter(ReadNode.class).count()); } @@ -87,7 +88,7 @@ public void testClassObjectAOT() { StructuredGraph result = compile("getClassObject", true); - NodeIterable filter = result.getNodes().filter(ConstantNode.class); + NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class); assertEquals(type.klass(), filter.first().asConstant()); @@ -100,7 +101,7 @@ public void testClassObject() { StructuredGraph result = compile("getClassObject", false); - NodeIterable filter = result.getNodes().filter(ConstantNode.class); + NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); Object mirror = filter.first().asConstant().asObject(); assertEquals(Class.class, mirror.getClass()); @@ -117,7 +118,7 @@ @Test public void testPrimitiveClassObjectAOT() { StructuredGraph result = compile("getPrimitiveClassObject", true); - NodeIterable filter = result.getNodes().filter(ConstantNode.class); + NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); assertEquals(getCodeCache().getTarget().wordKind, filter.first().kind()); @@ -128,7 +129,7 @@ @Test public void testPrimitiveClassObject() { StructuredGraph result = compile("getPrimitiveClassObject", false); - NodeIterable filter = result.getNodes().filter(ConstantNode.class); + NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); Object mirror = filter.first().asConstant().asObject(); assertEquals(Class.class, mirror.getClass()); @@ -156,7 +157,7 @@ private void testStringObjectCommon(boolean compileAOT) { StructuredGraph result = compile("getStringObject", compileAOT); - NodeIterable filter = result.getNodes().filter(ConstantNode.class); + NodeIterable filter = getConstantNodes(result); assertEquals(1, filter.count()); Object mirror = filter.first().asConstant().asObject(); assertEquals(String.class, mirror.getClass()); @@ -177,8 +178,8 @@ assertEquals(2, result.getNodes(FloatingReadNode.class).count()); assertEquals(1, result.getNodes(PiNode.class).count()); - assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); - ConstantNode constant = result.getNodes().filter(ConstantNode.class).first(); + assertEquals(1, getConstantNodes(result).count()); + ConstantNode constant = getConstantNodes(result).first(); assertEquals(Kind.Long, constant.kind()); assertEquals(((HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(Boolean.class)).klass(), constant.asConstant()); } @@ -188,8 +189,8 @@ StructuredGraph result = compile("getBoxedBoolean", false); assertEquals(0, result.getNodes(FloatingReadNode.class).count()); assertEquals(0, result.getNodes(PiNode.class).count()); - assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); - ConstantNode constant = result.getNodes().filter(ConstantNode.class).first(); + assertEquals(1, getConstantNodes(result).count()); + ConstantNode constant = getConstantNodes(result).first(); assertEquals(Kind.Object, constant.kind()); assertEquals(Boolean.TRUE, constant.asConstant().asObject()); } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java Sun Nov 03 15:27:52 2013 +0100 @@ -695,13 +695,14 @@ base /= scale; assert NumUtil.isInt(base); + StructuredGraph graph = location.graph(); if (index == null) { - return ConstantNode.forInt((int) base, location.graph()); + return ConstantNode.forInt((int) base, graph); } else { if (base == 0) { return index; } else { - return IntegerArithmeticNode.add(ConstantNode.forInt((int) base, location.graph()), index); + return IntegerArithmeticNode.add(graph, ConstantNode.forInt((int) base, graph), index); } } } @@ -709,7 +710,7 @@ private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { StructuredGraph g = n.graph(); ValueNode array = n.array(); - ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); + ValueNode arrayLength = readArrayLength(n.graph(), array, tool.getConstantReflection()); if (arrayLength == null) { Stamp stamp = StampFactory.positiveInt(); ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, runtime.getConfig().arrayLengthOffset, g), stamp, BarrierType.NONE, false)); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.phases; +import static com.oracle.graal.nodes.ConstantNode.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -38,8 +40,8 @@ @Override protected boolean verify(StructuredGraph graph, PhaseContext context) { - for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { - if (node.recordsUsages() || !node.gatherUsages().isEmpty()) { + for (ConstantNode node : getConstantNodes(graph)) { + if (node.recordsUsages() || !node.gatherUsages(graph).isEmpty()) { assert !isObject(node) || isNullReference(node) || isInternedString(node) : "illegal object constant: " + node; } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.phases; import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.nodes.ConstantNode.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.meta.*; @@ -52,23 +53,30 @@ this.classMirrorOffset = classMirrorOffset; } + private FloatingReadNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, Constant constant) { + if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { + MetaAccessProvider metaAccess = context.getMetaAccess(); + ResolvedJavaType type = metaAccess.lookupJavaType((Class) constant.asObject()); + assert type instanceof HotSpotResolvedObjectType; + + Constant klass = ((HotSpotResolvedObjectType) type).klass(); + ConstantNode klassNode = ConstantNode.forConstant(klass, metaAccess, graph); + + Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class)); + LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), classMirrorOffset, graph)); + FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp)); + return freadNode; + } + return null; + } + @Override protected void run(StructuredGraph graph, PhaseContext context) { - for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { + for (ConstantNode node : getConstantNodes(graph)) { Constant constant = node.asConstant(); - if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { - MetaAccessProvider metaAccess = context.getMetaAccess(); - ResolvedJavaType type = metaAccess.lookupJavaType((Class) constant.asObject()); - assert type instanceof HotSpotResolvedObjectType; - - Constant klass = ((HotSpotResolvedObjectType) type).klass(); - ConstantNode klassNode = ConstantNode.forConstant(klass, metaAccess, graph); - - Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class)); - LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), classMirrorOffset, graph)); - FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp)); - - node.replace(freadNode); + FloatingReadNode freadNode = getClassConstantReplacement(graph, context, constant); + if (freadNode != null) { + node.replace(graph, freadNode); } } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Sun Nov 03 15:27:52 2013 +0100 @@ -216,7 +216,7 @@ Arguments args; - StructuredGraph graph = hub.graph(); + StructuredGraph graph = instanceOf.graph(); if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) { Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); args = new Arguments(instanceofWithProfile, graph.getGuardsStage()); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java Sun Nov 03 15:27:52 2013 +0100 @@ -45,6 +45,11 @@ } @Override + public StructuredGraph graph() { + return phi.graph(); + } + + @Override public Direction direction() { Stamp stamp = rawStride.stamp(); if (stamp instanceof IntegerStamp) { @@ -83,7 +88,7 @@ return rawStride; } if (op instanceof IntegerSubNode) { - return rawStride.graph().unique(new NegateNode(rawStride)); + return graph().unique(new NegateNode(rawStride)); } throw GraalInternalError.shouldNotReachHere(); } @@ -117,7 +122,7 @@ @Override public ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind) { Kind fromKind = phi.kind(); - Graph graph = phi.graph(); + StructuredGraph graph = graph(); ValueNode stride = strideNode(); ValueNode maxTripCount = loop.counted().maxTripCountNode(assumePositiveTripCount); ValueNode initNode = this.initNode(); @@ -127,13 +132,13 @@ maxTripCount = graph.unique(new ConvertNode(convertOp, maxTripCount)); initNode = graph.unique(new ConvertNode(convertOp, initNode)); } - return IntegerArithmeticNode.add(IntegerArithmeticNode.mul(stride, IntegerArithmeticNode.sub(maxTripCount, ConstantNode.forIntegerKind(kind, 1, graph))), initNode); + return IntegerArithmeticNode.add(graph, IntegerArithmeticNode.mul(graph, stride, IntegerArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerKind(kind, 1, graph))), initNode); } @Override public ValueNode exitValueNode() { ValueNode maxTripCount = loop.counted().maxTripCountNode(false); - return IntegerArithmeticNode.add(IntegerArithmeticNode.mul(strideNode(), maxTripCount), initNode()); + return IntegerArithmeticNode.add(graph(), IntegerArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode()); } @Override diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Sun Nov 03 15:27:52 2013 +0100 @@ -25,7 +25,6 @@ import static com.oracle.graal.nodes.calc.IntegerArithmeticNode.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.loop.InductionVariable.Direction; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -54,12 +53,12 @@ public ValueNode maxTripCountNode(boolean assumePositive) { StructuredGraph graph = iv.valueNode().graph(); Kind kind = iv.valueNode().kind(); - IntegerArithmeticNode range = IntegerArithmeticNode.sub(end, iv.initNode()); + IntegerArithmeticNode range = IntegerArithmeticNode.sub(graph, end, iv.initNode()); if (oneOff) { if (iv.direction() == Direction.Up) { - range = IntegerArithmeticNode.add(range, ConstantNode.forIntegerKind(kind, 1, graph)); + range = IntegerArithmeticNode.add(graph, range, ConstantNode.forIntegerKind(kind, 1, graph)); } else { - range = IntegerArithmeticNode.sub(range, ConstantNode.forIntegerKind(kind, 1, graph)); + range = IntegerArithmeticNode.sub(graph, range, ConstantNode.forIntegerKind(kind, 1, graph)); } } IntegerDivNode div = graph.add(new IntegerDivNode(kind, range, iv.strideNode())); @@ -139,20 +138,20 @@ return overflowGuard; } Kind kind = iv.valueNode().kind(); - Graph graph = iv.valueNode().graph(); + StructuredGraph graph = iv.valueNode().graph(); CompareNode cond; // we use a negated guard with a < condition to achieve a >= ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph); if (iv.direction() == Direction.Up) { - IntegerArithmeticNode v1 = sub(ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(iv.strideNode(), one)); + IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(graph, iv.strideNode(), one)); if (oneOff) { - v1 = sub(v1, one); + v1 = sub(graph, v1, one); } cond = graph.unique(new IntegerLessThanNode(v1, end)); } else { assert iv.direction() == Direction.Down; - IntegerArithmeticNode v1 = add(ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(one, iv.strideNode())); + IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(graph, one, iv.strideNode())); if (oneOff) { - v1 = add(v1, one); + v1 = add(graph, v1, one); } cond = graph.unique(new IntegerLessThanNode(end, v1)); } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Sun Nov 03 15:27:52 2013 +0100 @@ -41,6 +41,11 @@ } @Override + public StructuredGraph graph() { + return base.graph(); + } + + @Override public Direction direction() { return base.direction(); } @@ -81,7 +86,7 @@ @Override public ValueNode strideNode() { if (value instanceof IntegerSubNode && base.valueNode() == value.y()) { - return value.graph().unique(new NegateNode(base.strideNode())); + return graph().unique(new NegateNode(base.strideNode())); } return base.strideNode(); } @@ -123,14 +128,14 @@ private ValueNode op(ValueNode b, ValueNode o) { if (value instanceof IntegerAddNode) { - return IntegerArithmeticNode.add(b, o); + return IntegerArithmeticNode.add(graph(), b, o); } if (value instanceof IntegerSubNode) { if (base.valueNode() == value.x()) { - return IntegerArithmeticNode.sub(b, o); + return IntegerArithmeticNode.sub(graph(), b, o); } else { assert base.valueNode() == value.y(); - return IntegerArithmeticNode.sub(o, b); + return IntegerArithmeticNode.sub(graph(), o, b); } } throw GraalInternalError.shouldNotReachHere(); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java Sun Nov 03 15:27:52 2013 +0100 @@ -48,6 +48,11 @@ } @Override + public StructuredGraph graph() { + return base.graph(); + } + + @Override public Direction direction() { Stamp stamp = scale.stamp(); if (stamp instanceof IntegerStamp) { @@ -68,12 +73,12 @@ @Override public ValueNode initNode() { - return IntegerArithmeticNode.mul(base.initNode(), scale); + return IntegerArithmeticNode.mul(graph(), base.initNode(), scale); } @Override public ValueNode strideNode() { - return IntegerArithmeticNode.mul(base.strideNode(), scale); + return IntegerArithmeticNode.mul(graph(), base.strideNode(), scale); } @Override @@ -98,12 +103,12 @@ @Override public ValueNode extremumNode(boolean assumePositiveTripCount, Kind kind) { - return IntegerArithmeticNode.mul(base.extremumNode(assumePositiveTripCount, kind), ConvertNode.convert(kind, scale)); + return IntegerArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, kind), ConvertNode.convert(kind, scale)); } @Override public ValueNode exitValueNode() { - return IntegerArithmeticNode.mul(base.exitValueNode(), scale); + return IntegerArithmeticNode.mul(graph(), base.exitValueNode(), scale); } @Override diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java Sun Nov 03 15:27:52 2013 +0100 @@ -46,6 +46,8 @@ } } + public abstract StructuredGraph graph(); + protected final LoopEx loop; public InductionVariable(LoopEx loop) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Sun Nov 03 15:27:52 2013 +0100 @@ -77,7 +77,7 @@ } public boolean isOutsideLoop(Node n) { - return !whole().contains(n); + return n.isExternal() || !whole().contains(n); } public LoopBeginNode loopBegin() { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Sun Nov 03 15:27:52 2013 +0100 @@ -72,7 +72,10 @@ @SuppressWarnings("unchecked") public New getDuplicatedNode(Old n) { assert isDuplicate(); - return (New) duplicationMap.get(n); + if (!n.isExternal()) { + return (New) duplicationMap.get(n); + } + return n; } protected void putDuplicatedNode(Old oldNode, New newNode) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -25,23 +25,45 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** - * The {@code ConstantNode} represents a constant such as an integer value, long, float, object - * reference, address, etc. + * The {@code ConstantNode} represents a {@link Constant constant}. */ @NodeInfo(shortName = "Const", nameTemplate = "Const({p#rawvalue})") -public class ConstantNode extends FloatingNode implements LIRLowerable { +public final class ConstantNode extends FloatingNode implements LIRLowerable { - public final Constant value; + private static final DebugMetric ConstantNodes = Debug.metric("ConstantNodes"); + + private final Constant value; protected ConstantNode(Constant value) { super(StampFactory.forConstant(value)); this.value = value; + ConstantNodes.increment(); + } + + /** + * Constructs a new ConstantNode representing the specified constant. + * + * @param value the constant + */ + protected ConstantNode(Constant value, MetaAccessProvider metaAccess) { + super(StampFactory.forConstant(value, metaAccess)); + this.value = value; + ConstantNodes.increment(); + } + + /** + * @return the constant value represented by this node + */ + public Constant getValue() { + return value; } /** @@ -55,24 +77,24 @@ return ConstantNodeRecordsUsages; } - /** - * Constructs a new ConstantNode representing the specified constant. - * - * @param value the constant - */ - protected ConstantNode(Constant value, MetaAccessProvider metaAccess) { - super(StampFactory.forConstant(value, metaAccess)); - this.value = value; + @Override + public boolean isAlive() { + return true; + } + + @Override + public boolean isExternal() { + return true; } /** * Computes the usages of this node by iterating over all the nodes in the graph, searching for * those that have this node as an input. */ - public List gatherUsages() { + public List gatherUsages(StructuredGraph graph) { assert !ConstantNodeRecordsUsages; List usages = new ArrayList<>(); - for (Node node : graph().getNodes()) { + for (Node node : graph.getNodes()) { for (Node input : node.inputs()) { if (input == this) { usages.add(node); @@ -82,20 +104,45 @@ return usages; } - public void replace(Node replacement) { + /** + * Gathers all the {@link ConstantNode}s that are inputs to the {@linkplain Graph#getNodes() + * live nodes} in a given graph. This is an expensive operation that should only be used in + * test/verification/AOT code. + */ + public static NodeIterable getConstantNodes(StructuredGraph graph) { + Map result = new HashMap<>(); + for (Node node : graph.getNodes()) { + for (Node input : node.inputs()) { + if (input instanceof ConstantNode) { + result.put((ConstantNode) input, (ConstantNode) input); + } + } + } + return new ConstantNodeList(result.keySet()); + } + + /** + * Replaces this node at its usages with another node. If {@value #ConstantNodeRecordsUsages} is + * false, this is an expensive operation that should only be used in test/verification/AOT code. + */ + public void replace(StructuredGraph graph, Node replacement) { if (!recordsUsages()) { - List usages = gatherUsages(); + List usages = gatherUsages(graph); for (Node usage : usages) { usage.replaceFirstInput(this, replacement); } - graph().removeFloating(this); + if (!isExternal()) { + graph.removeFloating(this); + } } else { + assert graph == graph(); graph().replaceFloating(this, replacement); } } @Override public void generate(LIRGeneratorTool gen) { + assert ConstantNodeRecordsUsages : "LIR generator should generate constants per-usage"; if (gen.canInlineConstant(value) || onlyUsedInVirtualState()) { gen.setResult(this, value); } else { @@ -118,9 +165,9 @@ if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) { return forInt(constant.asInt(), graph); } else if (constant.getKind() == Kind.Object) { - return graph.unique(new ConstantNode(constant, metaAccess)); + return unique(graph, new ConstantNode(constant, metaAccess)); } else { - return graph.unique(new ConstantNode(constant)); + return unique(graph, new ConstantNode(constant)); } } @@ -136,100 +183,95 @@ * Returns a node for a double constant. * * @param d the double value for which to create the instruction - * @param graph * @return a node for a double constant */ public static ConstantNode forDouble(double d, Graph graph) { - return graph.unique(new ConstantNode(Constant.forDouble(d))); + return unique(graph, new ConstantNode(Constant.forDouble(d))); } /** * Returns a node for a float constant. * * @param f the float value for which to create the instruction - * @param graph * @return a node for a float constant */ public static ConstantNode forFloat(float f, Graph graph) { - return graph.unique(new ConstantNode(Constant.forFloat(f))); + return unique(graph, new ConstantNode(Constant.forFloat(f))); } /** * Returns a node for an long constant. * * @param i the long value for which to create the instruction - * @param graph * @return a node for an long constant */ public static ConstantNode forLong(long i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forLong(i))); + return unique(graph, new ConstantNode(Constant.forLong(i))); } /** * Returns a node for an integer constant. * * @param i the integer value for which to create the instruction - * @param graph * @return a node for an integer constant */ public static ConstantNode forInt(int i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forInt(i))); + return unique(graph, new ConstantNode(Constant.forInt(i))); } /** * Returns a node for a boolean constant. * * @param i the boolean value for which to create the instruction - * @param graph * @return a node representing the boolean */ public static ConstantNode forBoolean(boolean i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forInt(i ? 1 : 0))); + return unique(graph, new ConstantNode(Constant.forInt(i ? 1 : 0))); } /** * Returns a node for a byte constant. * * @param i the byte value for which to create the instruction - * @param graph * @return a node representing the byte */ public static ConstantNode forByte(byte i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forInt(i))); + return unique(graph, new ConstantNode(Constant.forInt(i))); } /** * Returns a node for a char constant. * * @param i the char value for which to create the instruction - * @param graph * @return a node representing the char */ public static ConstantNode forChar(char i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forInt(i))); + return unique(graph, new ConstantNode(Constant.forInt(i))); } /** * Returns a node for a short constant. * * @param i the short value for which to create the instruction - * @param graph * @return a node representing the short */ public static ConstantNode forShort(short i, Graph graph) { - return graph.unique(new ConstantNode(Constant.forInt(i))); + return unique(graph, new ConstantNode(Constant.forInt(i))); } /** * Returns a node for an object constant. * * @param o the object value for which to create the instruction - * @param graph * @return a node representing the object */ public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, Graph graph) { assert !(o instanceof Constant) : "wrapping a Constant into a Constant"; - return graph.unique(new ConstantNode(Constant.forObject(o), metaAccess)); + return unique(graph, new ConstantNode(Constant.forObject(o), metaAccess)); + } + + private static ConstantNode unique(Graph graph, ConstantNode node) { + return graph.uniqueWithoutAdd(node); } public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) { @@ -292,4 +334,15 @@ return super.toString(verbosity); } } + + static class ConstantNodeList extends NodeList { + + public ConstantNodeList(Collection nodes) { + super(nodes.toArray(new ConstantNode[nodes.size()])); + } + + @Override + protected void update(ConstantNode oldNode, ConstantNode newNode) { + } + } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -110,7 +110,7 @@ * @return {@code true} if this value represents the null constant */ public final boolean isNullConstant() { - return this instanceof ConstantNode && ((ConstantNode) this).value.isNull(); + return this instanceof ConstantNode && ((ConstantNode) this).getValue().isNull(); } /** @@ -121,7 +121,7 @@ */ public final Constant asConstant() { if (this instanceof ConstantNode) { - return ((ConstantNode) this).value; + return ((ConstantNode) this).getValue(); } return null; } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -83,7 +83,7 @@ } } - public static BinaryNode add(ValueNode x, ValueNode y) { + public static BinaryNode add(StructuredGraph graph, ValueNode x, ValueNode y) { assert x.kind() == y.kind(); switch (x.kind()) { case Byte: @@ -91,7 +91,7 @@ case Short: case Int: case Long: - return IntegerArithmeticNode.add(x, y); + return IntegerArithmeticNode.add(graph, x, y); case Float: case Double: return x.graph().unique(new FloatAddNode(x.kind(), x, y, false)); @@ -100,7 +100,7 @@ } } - public static BinaryNode sub(ValueNode x, ValueNode y) { + public static BinaryNode sub(StructuredGraph graph, ValueNode x, ValueNode y) { assert x.kind() == y.kind(); switch (x.kind()) { case Byte: @@ -108,7 +108,7 @@ case Short: case Int: case Long: - return IntegerArithmeticNode.sub(x, y); + return IntegerArithmeticNode.sub(graph, x, y); case Float: case Double: return x.graph().unique(new FloatSubNode(x.kind(), x, y, false)); @@ -117,7 +117,7 @@ } } - public static BinaryNode mul(ValueNode x, ValueNode y) { + public static BinaryNode mul(StructuredGraph graph, ValueNode x, ValueNode y) { assert x.kind() == y.kind(); switch (x.kind()) { case Byte: @@ -125,7 +125,7 @@ case Short: case Int: case Long: - return IntegerArithmeticNode.mul(x, y); + return IntegerArithmeticNode.mul(graph, x, y); case Float: case Double: return x.graph().unique(new FloatMulNode(x.kind(), x, y, false)); @@ -168,9 +168,10 @@ //@formatter:on /** * Tries to re-associate values which satisfy the criterion. For example with a constantness - * criterion : (a + 2) + 1 => a + (1 + 2)
- * This method accepts only reassociable operations (see - * {@linkplain #canTryReassociate(BinaryNode)}) such as +, -, *, &, | and ^ + * criterion: {@code (a + 2) + 1 => a + (1 + 2)} + *

+ * This method accepts only {@linkplain #canTryReassociate(BinaryNode) reassociable} operations + * such as +, -, *, &, | and ^ */ public static BinaryNode reassociate(BinaryNode node, NodePredicate criterion) { assert canTryReassociate(node); @@ -217,28 +218,29 @@ ValueNode a = match2.getOtherValue(other); if (node instanceof IntegerAddNode || node instanceof IntegerSubNode) { BinaryNode associated; + StructuredGraph graph = node.graph(); if (invertM1) { - associated = IntegerArithmeticNode.sub(m2, m1); + associated = IntegerArithmeticNode.sub(graph, m2, m1); } else if (invertM2) { - associated = IntegerArithmeticNode.sub(m1, m2); + associated = IntegerArithmeticNode.sub(graph, m1, m2); } else { - associated = IntegerArithmeticNode.add(m1, m2); + associated = IntegerArithmeticNode.add(graph, m1, m2); } if (invertA) { - return IntegerArithmeticNode.sub(associated, a); + return IntegerArithmeticNode.sub(graph, associated, a); } if (aSub) { - return IntegerArithmeticNode.sub(a, associated); + return IntegerArithmeticNode.sub(graph, a, associated); } - return IntegerArithmeticNode.add(a, associated); + return IntegerArithmeticNode.add(graph, a, associated); } else if (node instanceof IntegerMulNode) { - return IntegerArithmeticNode.mul(a, IntegerAddNode.mul(m1, m2)); + return IntegerArithmeticNode.mul(node.graph(), a, IntegerAddNode.mul(node.graph(), m1, m2)); } else if (node instanceof AndNode) { - return BitLogicNode.and(a, BitLogicNode.and(m1, m2)); + return BitLogicNode.and(node.graph(), a, BitLogicNode.and(node.graph(), m1, m2)); } else if (node instanceof OrNode) { - return BitLogicNode.or(a, BitLogicNode.or(m1, m2)); + return BitLogicNode.or(node.graph(), a, BitLogicNode.or(node.graph(), m1, m2)); } else if (node instanceof XorNode) { - return BitLogicNode.xor(a, BitLogicNode.xor(m1, m2)); + return BitLogicNode.xor(node.graph(), a, BitLogicNode.xor(node.graph(), m1, m2)); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -43,9 +42,8 @@ assert kind == Kind.Int || kind == Kind.Long; } - public static BitLogicNode and(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static BitLogicNode and(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new AndNode(Kind.Int, v1, v2)); @@ -56,9 +54,8 @@ } } - public static BitLogicNode or(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static BitLogicNode or(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new OrNode(Kind.Int, v1, v2)); @@ -69,9 +66,8 @@ } } - public static BitLogicNode xor(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static BitLogicNode xor(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new XorNode(Kind.Int, v1, v2)); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -144,7 +144,7 @@ return this; } - public static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) { + public static CompareNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) { assert x.kind() == y.kind(); assert condition.isCanonical() : "condition is not canonical: " + condition; assert x.kind() != Kind.Double && x.kind() != Kind.Float; @@ -166,6 +166,6 @@ comparison = new IntegerBelowThanNode(x, y); } - return x.graph().unique(comparison); + return graph.unique(comparison); } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -113,8 +113,8 @@ generator.emitConditional(this); } - private ConditionalNode(Condition condition, ValueNode x, ValueNode y) { - this(createCompareNode(condition, x, y)); + private ConditionalNode(@InjectedNodeParameter StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) { + this(createCompareNode(graph, condition, x, y)); } private ConditionalNode(ValueNode type, ValueNode object) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -80,17 +80,17 @@ } if (c < 0) { if (kind() == Kind.Int) { - return IntegerArithmeticNode.sub(x(), ConstantNode.forInt((int) -c, graph())); + return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forInt((int) -c, graph())); } else { assert kind() == Kind.Long; - return IntegerArithmeticNode.sub(x(), ConstantNode.forLong(-c, graph())); + return IntegerArithmeticNode.sub(graph(), x(), ConstantNode.forLong(-c, graph())); } } } if (x() instanceof NegateNode) { - return IntegerArithmeticNode.sub(y(), ((NegateNode) x()).x()); + return IntegerArithmeticNode.sub(graph(), y(), ((NegateNode) x()).x()); } else if (y() instanceof NegateNode) { - return IntegerArithmeticNode.sub(x(), ((NegateNode) y()).x()); + return IntegerArithmeticNode.sub(graph(), x(), ((NegateNode) y()).x()); } return this; } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,9 +33,8 @@ assert kind == Kind.Int || kind == Kind.Long; } - public static IntegerAddNode add(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static IntegerAddNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new IntegerAddNode(Kind.Int, v1, v2)); @@ -47,9 +45,8 @@ } } - public static IntegerMulNode mul(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static IntegerMulNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new IntegerMulNode(Kind.Int, v1, v2)); @@ -60,9 +57,8 @@ } } - public static IntegerSubNode sub(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); + public static IntegerSubNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind(); switch (v1.kind()) { case Int: return graph.unique(new IntegerSubNode(Kind.Int, v1, v2)); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -60,7 +60,7 @@ } else { if (x().isConstant() && x().asConstant().asLong() == 0) { // 0 |<| y is the same as 0 != y - return graph().unique(new LogicNegationNode(CompareNode.createCompareNode(Condition.EQ, x(), y()))); + return graph().unique(new LogicNegationNode(CompareNode.createCompareNode(graph(), Condition.EQ, x(), y()))); } if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -79,7 +79,7 @@ } RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph()))); UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(kind(), sign, ConstantNode.forInt(bits - log2, graph()))); - dividend = IntegerArithmeticNode.add(dividend, round); + dividend = IntegerArithmeticNode.add(graph(), dividend, round); } RightShiftNode shift = graph().unique(new RightShiftNode(kind(), dividend, ConstantNode.forInt(log2, graph()))); if (c < 0) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -99,10 +99,10 @@ } if (c < 0) { if (kind() == Kind.Int) { - return IntegerArithmeticNode.add(x(), ConstantNode.forInt((int) -c, graph())); + return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forInt((int) -c, graph())); } else { assert kind() == Kind.Long; - return IntegerArithmeticNode.add(x(), ConstantNode.forLong(-c, graph())); + return IntegerArithmeticNode.add(graph(), x(), ConstantNode.forLong(-c, graph())); } } } else if (x().isConstant()) { @@ -113,7 +113,7 @@ return BinaryNode.reassociate(this, ValueNode.isConstantPredicate()); } if (y() instanceof NegateNode) { - return IntegerArithmeticNode.add(x(), ((NegateNode) y()).x()); + return IntegerArithmeticNode.add(graph(), x(), ((NegateNode) y()).x()); } return this; } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -82,7 +82,7 @@ } if (x() instanceof IntegerSubNode) { IntegerSubNode sub = (IntegerSubNode) x; - return IntegerArithmeticNode.sub(sub.y(), sub.x()); + return IntegerArithmeticNode.sub(graph(), sub.y(), sub.x()); } return this; } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -82,7 +82,7 @@ IndexedLocationNode yIdx = (IndexedLocationNode) y; if (xIdx.getIndexScaling() == yIdx.getIndexScaling()) { long displacement = xIdx.getDisplacement() + yIdx.getDisplacement(); - ValueNode index = IntegerArithmeticNode.add(xIdx.getIndex(), yIdx.getIndex()); + ValueNode index = IntegerArithmeticNode.add(graph(), xIdx.getIndex(), yIdx.getIndex()); return IndexedLocationNode.create(getLocationIdentity(), getValueKind(), displacement, index, graph(), xIdx.getIndexScaling()); } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -47,7 +47,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - ValueNode length = readArrayLength(array(), tool.getConstantReflection()); + ValueNode length = readArrayLength(graph(), array(), tool.getConstantReflection()); if (length != null) { return length; } @@ -57,10 +57,12 @@ /** * Gets the length of an array if possible. * + * @param graph TODO * @param array an array + * * @return a node representing the length of {@code array} or null if it is not available */ - public static ValueNode readArrayLength(ValueNode array, ConstantReflectionProvider constantReflection) { + public static ValueNode readArrayLength(StructuredGraph graph, ValueNode array, ConstantReflectionProvider constantReflection) { if (array instanceof ArrayLengthProvider) { ValueNode length = ((ArrayLengthProvider) array).length(); if (length != null) { @@ -72,7 +74,7 @@ if (constantValue != null && constantValue.isNonNull()) { Integer constantLength = constantReflection.lookupArrayLength(constantValue); if (constantLength != null) { - return ConstantNode.forInt(constantLength, array.graph()); + return ConstantNode.forInt(constantLength, graph); } } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Sun Nov 03 15:27:52 2013 +0100 @@ -160,6 +160,12 @@ return forFloat(kind, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble())); case Illegal: return illegal(Kind.Illegal); + case Object: + if (value.isNull()) { + return alwaysNull(); + } else { + return objectNonNull(); + } default: throw new GraalInternalError("unexpected kind: %s", kind); } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Sun Nov 03 15:27:52 2013 +0100 @@ -123,7 +123,7 @@ } public static void killWithUnusedFloatingInputs(Node node) { - if (node.recordsUsages()) { + if (node.recordsUsages() && !node.isExternal()) { List floatingInputs = node.inputs().filter(isFloatingNode()).snapshot(); node.safeDelete(); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -510,7 +510,7 @@ PiNode piNode; if (isNull) { ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph); - piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccess), replacementAnchor.asNode())); + piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.getValue(), metaAccess), replacementAnchor.asNode())); } else { piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode())); } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -112,13 +112,17 @@ for (Node node : graph.getNodes()) { if (flood.isMarked(node)) { for (Node input : node.inputs()) { - flood.add(input); + if (!input.isExternal()) { + flood.add(input); + } } } } for (Node current : flood) { for (Node input : current.inputs()) { - flood.add(input); + if (!input.isExternal()) { + flood.add(input); + } } } } diff -r 1c0261ebeeed -r 2c4aa758ee18 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 Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Sun Nov 03 15:27:52 2013 +0100 @@ -39,6 +39,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; +import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -487,7 +488,7 @@ ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), metaAccess, graph); LoadHubNode receiverHub = graph.unique(new LoadHubNode(nonNullReceiver, typeHub.kind(), null)); - CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub); + CompareNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub); FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile)); assert invoke.predecessor() != null; @@ -803,7 +804,7 @@ FixedNode lastSucc = successors[concretes.size()]; for (int i = concretes.size() - 1; i >= 0; --i) { LoadMethodNode method = graph.add(new LoadMethodNode(concretes.get(i), hub, constantMethods[i].kind())); - CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, method, constantMethods[i]); + CompareNode methodCheck = CompareNode.createCompareNode(graph, Condition.EQ, method, constantMethods[i]); IfNode ifNode = graph.add(new IfNode(methodCheck, successors[i], lastSucc, probability[i])); method.setNext(ifNode); lastSucc = method; @@ -1433,7 +1434,12 @@ if (returnNode.result() instanceof LocalNode) { returnValue = localReplacement.replacement(returnNode.result()); } else if (returnNode.result() != null) { - returnValue = duplicates.get(returnNode.result()); + returnValue = returnNode.result(); + if (!returnValue.isExternal()) { + returnValue = duplicates.get(returnValue); + } else if (returnValue instanceof ValueNumberable) { + returnValue = graph.uniqueWithoutAdd(returnValue); + } } invoke.asNode().replaceAtUsages(returnValue); Node returnDuplicate = duplicates.get(returnNode); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -98,7 +98,7 @@ // Short cut creation of null check guard if the object is known to be non-null. return null; } - StructuredGraph graph = object.graph(); + StructuredGraph graph = guardedNode.asNode().graph(); if (graph.getGuardsStage().ordinal() > GuardsStage.FLOATING_GUARDS.ordinal()) { NullCheckNode nullCheck = graph.add(new NullCheckNode(object)); graph.addBeforeFixed((FixedNode) guardedNode, nullCheck); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -364,7 +364,7 @@ // stop iterating: fixed nodes within the given set are traversal roots // anyway, and all other // fixed nodes are known to be outside. - } else if (!aboveBound.isMarked(node)) { + } else if (!node.isExternal() && !aboveBound.isMarked(node)) { worklist.add(node); aboveBound.mark(node); } @@ -377,7 +377,9 @@ while (!worklist.isEmpty()) { Node current = worklist.remove(); for (Node input : current.inputs()) { - aboveClosure.apply(current, input); + if (!input.isExternal()) { + aboveClosure.apply(current, input); + } } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -672,6 +672,10 @@ * Determines the earliest block in which the given node can be scheduled. */ private Block earliestBlock(Node node) { + if (node.isExternal()) { + return cfg.getStartBlock(); + } + Block earliest = cfg.getNodeToBlock().get(node); if (earliest != null) { return earliest; @@ -987,7 +991,7 @@ for (Node input : state.inputs()) { if (input instanceof VirtualState) { addUnscheduledToLatestSorting(b, (VirtualState) input, sortedInstructions, visited, reads, beforeLastLocation); - } else { + } else if (!input.isExternal()) { addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); } } @@ -1004,8 +1008,9 @@ if (input instanceof FrameState) { assert state == null; state = (FrameState) input; - } else { + } else if (!input.isExternal()) { addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); + } } List inputs = phantomInputs.get(i); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Sun Nov 03 15:27:52 2013 +0100 @@ -72,7 +72,7 @@ for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) { if (!isEqualsMethod(graph)) { // bail out if we compare an object of type klass with == or != (except null checks) - assert !(checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) : "Verifcation of " + klass.getName() + + assert !(checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) : "Verification of " + klass.getName() + " usage failed: Comparing " + cn.x() + " and " + cn.y() + " in " + graph.method() + " must use .equals() for object equality, not '==' or '!='"; } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Sun Nov 03 15:27:52 2013 +0100 @@ -137,8 +137,9 @@ ControlFlowGraph cfg = schedule == null ? null : schedule.getCFG(); BlockMap> blockToNodes = schedule == null ? null : schedule.getBlockToNodesMap(); Block[] blocks = cfg == null ? null : cfg.getBlocks(); - writeNodes(graph); - writeBlocks(blocks, blockToNodes); + Map externalNodes = new HashMap<>(); + writeNodes(graph, externalNodes); + writeBlocks(blocks, blockToNodes, externalNodes); } private void flush() throws IOException { @@ -388,7 +389,17 @@ } @SuppressWarnings("deprecation") - private void writeNodes(Graph graph) throws IOException { + private static int getNodeId(Node node, Map externalNodes) { + if (!node.isExternal()) { + return node.getId(); + } else { + Integer id = externalNodes.get(node); + assert id != null; + return id; + } + } + + private void writeNodes(Graph graph, Map externalNodes) throws IOException { NodesToDoubles probabilities = null; if (PrintGraphProbabilities.getValue()) { try { @@ -397,14 +408,26 @@ } } Map props = new HashMap<>(); - writeInt(graph.getNodeCount()); + int firstExternalNodeId = graph.getNodeCount() + graph.getDeletedNodeCount(); + for (Node node : graph.getNodes()) { + for (Node input : node.inputs()) { + if (input.isExternal()) { + if (!externalNodes.containsKey(input)) { + externalNodes.put(input, externalNodes.size() + firstExternalNodeId); + } + } + } + } + + writeInt(graph.getNodeCount() + externalNodes.size()); + for (Node node : graph.getNodes()) { NodeClass nodeClass = node.getNodeClass(); node.getDebugProperties(props); if (probabilities != null && node instanceof FixedNode && probabilities.contains((FixedNode) node)) { props.put("probability", probabilities.get((FixedNode) node)); } - writeInt(node.getId()); + writeInt(getNodeId(node, externalNodes)); writePoolObject(nodeClass); writeByte(node.predecessor() == null ? 0 : 1); // properties @@ -415,20 +438,35 @@ writePropertyObject(entry.getValue()); } // inputs - writeEdges(node, nodeClass.getFirstLevelInputPositions()); + writeEdges(node, nodeClass.getFirstLevelInputPositions(), externalNodes); // successors - writeEdges(node, nodeClass.getFirstLevelSuccessorPositions()); + writeEdges(node, nodeClass.getFirstLevelSuccessorPositions(), externalNodes); props.clear(); } + for (Node node : externalNodes.keySet()) { + NodeClass nodeClass = node.getNodeClass(); + node.getDebugProperties(props); + writeInt(getNodeId(node, externalNodes)); + writePoolObject(nodeClass); + writeByte(0); + // properties + writeShort((char) props.size()); + for (Entry entry : props.entrySet()) { + String key = entry.getKey().toString(); + writePoolObject(key); + writePropertyObject(entry.getValue()); + } + props.clear(); + } } - private void writeEdges(Node node, Collection positions) throws IOException { + private void writeEdges(Node node, Collection positions, Map externalNodes) throws IOException { NodeClass nodeClass = node.getNodeClass(); for (Position pos : positions) { if (pos.subIndex == NodeClass.NOT_ITERABLE) { Node edge = nodeClass.get(node, pos); - writeNodeRef(edge); + writeNodeRef(edge, externalNodes); } else { NodeList list = nodeClass.getNodeList(node, pos); if (list == null) { @@ -438,24 +476,22 @@ assert listSize == ((char) listSize); writeShort((char) listSize); for (Node edge : list) { - writeNodeRef(edge); + writeNodeRef(edge, externalNodes); } } } } } - @SuppressWarnings("deprecation") - private void writeNodeRef(Node edge) throws IOException { + private void writeNodeRef(Node edge, Map externalNodes) throws IOException { if (edge != null) { - writeInt(edge.getId()); + writeInt(getNodeId(edge, externalNodes)); } else { writeInt(-1); } } - @SuppressWarnings("deprecation") - private void writeBlocks(Block[] blocks, BlockMap> blockToNodes) throws IOException { + private void writeBlocks(Block[] blocks, BlockMap> blockToNodes, Map externalNodes) throws IOException { if (blocks != null) { writeInt(blocks.length); for (Block block : blocks) { @@ -463,7 +499,7 @@ writeInt(block.getId()); writeInt(nodes.size()); for (Node node : nodes) { - writeInt(node.getId()); + writeInt(getNodeId(node, externalNodes)); } writeInt(block.getSuccessors().size()); for (Block sux : block.getSuccessors()) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Sun Nov 03 15:27:52 2013 +0100 @@ -141,7 +141,7 @@ } if (condition == null || condition.y() != testValue) { // Re-use previously generated condition if the trueValue for the test is the same - condition = createCompareNode(Condition.EQ, result, testValue); + condition = createCompareNode(result.graph(), Condition.EQ, result, testValue); } return condition; } @@ -152,13 +152,13 @@ * @param t the true value for the materialization * @param f the false value for the materialization */ - ValueNode asMaterialization(ValueNode t, ValueNode f) { + ValueNode asMaterialization(StructuredGraph graph, ValueNode t, ValueNode f) { assert isInitialized(); if (t == this.trueValue && f == this.falseValue) { // Can simply use the phi result if the same materialized values are expected. return result; } else { - return t.graph().unique(new ConditionalNode(asCondition(trueValue), t, f)); + return graph.unique(new ConditionalNode(asCondition(trueValue), t, f)); } } } @@ -230,7 +230,7 @@ @Override public void replaceUsingInstantiation() { - ValueNode newValue = instantiation.asMaterialization(trueValue, falseValue); + ValueNode newValue = instantiation.asMaterialization(usage.graph(), trueValue, falseValue); usage.replaceAtUsages(newValue); usage.clearInputs(); assert usage.usages().isEmpty(); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -72,6 +72,7 @@ ResolvedJavaMethod target = methodCallTargetNode.targetMethod(); NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class); ResolvedJavaType declaringClass = target.getDeclaringClass(); + StructuredGraph graph = methodCallTargetNode.graph(); if (intrinsic != null) { assert target.getAnnotation(Fold.class) == null; assert Modifier.isStatic(target.getModifiers()) : "node intrinsic must be static: " + target; @@ -86,10 +87,10 @@ // Create the new node instance. ResolvedJavaType c = getNodeClass(target, intrinsic); - Node newInstance = createNodeInstance(c, parameterTypes, methodCallTargetNode.invoke().asNode().stamp(), intrinsic.setStampFromReturnType(), nodeConstructorArguments); + Node newInstance = createNodeInstance(graph, c, parameterTypes, methodCallTargetNode.invoke().asNode().stamp(), intrinsic.setStampFromReturnType(), nodeConstructorArguments); // Replace the invoke with the new node. - newInstance = methodCallTargetNode.graph().addOrUnique(newInstance); + newInstance = graph.addOrUnique(newInstance); methodCallTargetNode.invoke().intrinsify(newInstance); // Clean up checkcast instructions inserted by javac if the return type is generic. @@ -194,12 +195,13 @@ return result; } - private Node createNodeInstance(ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType, Constant[] nodeConstructorArguments) { + private Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType, + Constant[] nodeConstructorArguments) { ResolvedJavaMethod constructor = null; Constant[] arguments = null; for (ResolvedJavaMethod c : nodeClass.getDeclaredConstructors()) { - Constant[] match = match(c, parameterTypes, nodeConstructorArguments); + Constant[] match = match(graph, c, parameterTypes, nodeConstructorArguments); if (match != null) { if (constructor == null) { @@ -246,7 +248,7 @@ return false; } - private Constant[] match(ResolvedJavaMethod c, ResolvedJavaType[] parameterTypes, Constant[] nodeConstructorArguments) { + private Constant[] match(StructuredGraph graph, ResolvedJavaMethod c, ResolvedJavaType[] parameterTypes, Constant[] nodeConstructorArguments) { Constant[] arguments = null; Constant[] injected = null; @@ -257,6 +259,8 @@ injected = injected == null ? new Constant[1] : Arrays.copyOf(injected, injected.length + 1); if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) { injected[injected.length - 1] = Constant.forObject(metaAccess); + } else if (signature[i].equals(metaAccess.lookupJavaType(StructuredGraph.class))) { + injected[injected.length - 1] = Constant.forObject(graph); } else if (signature[i].equals(metaAccess.lookupJavaType(ForeignCallsProvider.class))) { injected[injected.length - 1] = Constant.forObject(providers.getForeignCalls()); } else { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -61,10 +61,9 @@ } else { locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); } - Node result = graph().add( - new UnsafeLoadNode(objectArgument, offsetArgument, this.getTargetMethod().getSignature().getReturnKind(), locationIdentity, CompareNode.createCompareNode(Condition.EQ, - conditionArgument, ConstantNode.forBoolean(true, graph())))); - + CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())); + Kind returnKind = this.getTargetMethod().getSignature().getReturnKind(); + Node result = graph().add(new UnsafeLoadNode(objectArgument, offsetArgument, returnKind, locationIdentity, compare)); return result; } return this; diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Sun Nov 03 15:27:52 2013 +0100 @@ -58,7 +58,7 @@ return objectArgument; } ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c); - ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); + ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, StampFactory.declaredNonNull(lookupJavaType), valueAnchorNode)); this.replaceAtUsages(piCast); return valueAnchorNode; diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Sun Nov 03 15:27:52 2013 +0100 @@ -231,7 +231,7 @@ public ValueNode getScalarAlias(ValueNode node) { assert !(node instanceof VirtualObjectNode); - if (node == null || !node.isAlive() || aliases.isNew(node)) { + if (node == null || !node.isAlive() || node.isExternal() || aliases.isNew(node)) { return node; } ValueNode result = aliases.get(node); diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Sun Nov 03 15:27:52 2013 +0100 @@ -616,7 +616,7 @@ } public ObjectState getObjectState(PartialEscapeBlockState state, ValueNode value) { - if (value == null) { + if (value == null || value.isExternal()) { return null; } if (value.isAlive() && !aliases.isNew(value)) { diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Sun Nov 03 15:27:52 2013 +0100 @@ -69,18 +69,22 @@ for (Node node : graph.getNodes()) { if (flood.isMarked(node)) { for (Node input : node.inputs()) { - flood.add(input); - if (!path.containsKey(input)) { - path.put(input, node); + if (!input.isExternal()) { + flood.add(input); + if (!path.containsKey(input)) { + path.put(input, node); + } } } } } for (Node current : flood) { for (Node input : current.inputs()) { - flood.add(input); - if (!path.containsKey(input)) { - path.put(input, current); + if (!input.isExternal()) { + flood.add(input); + if (!path.containsKey(input)) { + path.put(input, current); + } } } } diff -r 1c0261ebeeed -r 2c4aa758ee18 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Nov 01 19:35:33 2013 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Sun Nov 03 15:27:52 2013 +0100 @@ -114,8 +114,8 @@ if (isWord(node)) { if (node.isConstant()) { ConstantNode oldConstant = (ConstantNode) node; - assert oldConstant.value.getKind() == Kind.Object; - WordBase value = (WordBase) oldConstant.value.asObject(); + assert oldConstant.getValue().getKind() == Kind.Object; + WordBase value = (WordBase) oldConstant.getValue().asObject(); ConstantNode newConstant = ConstantNode.forIntegerKind(wordKind, value.rawValue(), node.graph()); graph.replaceFloating(oldConstant, newConstant);