# HG changeset patch # User Lukas Stadler # Date 1367605734 -7200 # Node ID 76937211a12d2f2c9b36fc1a826dd5590a877374 # Parent 8ccca4b4f880f5fe2bff46092c34a315e96ffd1d# Parent 5bf09c5cd2e66fb60b46440b68cb5e7675984b1a Merge (fixed: 5bf09c5cd2e6 ReadNode/PiPush: compute declaring class by field offset) diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri May 03 20:28:54 2013 +0200 @@ -26,7 +26,7 @@ import junit.framework.Assert; -import org.junit.*; +import org.junit.Test; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; @@ -91,6 +91,22 @@ compileSnippet("test4Snippet", 2, 2); } + public static long test5Snippet(A1 a1) { + long sum = 0; + A2 a2 = (A2) a1; + A3 a3 = (A3) a2; + sum += a2.x2; + return sum + a3.x3; + } + + @Test + public void test5() { + StructuredGraph graph = compileSnippet("test5Snippet", 2, 1); + for (LoadFieldNode lfn : graph.getNodes().filter(LoadFieldNode.class)) { + Assert.assertTrue(lfn.object() instanceof CheckCastNode); + } + } + private StructuredGraph compileSnippet(final String snippet, final int checkcasts, final int afterCanon) { return Debug.scope(snippet, new Callable() { diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri May 03 20:28:54 2013 +0200 @@ -31,9 +31,9 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -66,17 +66,24 @@ public void run() { StructuredGraph graph = compileTestSnippet(snippet); + int counter = 0; for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { - LocationIdentity locId = rn.location().getLocationIdentity(); - if (locId instanceof ResolvedJavaField) { - ResolvedJavaField field = (ResolvedJavaField) locId; - if (field.getName().equals("x")) { - Assert.assertTrue(rn.object() instanceof LocalNode); - } else { - Assert.assertTrue(rn.object() instanceof UnsafeCastNode); + if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { + long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); + ResolvedJavaType receiverType = rn.object().objectStamp().type(); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); + + if (field != null) { + if (field.getName().equals("x")) { + Assert.assertTrue(rn.object() instanceof LocalNode); + } else { + Assert.assertTrue(rn.object() instanceof UnsafeCastNode); + } + counter++; } } } + Assert.assertEquals(2, counter); Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1); } diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri May 03 20:28:54 2013 +0200 @@ -102,19 +102,27 @@ @Override public boolean push(PiNode parent) { - LocationIdentity locId = location().getLocationIdentity(); - if (locId instanceof ResolvedJavaField) { - ResolvedJavaType fieldType = ((ResolvedJavaField) locId).getDeclaringClass(); - ValueNode piValueStamp = parent.object(); - ResolvedJavaType beforePiType = piValueStamp.objectStamp().type(); + if (location() instanceof ConstantLocationNode) { + long displacement = ((ConstantLocationNode) location()).getDisplacement(); + if (parent.stamp() instanceof ObjectStamp) { + ObjectStamp piStamp = parent.objectStamp(); + ResolvedJavaType receiverType = piStamp.type(); + if (receiverType != null) { + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement); - if (beforePiType != null && fieldType.isAssignableFrom(beforePiType)) { - ObjectStamp piStamp = parent.objectStamp(); - if (piStamp.nonNull() == piValueStamp.objectStamp().nonNull() && piStamp.alwaysNull() == piValueStamp.objectStamp().alwaysNull()) { - replaceFirstInput(parent, piValueStamp); - return true; + if (field != null) { + ResolvedJavaType declaringClass = field.getDeclaringClass(); + if (declaringClass.isAssignableFrom(receiverType) && declaringClass != receiverType) { + ObjectStamp piValueStamp = parent.object().objectStamp(); + if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) { + replaceFirstInput(parent, parent.object()); + return true; + } + } + } } } + } return false; } diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri May 03 20:28:54 2013 +0200 @@ -85,11 +85,15 @@ // checkcast. return object(); } + // remove checkcast if next node is a more specific checkcast - if (next() instanceof CheckCastNode) { - CheckCastNode ccn = (CheckCastNode) next(); - if (ccn != null && ccn.type() != null && this == ccn.object() && type.isAssignableFrom(ccn.type())) { - return object(); + if (predecessor() instanceof CheckCastNode) { + CheckCastNode ccn = (CheckCastNode) predecessor(); + if (ccn != null && ccn.type != null && ccn == object && ccn.forStoreCheck == forStoreCheck && ccn.type.isAssignableFrom(type)) { + StructuredGraph graph = (StructuredGraph) ccn.graph(); + CheckCastNode newccn = graph.add(new CheckCastNode(type, ccn.object, ccn.profile, ccn.forStoreCheck)); + graph.replaceFixedWithFixed(ccn, newccn); + return newccn; } } diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri May 03 20:28:54 2013 +0200 @@ -34,7 +34,10 @@ private static final boolean ____ = false; // Checkstyle: resume - public static int Threads = 4; + public static int Threads; + static { + Threads = Runtime.getRuntime().availableProcessors(); + } public static String CompilerConfiguration = "basic"; public static String GraalRuntime = "basic"; diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Fri May 03 20:28:54 2013 +0200 @@ -334,7 +334,7 @@ // default handler createElementForNode(node); - List children = NodeUtil.findNodeChildren(node); + List children = NodeUtil.findNodeChildren((Node) node); for (Object child : children) { if (child == null) { continue; diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri May 03 20:28:54 2013 +0200 @@ -29,6 +29,9 @@ import sun.misc.*; +import com.oracle.truffle.api.nodes.Node.Child; +import com.oracle.truffle.api.nodes.Node.Children; + /** * Utility class that manages the special access methods for node instances. */ @@ -73,15 +76,13 @@ } // Node fields - if (Node.class.isAssignableFrom(field.getType())) { - if (!field.getName().equals("parent")) { - nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); - nodeFieldClassesList.add(field.getType()); - } else { - parentOffsetTemp = unsafe.objectFieldOffset(field); - parentClassTmp = field.getType(); - } - } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType())) { + if (Node.class.isAssignableFrom(field.getType()) && field.getName().equals("parent")) { + parentOffsetTemp = unsafe.objectFieldOffset(field); + parentClassTmp = field.getType(); + } else if (Node.class.isAssignableFrom(field.getType()) && field.getAnnotation(Child.class) != null) { + nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); + nodeFieldClassesList.add(field.getType()); + } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType()) && field.getAnnotation(Children.class) != null) { nodeArrayFieldOffsetsList.add(unsafe.objectFieldOffset(field)); nodeArrayFieldClassesList.add(field.getType()); } else { @@ -251,18 +252,18 @@ return (T) clone; } - public static List findNodeChildren(Object node) { - List nodes = new ArrayList<>(); + public static List findNodeChildren(Node node) { + List nodes = new ArrayList<>(); NodeClass nodeClass = NodeClass.get(node.getClass()); for (long fieldOffset : nodeClass.nodeFieldOffsets) { Object child = unsafe.getObject(node, fieldOffset); if (child != null) { - nodes.add(child); + nodes.add((Node) child); } } for (long fieldOffset : nodeClass.nodeArrayFieldOffsets) { - Object[] children = (Object[]) unsafe.getObject(node, fieldOffset); + Node[] children = (Node[]) unsafe.getObject(node, fieldOffset); if (children != null) { nodes.addAll(Arrays.asList(children)); } @@ -386,10 +387,8 @@ } @SuppressWarnings("unchecked") - public static T findFirstNodeInstance(Object root, Class clazz) { - List childNodes = findNodeChildren(root); - - for (Object childNode : childNodes) { + public static T findFirstNodeInstance(Node root, Class clazz) { + for (Node childNode : findNodeChildren(root)) { if (clazz.isInstance(childNode)) { return (T) childNode; } else { @@ -474,8 +473,16 @@ } public static String printTreeToString(Node node) { + return printTreeToString(node, false); + } + + private static String printTreeToString(Node node, boolean compact) { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - printTree(new PrintStream(byteOut), node); + if (compact) { + printCompactTree(new PrintStream(byteOut), node); + } else { + printTree(new PrintStream(byteOut), node); + } try { byteOut.flush(); } catch (IOException e) { @@ -494,6 +501,61 @@ printTree(p, node, new NodeTreeResolver()); } + public static String printCompactTreeToString(Node node) { + return printTreeToString(node, true); + } + + public static void printCompactTree(PrintStream p, Node node) { + printCompactTree(p, null, node, 1); + } + + private static void printCompactTree(PrintStream p, Node parent, Node node, int level) { + if (node == null) { + return; + } + for (int i = 0; i < level; i++) { + p.print(" "); + } + if (parent == null) { + p.println(node.getClass().getSimpleName()); + } else { + String fieldName = null; + Field[] fields = NodeUtil.getAllFields(parent.getClass()); + try { + for (Field field : fields) { + field.setAccessible(true); + Object value = field.get(parent); + if (value == node) { + fieldName = field.getName(); + break; + } else if (value instanceof Node[]) { + int index = 0; + for (Node arrayNode : (Node[]) value) { + if (arrayNode == node) { + fieldName = field.getName() + "[" + index + "]"; + break; + } + index++; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + if (fieldName == null) { + fieldName = "unknownField"; + } + p.print(fieldName); + p.print(" = "); + p.println(node.getClass().getSimpleName()); + } + + for (Node child : node.getChildren()) { + printCompactTree(p, node, child, level + 1); + } + } + /** * Prints a human readable form of a tree to the given {@link PrintStream}. The * {@link TreeResolver} interface needs to be implemented to specify how the method can read the @@ -639,12 +701,12 @@ @Override public boolean isChildObject(Field f) { - return Node.class.isAssignableFrom(f.getType()); + return Node.class.isAssignableFrom(f.getType()) && f.getAnnotation(Child.class) != null; } @Override public boolean isChildArrayObject(Field f) { - return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()); + return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()) && f.getAnnotation(Children.class) != null; } @Override diff -r 8ccca4b4f880 -r 76937211a12d graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri May 03 20:28:14 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri May 03 20:28:54 2013 +0200 @@ -1460,8 +1460,7 @@ List executeParameters = new ArrayList<>(); for (ActualParameter sourceParameter : executable.getParameters()) { - NodeChildData field = specialization.getNode().findChild(sourceParameter.getSpecification().getName()); - if (field == null) { + if (!sourceParameter.getSpecification().isSignature()) { continue; } @@ -1645,21 +1644,24 @@ for (ActualParameter targetParameter : targetParameters) { NodeChildData field = sourceNode.findChild(targetParameter.getSpecification().getName()); - if (field == null) { + if (!targetParameter.getSpecification().isSignature()) { continue; } + TypeData targetType = targetParameter.getTypeSystemType(); - - ExecutableTypeData targetExecutable = field.findExecutableType(getContext(), targetType); + ExecutableTypeData targetExecutable = null; + if (field != null) { + targetExecutable = field.findExecutableType(getContext(), targetType); + } ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); String targetVariableName = valueName(targetParameter); CodeTree executionExpression = null; - if (cast || sourceParameter != null) { + if ((sourceParameter != null && cast) || sourceParameter != null) { TypeData sourceType = sourceParameter.getTypeSystemType(); - if (!sourceType.needsCastTo(getContext(), targetType)) { - if (field.isShortCircuit() && sourceParameter != null) { + if (targetExecutable == null || !sourceType.needsCastTo(getContext(), targetType)) { + if (field != null && field.isShortCircuit() && sourceParameter != null) { builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter)); } builder.startStatement(); @@ -1667,8 +1669,10 @@ builder.string(valueName(targetParameter)).string(" = "); builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter))); builder.end(); + continue; } else { - executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter))); + CodeTree valueTree = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); + executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, valueTree); } } else if (sourceParameter == null) { executionExpression = createExecuteChildExpression(builder, field, targetParameter, unexpectedParameter);