changeset 9555:76937211a12d

Merge (fixed: 5bf09c5cd2e6 ReadNode/PiPush: compute declaring class by field offset)
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 03 May 2013 20:28:54 +0200
parents 8ccca4b4f880 (current diff) 5bf09c5cd2e6 (diff)
children 54748fae40d7
files
diffstat 8 files changed, 158 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- 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<StructuredGraph>() {
 
--- 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);
             }
--- 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;
     }
--- 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;
             }
         }
 
--- 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";
--- 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<Object> children = NodeUtil.findNodeChildren(node);
+        List<Node> children = NodeUtil.findNodeChildren((Node) node);
         for (Object child : children) {
             if (child == null) {
                 continue;
--- 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<Object> findNodeChildren(Object node) {
-        List<Object> nodes = new ArrayList<>();
+    public static List<Node> findNodeChildren(Node node) {
+        List<Node> 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> T findFirstNodeInstance(Object root, Class<T> clazz) {
-        List<Object> childNodes = findNodeChildren(root);
-
-        for (Object childNode : childNodes) {
+    public static <T> T findFirstNodeInstance(Node root, Class<T> 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
--- 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<ActualParameter> 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);