changeset 9356:86d981cd8e22

Fixed a bug in new code generation layout.
author Christian Humer <christian.humer@gmail.com>
date Sat, 27 Apr 2013 00:49:49 +0200
parents 927e0792094b
children cc2149467eed
files graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java
diffstat 3 files changed, 66 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java	Fri Apr 26 23:03:09 2013 +0200
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java	Sat Apr 27 00:49:49 2013 +0200
@@ -45,23 +45,19 @@
         assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1));
         assertEquals(1, InvocationGuard.specializedInvocations);
         assertEquals(0, InvocationGuard.genericInvocations);
-        assertEquals(1, InvocationGuard.guardInvocations);
 
         assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1));
         assertEquals(1, InvocationGuard.specializedInvocations);
         assertEquals(1, InvocationGuard.genericInvocations);
-        assertEquals(2, InvocationGuard.guardInvocations);
     }
 
     @NodeChildren({@NodeChild("value0"), @NodeChild("value1")})
     public abstract static class InvocationGuard extends ValueNode {
 
-        static int guardInvocations = 0;
         static int specializedInvocations = 0;
         static int genericInvocations = 0;
 
         boolean guard(int value0, int value1) {
-            guardInvocations++;
             return value0 != Integer.MAX_VALUE;
         }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Fri Apr 26 23:03:09 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Sat Apr 27 00:49:49 2013 +0200
@@ -475,6 +475,19 @@
         currentElement.registerAtEnd(callback);
     }
 
+    public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) {
+        if (!Utils.isVoid(type)) {
+            startStatement();
+            type(type);
+            string(" ");
+            string(name);
+            string(" = ");
+            defaultValue(type);
+            end(); // statement
+        }
+        return this;
+    }
+
     public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) {
         if (Utils.isVoid(type)) {
             startStatement();
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Fri Apr 26 23:03:09 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Sat Apr 27 00:49:49 2013 +0200
@@ -760,8 +760,12 @@
                 builder.end();
 
                 emitSpecializationListeners(builder, node);
+                builder.defaultDeclaration(node.getGenericSpecialization().getReturnSignature().getPrimitiveType(), "result");
+                if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) {
+                    builder.defaultDeclaration(getContext().getType(boolean.class), "resultIsSet");
+                }
                 builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
-                prefix = "allowed";
+                prefix = null;
             }
 
             addInternalValueParameters(method, node.getGenericSpecialization(), true);
@@ -801,9 +805,10 @@
 
                 execute.tree(createGenericInvoke(builder, current, specialize));
 
-                if (specialize) {
+                if (specialize && !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));
             }
 
@@ -811,10 +816,6 @@
                 builder.string("// unreachable ").string(specializationData.getId()).newLine();
             }
 
-            if (specialize) {
-                builder.startThrow().startNew(getContext().getType(AssertionError.class)).end().end();
-            }
-
             return method;
         }
 
@@ -825,21 +826,57 @@
                 builder.startTryBlock();
             }
 
-            if (current.getMethod() == null) {
+            CodeTree executeCall = null;
+            if (current.getMethod() != null) {
+                executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null);
+            }
+
+            if (specialize && executeCall == null && !current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
                 emitEncounteredSynthetic(builder);
-            } else {
-                CodeTree executeCall = createTemplateMethodCall(builder, null, current.getNode().getGenericSpecialization(), current, null);
+            } else if (specialize) {
+
+                if (current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
+                    builder.startIf().string("!resultIsSet").end().startBlock();
+                    if (executeCall != null) {
+                        if (current.getReturnSignature().isVoid()) {
+                            builder.statement(executeCall);
+                        } else {
+                            builder.startStatement().string("result = ").tree(executeCall).end();
+                        }
+                        builder.statement("resultIsSet = true");
+                    } else {
+                        emitEncounteredSynthetic(builder);
+                    }
+                    builder.end();
+                }
 
-                if (specialize) {
-                    builder.declaration(current.getReturnSignature().getPrimitiveType(), "result", executeCall);
-                    builder.startStatement().startCall("super", "replace");
-                    builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
-                    builder.end().end();
+                if (!current.isGeneric()) {
+                    builder.startIf().string("allowed").end().startBlock();
+                }
+
+                if (!current.getNode().getGenericSpecialization().isUseSpecializationsForGeneric()) {
                     if (current.getReturnSignature().isVoid()) {
-                        builder.returnStatement();
+                        builder.statement(executeCall);
                     } else {
-                        builder.startReturn().string("result").end();
+                        builder.startStatement().string("result = ").tree(executeCall).end();
                     }
+                }
+
+                builder.startStatement().startCall("super", "replace");
+                builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
+                builder.end().end();
+
+                if (current.getReturnSignature().isVoid()) {
+                    builder.returnStatement();
+                } else {
+                    builder.startReturn().string("result").end();
+                }
+                if (!current.isGeneric()) {
+                    builder.end();
+                }
+            } else {
+                if (executeCall == null) {
+                    emitEncounteredSynthetic(builder);
                 } else {
                     builder.startReturn().tree(executeCall).end();
                 }