diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 10602:b8fe1fe004ec

Truffle-DSL: fixed bugs in the generated polymorphic code generation.
author Christian Humer <christian.humer@gmail.com>
date Tue, 02 Jul 2013 19:21:59 +0200
parents e93efe3ba5f4
children 3ae117e62905
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Tue Jul 02 14:51:22 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Tue Jul 02 19:21:59 2013 +0200
@@ -79,7 +79,7 @@
         }
 
         String name = Utils.firstLetterUpperCase(nodeid);
-        if (specialization == node.getGenericPolymorphicSpecializtion()) {
+        if (specialization == node.getGenericPolymorphicSpecialization()) {
             name += "PolymorphicNode";
         } else {
             name += "Polymorphic" + polymorphicIndex(node, specialization) + "Node";
@@ -101,7 +101,7 @@
 
     private static String executeCachedName(SpecializationData polymorphic) {
         NodeData node = polymorphic.getNode();
-        boolean generic = polymorphic == node.getGenericPolymorphicSpecializtion();
+        boolean generic = polymorphic == node.getGenericPolymorphicSpecialization();
 
         if (generic) {
             return "executeCachedGeneric0";
@@ -116,7 +116,7 @@
             if (specialization == polymorphic) {
                 break;
             }
-            if (specialization != node.getGenericPolymorphicSpecializtion()) {
+            if (specialization != node.getGenericPolymorphicSpecialization()) {
                 index++;
             }
         }
@@ -687,10 +687,10 @@
 
                 if (node.getPolymorphicDepth() > 1) {
                     PolymorphicNodeFactory generic = new PolymorphicNodeFactory(getContext(), generatedNode, true);
-                    add(generic, node.getGenericPolymorphicSpecializtion());
+                    add(generic, node.getGenericPolymorphicSpecialization());
 
                     for (SpecializationData specialization : node.getPolymorphicSpecializations()) {
-                        if (specialization == node.getGenericPolymorphicSpecializtion()) {
+                        if (specialization == node.getGenericPolymorphicSpecialization()) {
                             continue;
                         }
                         add(new PolymorphicNodeFactory(context, generic.getElement(), false), specialization);
@@ -1094,10 +1094,10 @@
 
                     clazz.add(createCreateSpecialization(node));
 
-                    CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getGenericPolymorphicSpecializtion(), null);
+                    CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getGenericPolymorphicSpecialization(), null);
                     clazz.add(genericCachedExecute);
                     for (SpecializationData polymorph : node.getPolymorphicSpecializations()) {
-                        if (polymorph == node.getGenericPolymorphicSpecializtion()) {
+                        if (polymorph == node.getGenericPolymorphicSpecialization()) {
                             continue;
                         }
                         clazz.add(createCachedExecute(node, polymorph, genericCachedExecute));
@@ -1214,10 +1214,10 @@
             CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED), polymorph.getReturnType().getType(), name);
             addInternalValueParameters(cachedExecute, polymorph, true, true);
 
-            if (polymorph == node.getGenericPolymorphicSpecializtion()) {
+            if (polymorph == node.getGenericPolymorphicSpecialization()) {
                 cachedExecute.getModifiers().add(ABSTRACT);
             } else {
-                SpecializationData genericPolymorph = node.getGenericPolymorphicSpecializtion();
+                SpecializationData genericPolymorph = node.getGenericPolymorphicSpecialization();
                 CodeTreeBuilder builder = cachedExecute.createBuilder();
                 ExecutableTypeData genericExecutable = new ExecutableTypeData(genericPolymorph, genericPolymorphMethod, node.getTypeSystem(), genericPolymorph.getReturnType().getTypeSystemType());
                 ExecutableTypeData specificExecutable = new ExecutableTypeData(polymorph, cachedExecute, node.getTypeSystem(), polymorph.getReturnType().getTypeSystemType());
@@ -1378,6 +1378,7 @@
 
             DeclaredType annotationType;
             if (child.getCardinality() == Cardinality.MANY) {
+                var.getModifiers().add(Modifier.FINAL);
                 annotationType = getContext().getTruffleTypes().getChildrenAnnotation();
             } else {
                 annotationType = getContext().getTruffleTypes().getChildAnnotation();
@@ -1415,26 +1416,31 @@
 
             List<SpecializationData> specializations = node.getSpecializations();
 
+            boolean firstUnreachable = true;
+            SpecializationData previous = null;
             for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || !current.isReachable()) {
+                if (current.isUninitialized()) {
                     continue;
                 }
-                CodeTreeBuilder execute = new CodeTreeBuilder(builder);
 
-                execute.tree(createGenericInvokeAndSpecialize(builder, node.getGenericSpecialization(), current));
+                if (current.isReachable()) {
+                    CodeTree execute = createGenericInvokeAndSpecialize(builder, node.getGenericSpecialization(), current);
 
-                if (!current.isGeneric()) {
-                    builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end();
-                }
+                    if (!current.isGeneric()) {
+                        builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end();
+                    }
 
-                builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true, false));
-            }
-
-            for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || current.isReachable()) {
-                    continue;
+                    builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute, null, true, false));
+                } else {
+                    if (firstUnreachable) {
+                        if (previous != null && !previous.isGenericSpecialization(getContext()) && !previous.hasRewrite(getContext())) {
+                            emitEncounteredSynthetic(builder, current);
+                        }
+                        firstUnreachable = false;
+                    }
+                    builder.string("// unreachable ").string(current.getId()).newLine();
                 }
-                builder.string("// unreachable ").string(current.getId()).newLine();
+                previous = current;
             }
 
             return method;
@@ -1527,7 +1533,7 @@
                         builder.startWhile().string("searchNode != null").end();
                         builder.startBlock();
                         builder.statement("searchNode = searchNode.getParent()");
-                        builder.startIf().instanceOf("searchNode", nodePolymorphicClassName(node, node.getGenericPolymorphicSpecializtion())).end();
+                        builder.startIf().instanceOf("searchNode", nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization())).end();
                         builder.startBlock().breakStatement().end();
                         builder.end();
                         builder.startStatement().startCall("searchNode", "replace");
@@ -1586,15 +1592,26 @@
         }
 
         private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node) {
-            String className = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecializtion());
+            String className = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
             CodeTreeBuilder builder = parent.create();
             builder.startStatement();
             builder.string(className);
             builder.string(" polymorphic = ");
             builder.startNew(className).string("this").end();
             builder.end();
-            for (NodeChildData child : node.getChildren()) {
-                builder.startStatement().string("this.").string(child.getName()).string(" = null").end();
+
+            for (ActualParameter param : node.getGenericSpecialization().getParameters()) {
+                if (!param.getSpecification().isSignature()) {
+                    continue;
+                }
+                NodeChildData child = node.findChild(param.getSpecification().getName());
+                if (child != null) {
+                    builder.startStatement().string("this.").string(child.getName());
+                    if (child.getCardinality().isMany()) {
+                        builder.string("[").string(String.valueOf(param.getIndex())).string("]");
+                    }
+                    builder.string(" = null").end();
+                }
             }
             builder.startStatement().startCall("super", "replace");
             builder.string("polymorphic");
@@ -1814,7 +1831,7 @@
                 builder.tree(createDeoptimize(builder));
                 builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter, false));
                 if (specialization.isPolymorphic()) {
-                    builder.tree(createReturnOptimizeTypes(builder, specialization, param));
+                    builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param));
                 } else {
                     builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization.findNextSpecialization(), param, "Expected " + param.getLocalName() + " instanceof " +
                                     Utils.getSimpleName(param.getType())));
@@ -1825,10 +1842,10 @@
             return builder.getRoot();
         }
 
-        private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, SpecializationData specialization, ActualParameter param) {
+        private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, ActualParameter param) {
             NodeData node = specialization.getNode();
             assert !node.getPolymorphicSpecializations().isEmpty();
-            SpecializationData generic = node.getGenericPolymorphicSpecializtion();
+            SpecializationData generic = node.getGenericPolymorphicSpecialization();
 
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
             builder.startReturn();
@@ -1839,9 +1856,8 @@
             execute.end();
 
             TypeData sourceType = generic.getReturnType().getTypeSystemType();
-            TypeData targetType = specialization.getReturnType().getTypeSystemType();
 
-            builder.tree(createCastType(node, sourceType, targetType, true, execute.getRoot()));
+            builder.tree(createExpectExecutableType(node, sourceType, currentExecutable, execute.getRoot()));
 
             builder.end();
             return builder.getRoot();
@@ -1875,6 +1891,7 @@
                 if (!parameter.getSpecification().isSignature()) {
                     builder.string(parameter.getLocalName());
                 } else {
+
                     if (index < targetField.getExecuteWith().size()) {
                         NodeChildData child = targetField.getExecuteWith().get(index);
 
@@ -2201,7 +2218,7 @@
 
         private CodeTree createAppendPolymorphic(CodeTreeBuilder parent, SpecializationData specialization) {
             NodeData node = specialization.getNode();
-            String genericClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecializtion());
+            String genericClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
 
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
             builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end();