diff graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 8595:8a1115c92271

Implemented codegen guard definitions can now omit unused parameters.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Apr 2013 21:43:20 +0200
parents a80bf36c6a1e
children e0ff5cf358a4
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Apr 01 12:19:15 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Apr 01 21:43:20 2013 +0200
@@ -117,24 +117,28 @@
         }
     }
 
-    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod target, TemplateMethod sourceMethod, TemplateMethod castMethod, String unexpectedValueName) {
+    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName) {
         CodeTreeBuilder builder = parent.create();
 
-        boolean castedValues = sourceMethod != castMethod;
+        boolean castedValues = sourceMethod != targetMethod;
 
         builder.startGroup();
-        ExecutableElement method = target.getMethod();
+        ExecutableElement method = targetMethod.getMethod();
         if (method == null) {
-            throw new IllegalStateException("Cannot call synthtetic operation methods.");
+            throw new IllegalStateException("Cannot call synthetic operation methods.");
         }
         TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
-        NodeData node = (NodeData) castMethod.getTemplate();
+        NodeData node = (NodeData) targetMethod.getTemplate();
         TypeSystemData typeSystem = node.getTypeSystem();
 
-        boolean accessible = target.canBeAccessedByInstanceOf(node.getNodeType());
+        boolean accessible = targetMethod.canBeAccessedByInstanceOf(node.getNodeType());
         if (accessible) {
             if (builder.findMethod().getModifiers().contains(STATIC)) {
-                builder.string(THIS_NODE_LOCAL_VAR_NAME);
+                if (method.getModifiers().contains(STATIC)) {
+                    builder.type(targetClass.asType());
+                } else {
+                    builder.string(THIS_NODE_LOCAL_VAR_NAME);
+                }
             } else {
                 builder.string("super");
             }
@@ -143,8 +147,8 @@
                 builder.type(targetClass.asType());
             } else {
                 ActualParameter parameter = null;
-                for (ActualParameter searchParameter : target.getParameters()) {
-                    if (!searchParameter.getSpecification().isOptional()) {
+                for (ActualParameter searchParameter : targetMethod.getParameters()) {
+                    if (searchParameter.getSpecification().isSignature()) {
                         parameter = searchParameter;
                         break;
                     }
@@ -172,10 +176,10 @@
         builder.string(".");
         builder.startCall(method.getSimpleName().toString());
 
-        for (ActualParameter targetParameter : castMethod.getParameters()) {
+        for (ActualParameter targetParameter : targetMethod.getParameters()) {
             ActualParameter valueParameter = sourceMethod.findParameter(targetParameter.getLocalName());
             if (valueParameter == null) {
-                continue;
+                valueParameter = targetParameter;
             }
             TypeData targetType = targetParameter.getActualTypeData(typeSystem);
 
@@ -257,12 +261,34 @@
         body.string(".").startCall(methodName);
     }
 
-    private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization,
+    private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
                     CodeTree guardedStatements, CodeTree elseStatements) {
 
+        NodeData node = targetSpecialization.getNode();
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, valueSpecialization, guardedSpecialization);
-        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization);
+        CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization);
+        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization);
+
+        Set<String> valuesNeedsCast;
+        if (castValues) {
+            // cast all
+            valuesNeedsCast = null;
+        } else {
+            // find out which values needs a cast
+            valuesNeedsCast = new HashSet<>();
+            for (GuardData guard : targetSpecialization.getGuards()) {
+                for (ActualParameter parameter : guard.getParameters()) {
+                    NodeFieldData field = node.findField(parameter.getSpecification().getName());
+                    if (field == null) {
+                        continue;
+                    }
+                    TypeData typeData = parameter.getActualTypeData(node.getTypeSystem());
+                    if (typeData != null && !typeData.isGeneric()) {
+                        valuesNeedsCast.add(parameter.getLocalName());
+                    }
+                }
+            }
+        }
 
         int ifCount = 0;
 
@@ -274,9 +300,7 @@
             ifCount++;
         }
 
-        if (explicitGuards != null || !onSpecialization) {
-            builder.tree(createCasts(parent, valueSpecialization, guardedSpecialization));
-        }
+        builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization));
 
         if (explicitGuards != null) {
             builder.startIf();
@@ -309,7 +333,7 @@
             // Explicitly specified guards
             for (GuardData guard : guardedSpecialization.getGuards()) {
                 builder.string(andOperator);
-                builder.tree(createTemplateMethodCall(parent, guard, valueSpecialization, guardedSpecialization, null));
+                builder.tree(createTemplateMethodCall(parent, valueSpecialization, guard, null));
                 andOperator = " && ";
             }
         }
@@ -317,7 +341,7 @@
         return builder.isEmpty() ? null : builder.getRoot();
     }
 
-    private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
+    private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         // Implict guards based on method signature
         for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
@@ -327,6 +351,10 @@
             }
             ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
 
+            if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
+                continue;
+            }
+
             CodeTree cast = createCast(parent, field, valueParam, guardedParam);
             if (cast == null) {
                 continue;
@@ -943,7 +971,7 @@
             CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize");
             method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
             method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
-            addInternalValueParameters(method, node.getGenericSpecialization(), false);
+            addInternalValueParameters(method, node.getGenericSpecialization(), true);
 
             CodeTreeBuilder body = method.createBuilder();
             body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
@@ -957,7 +985,7 @@
                 guarded.string(THIS_NODE_LOCAL_VAR_NAME);
                 guarded.end().end();
 
-                body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, true, guarded.getRoot(), null));
+                body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, false, guarded.getRoot(), null));
             }
             body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end();
 
@@ -1013,7 +1041,7 @@
                 addInternalValueParameterNames(nextBuilder, next, null, true, true);
                 nextBuilder.end().end();
 
-                invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot());
+                invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, true, invokeMethod, nextBuilder.getRoot());
             }
 
             builder.tree(invokeMethod);
@@ -1032,7 +1060,7 @@
                 emitEncounteredSynthetic(builder);
             } else {
                 builder.startReturn();
-                builder.tree(createTemplateMethodCall(builder, specialization, specialization.getNode().getGenericSpecialization(), specialization, null));
+                builder.tree(createTemplateMethodCall(builder, specialization.getNode().getGenericSpecialization(), specialization, null));
                 builder.end(); // return
             }
 
@@ -1202,7 +1230,7 @@
             if (next != null) {
                 returnSpecialized = createReturnSpecializeAndExecute(builder, next, null);
             }
-            builder.tree(createGuardAndCast(builder, null, specialization, specialization, false, executeNode, returnSpecialized));
+            builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized));
         }
 
         private CodeTree createDeoptimize(CodeTreeBuilder parent) {
@@ -1225,7 +1253,7 @@
                 builder.startCall(factoryClassName(node), "specialize");
                 builder.string("this");
                 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType());
-                addInternalValueParameterNames(builder, specialization, null, false, true);
+                addInternalValueParameterNames(builder, specialization, null, true, true);
                 builder.end(); // call replace, call specialize
             } else {
                 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end();
@@ -1263,7 +1291,7 @@
                 builder.end().end();
             } else {
                 builder.startReturn();
-                builder.tree(createTemplateMethodCall(builder, specialization, specialization, specialization, null));
+                builder.tree(createTemplateMethodCall(builder, specialization, specialization, null));
                 builder.end(); // return
             }
 
@@ -1294,7 +1322,7 @@
         private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
             for (TemplateMethod listener : node.getSpecializationListeners()) {
                 builder.startStatement();
-                builder.tree(createTemplateMethodCall(builder, listener, listener, listener, null));
+                builder.tree(createTemplateMethodCall(builder, listener, listener, null));
                 builder.end(); // statement
             }
         }
@@ -1390,7 +1418,7 @@
             builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
             ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
 
-            builder.tree(createTemplateMethodCall(builder, shortCircuitData, shortCircuitData, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
+            builder.tree(createTemplateMethodCall(builder, shortCircuitData, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
 
             builder.end(); // statement
 
@@ -1443,7 +1471,7 @@
             builder.startStatement();
             builder.startCall("replace");
             builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState");
-            addInternalValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true);
+            addInternalValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, true, true);
             builder.end();
             builder.end(); // call replace
             builder.end(); // statement