# HG changeset patch # User Tom Rodriguez # Date 1429835104 25200 # Node ID 905d93bb3d319230d69dc00dfde7b74ef30920c7 # Parent 05e3ec9d5aa2de021ab1ca07c0db82e92b7e2a58# Parent fe0531d98fbee0e3024edb313fbceef003e6592f Merge diff -r 05e3ec9d5aa2 -r 905d93bb3d31 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java Thu Apr 23 17:18:52 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java Thu Apr 23 17:25:04 2015 -0700 @@ -387,11 +387,12 @@ resultScope = new LoopScope(loopScope, loopScope.loopDepth + 1, 0, mergeOrderId, Arrays.copyOf(loopScope.createdNodes, loopScope.createdNodes.length), // methodScope.loopExplosion != LoopExplosionKind.NONE ? new ArrayDeque<>() : null, // methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE ? new HashMap<>() : null); + phiInputScope = resultScope; phiNodeScope = resultScope; - registerNode(phiInputScope, mergeOrderId, null, true, true); - phiInputScope.nodesToProcess.clear(mergeOrderId); - phiNodeScope.nodesToProcess.set(mergeOrderId); + registerNode(loopScope, mergeOrderId, null, true, true); + loopScope.nodesToProcess.clear(mergeOrderId); + resultScope.nodesToProcess.set(mergeOrderId); } } @@ -679,7 +680,7 @@ * not processed yet when processing the loop body, we need to create all phi functions * upfront. */ - boolean lazyPhi = !(merge instanceof LoopBeginNode) || methodScope.loopExplosion != LoopExplosionKind.NONE; + boolean lazyPhi = allowLazyPhis() && (!(merge instanceof LoopBeginNode) || methodScope.loopExplosion != LoopExplosionKind.NONE); int numPhis = methodScope.reader.getUVInt(); for (int i = 0; i < numPhis; i++) { int phiInputOrderId = readOrderId(methodScope); @@ -714,6 +715,11 @@ } } + protected boolean allowLazyPhis() { + /* We need to exactly reproduce the encoded graph, including unnecessary phi functions. */ + return false; + } + protected Node instantiateNode(MethodScope methodScope, int nodeOrderId) { methodScope.reader.setByteIndex(methodScope.encodedGraph.nodeStartOffsets[nodeOrderId]); NodeClass nodeClass = methodScope.encodedGraph.getNodeClasses()[methodScope.reader.getUVInt()]; @@ -795,7 +801,7 @@ /* Allow subclasses to canonicalize and intercept nodes. */ node = handleFloatingNodeBeforeAdd(methodScope, loopScope, node); if (!node.isAlive()) { - node = methodScope.graph.addOrUnique(node); + node = addFloatingNode(methodScope, node); } node = handleFloatingNodeAfterAdd(methodScope, loopScope, node); } @@ -803,6 +809,14 @@ return node; } + protected Node addFloatingNode(MethodScope methodScope, Node node) { + /* + * We want to exactly reproduce the encoded graph. Even though nodes should be unique in the + * encoded graph, this is not always guaranteed. + */ + return methodScope.graph.addWithoutUnique(node); + } + /** * Decodes a non-fixed node, but does not do any post-processing and does not register it. */ diff -r 05e3ec9d5aa2 -r 905d93bb3d31 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphEncoder.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphEncoder.java Thu Apr 23 17:18:52 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphEncoder.java Thu Apr 23 17:25:04 2015 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.util.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -388,7 +389,15 @@ decoder.decode(decodedGraph, encodedGraph); decodedGraph.verify(); - GraphComparison.verifyGraphsEqual(originalGraph, decodedGraph); + try { + GraphComparison.verifyGraphsEqual(originalGraph, decodedGraph); + } catch (Throwable ex) { + try (Debug.Scope scope = Debug.scope("GraphEncoder")) { + Debug.dump(originalGraph, "Original Graph"); + Debug.dump(decodedGraph, "Decoded Graph"); + } + throw ex; + } return true; } } @@ -483,19 +492,7 @@ assert !actualIter.hasNext(); } - protected static void verifyNodeEqual(Node e, Node actualNode, NodeMap nodeMapping, Deque> workList, boolean ignoreEndNode) { - Node expectedNode = e; - if (expectedNode instanceof PhiNode) { - /* - * The input graph can contain unnecessary (eliminatable) phi functions. Such phis are - * not re-created during decoding, so we need to simplify the expected node too. - */ - Node singleValue = ((PhiNode) expectedNode).singleValue(); - if (singleValue != null && singleValue != PhiNode.MULTIPLE_VALUES) { - expectedNode = singleValue; - } - } - + protected static void verifyNodeEqual(Node expectedNode, Node actualNode, NodeMap nodeMapping, Deque> workList, boolean ignoreEndNode) { assert expectedNode.getClass() == actualNode.getClass(); if (ignoreEndNode && expectedNode instanceof EndNode) { return; diff -r 05e3ec9d5aa2 -r 905d93bb3d31 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java Thu Apr 23 17:18:52 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimplifyingGraphDecoder.java Thu Apr 23 17:25:04 2015 -0700 @@ -82,6 +82,15 @@ } @Override + protected boolean allowLazyPhis() { + /* + * We do not need to exactly reproduce the encoded graph, so we want to avoid unnecessary + * phi functions. + */ + return true; + } + + @Override protected void simplifyFixedNode(MethodScope methodScope, LoopScope loopScope, int nodeOrderId, FixedNode node) { if (node instanceof IfNode) { IfNode ifNode = (IfNode) node; @@ -171,4 +180,13 @@ } return node; } + + @Override + protected Node addFloatingNode(MethodScope methodScope, Node node) { + /* + * In contrast to the base class implementation, we do not need to exactly reproduce the + * encoded graph. Since we do canonicalization, we also want nodes to be unique. + */ + return methodScope.graph.addOrUnique(node); + } }