# HG changeset patch # User Josef Eisl # Date 1396281085 -7200 # Node ID f729be5acf8e23e586a1246f3f95a6350e5859e7 # Parent c25b121d36ecd2b9c2296db0cb81b293b237ecc2# Parent 00b66fc77764f43c6810024416d8be333c7032cf Merge. diff -r c25b121d36ec -r f729be5acf8e graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Mon Mar 31 17:51:25 2014 +0200 @@ -338,6 +338,6 @@ new DeadCodeEliminationPhase().apply(referenceGraph); new CanonicalizerPhase(true).apply(referenceGraph, context); - assertEquals(referenceGraph, graph, excludeVirtual); + assertEquals(referenceGraph, graph, excludeVirtual, true); } } diff -r c25b121d36ec -r f729be5acf8e 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 Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Mar 31 17:51:25 2014 +0200 @@ -142,7 +142,7 @@ } protected void assertEquals(StructuredGraph expected, StructuredGraph graph) { - assertEquals(expected, graph, false); + assertEquals(expected, graph, false, true); } protected int countUnusedConstants(StructuredGraph graph) { @@ -165,9 +165,9 @@ return graph.getNodeCount() - countUnusedConstants(graph); } - protected void assertEquals(StructuredGraph expected, StructuredGraph graph, boolean excludeVirtual) { - String expectedString = getCanonicalGraphString(expected, excludeVirtual); - String actualString = getCanonicalGraphString(graph, excludeVirtual); + protected void assertEquals(StructuredGraph expected, StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) { + String expectedString = getCanonicalGraphString(expected, excludeVirtual, checkConstants); + String actualString = getCanonicalGraphString(graph, excludeVirtual, checkConstants); String mismatchString = "mismatch in graphs:\n========= expected =========\n" + expectedString + "\n\n========= actual =========\n" + actualString; if (!excludeVirtual && getNodeCountExcludingUnusedConstants(expected) != getNodeCountExcludingUnusedConstants(graph)) { @@ -183,7 +183,7 @@ } protected void assertConstantReturn(StructuredGraph graph, int value) { - String graphString = getCanonicalGraphString(graph, false); + String graphString = getCanonicalGraphString(graph, false, true); Assert.assertEquals("unexpected number of ReturnNodes: " + graphString, graph.getNodes(ReturnNode.class).count(), 1); ValueNode result = graph.getNodes(ReturnNode.class).first().result(); Assert.assertTrue("unexpected ReturnNode result node: " + graphString, result.isConstant()); @@ -191,7 +191,7 @@ Assert.assertEquals("unexpected ReturnNode result: " + graphString, result.asConstant().asInt(), value); } - protected static String getCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual) { + protected static String getCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) { SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); @@ -219,7 +219,7 @@ id = nextId++; canonicalId.set(node, id); } - String name = node instanceof ConstantNode ? node.toString(Verbosity.Name) : node.getClass().getSimpleName(); + String name = node instanceof ConstantNode && checkConstants ? node.toString(Verbosity.Name) : node.getClass().getSimpleName(); result.append(" " + id + "|" + name + (excludeVirtual ? "\n" : " (" + node.usages().count() + ")\n")); } } diff -r c25b121d36ec -r f729be5acf8e graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java Mon Mar 31 17:51:25 2014 +0200 @@ -61,17 +61,4 @@ public void afterSplit(AbstractBeginNode node) { // empty default implementation } - - public static final class EmptyState extends MergeableState implements Cloneable { - - @Override - public EmptyState clone() { - return this; - } - - @Override - public boolean merge(MergeNode merge, List withStates) { - return true; - } - } } diff -r c25b121d36ec -r f729be5acf8e graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java Mon Mar 31 17:51:25 2014 +0200 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.graph; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; + +/** + * This iterator implements a reverse post order iteration over the fixed nodes in the graph, + * starting at the given fixed node. + * + * No changes to the fixed nodes are expected during the iteration, they cause undefined behavior. + */ +public abstract class StatelessPostOrderNodeIterator { + + private final NodeBitMap visitedEnds; + private final Deque nodeQueue; + private final FixedNode start; + + public StatelessPostOrderNodeIterator(FixedNode start) { + visitedEnds = start.graph().createNodeBitMap(); + nodeQueue = new ArrayDeque<>(); + this.start = start; + } + + public void apply() { + FixedNode current = start; + + do { + if (current instanceof LoopBeginNode) { + loopBegin((LoopBeginNode) current); + current = ((LoopBeginNode) current).next(); + assert current != null; + } else if (current instanceof LoopEndNode) { + loopEnd((LoopEndNode) current); + assert !visitedEnds.isMarked(current); + visitedEnds.mark(current); + current = nodeQueue.pollFirst(); + } else if (current instanceof MergeNode) { + merge((MergeNode) current); + current = ((MergeNode) current).next(); + assert current != null; + } else if (current instanceof FixedWithNextNode) { + node(current); + current = ((FixedWithNextNode) current).next(); + } else if (current instanceof EndNode) { + end((EndNode) current); + queueMerge((EndNode) current); + current = nodeQueue.pollFirst(); + } else if (current instanceof ControlSinkNode) { + node(current); + current = nodeQueue.pollFirst(); + } else if (current instanceof ControlSplitNode) { + controlSplit((ControlSplitNode) current); + for (Node node : current.successors()) { + if (node != null) { + nodeQueue.addFirst((AbstractBeginNode) node); + } + } + current = nodeQueue.pollFirst(); + } else { + assert false : current; + } + } while (current != null); + finished(); + } + + private void queueMerge(EndNode end) { + assert !visitedEnds.isMarked(end); + visitedEnds.mark(end); + MergeNode merge = end.merge(); + boolean endsVisited = true; + for (int i = 0; i < merge.forwardEndCount(); i++) { + if (!visitedEnds.isMarked(merge.forwardEndAt(i))) { + endsVisited = false; + break; + } + } + if (endsVisited) { + nodeQueue.add(merge); + } + } + + protected void node(@SuppressWarnings("unused") FixedNode node) { + // empty default implementation + } + + protected void end(EndNode endNode) { + node(endNode); + } + + protected void merge(MergeNode merge) { + node(merge); + } + + protected void loopBegin(LoopBeginNode loopBegin) { + node(loopBegin); + } + + protected void loopEnd(LoopEndNode loopEnd) { + node(loopEnd); + } + + protected void controlSplit(ControlSplitNode controlSplit) { + node(controlSplit); + } + + protected void finished() { + // nothing to do + } +} diff -r c25b121d36ec -r f729be5acf8e graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Mon Mar 31 17:51:25 2014 +0200 @@ -80,7 +80,7 @@ final ArrayList nodes = new ArrayList<>(); final NodeBitMap visited = graph.createNodeBitMap(); - new PostOrderNodeIterator(graph.start(), new MergeableState.EmptyState()) { + new StatelessPostOrderNodeIterator(graph.start()) { @Override protected void node(FixedNode node) { visitForward(nodes, visited, node, false); diff -r c25b121d36ec -r f729be5acf8e graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Mar 31 17:51:25 2014 +0200 @@ -67,7 +67,7 @@ InstalledCode result = truffleCompiler.compileMethodHelper(actual, assumptions, root.toString(), getSpeculationLog()); StructuredGraph expected = parseForComparison(methodName); removeFrameStates(actual); - Assert.assertEquals(getCanonicalGraphString(expected, true), getCanonicalGraphString(actual, true)); + Assert.assertEquals(getCanonicalGraphString(expected, true, true), getCanonicalGraphString(actual, true, true)); return result; } diff -r c25b121d36ec -r f729be5acf8e 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 Mon Mar 31 17:51:11 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Mar 31 17:51:25 2014 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; @@ -110,7 +111,7 @@ ((Virtualizable) node).virtualize(tool); } if (tool.isDeleted()) { - return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode); + return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode || node instanceof BoxNode); } if (isMarked) { for (ValueNode input : node.inputs().filter(ValueNode.class)) { @@ -322,7 +323,7 @@ * merging operation invalid. The merging process is executed until a stable state has been * reached. This method needs to be careful to place the effects of the merging operation * into the correct blocks. - * + * * @param states the predecessor block states of the merge */ @Override @@ -398,7 +399,7 @@ * materialized, and a PhiNode for the materialized values will be created. Object states * can be incompatible if they contain {@code long} or {@code double} values occupying two * {@code int} slots in such a way that that their values cannot be merged using PhiNodes. - * + * * @param object the virtual object that should be associated with the merged object state * @param objStates the incoming object states (all of which need to be virtual) * @param blockStates the predecessor block states of the merge @@ -509,7 +510,7 @@ /** * Fill the inputs of the PhiNode corresponding to one {@link Kind#Object} entry in the * virtual object. - * + * * @return true if materialization happened during the merge, false otherwise */ private boolean mergeObjectEntry(ObjectState[] objStates, List blockStates, PhiNode phi, int entryIndex) { @@ -548,7 +549,7 @@ * refer to virtual object states. In order for the merging to happen, all incoming object * states need to be compatible and without object identity (meaning that their object * identity if not used later on). - * + * * @param phi the PhiNode that should be processed * @param states the predecessor block states of the merge * @param mergedVirtualObjects the set of virtual objects that exist in all incoming states,