changeset 11458:906d0cdf9c51

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Thu, 29 Aug 2013 17:17:35 +0200
parents fd1383d45420 (current diff) bd1a12a78a51 (diff)
children c66cdfb7445b df18a4214c7c
files
diffstat 11 files changed, 276 insertions(+), 303 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Thu Aug 29 17:17:35 2013 +0200
@@ -47,12 +47,18 @@
         public long y = 10;
     }
 
+    public static class C extends B {
+
+        public long z = 5;
+    }
+
     public static long test1Snippet(A a) {
-        B b = (B) a;
-        long ret = b.x; // this can be moved before the checkcast
-        ret += b.y;
+        C c = (C) a;
+        long ret = c.x; // this can be pushed before the checkcast
+        ret += c.y; // not allowed to push
+        ret += c.z; // not allowed to push
         // the null-check should be canonicalized with the null-check of the checkcast
-        ret += b != null ? 100 : 200;
+        ret += c != null ? 100 : 200;
         return ret;
     }
 
@@ -64,24 +70,20 @@
             public void run() {
                 StructuredGraph graph = compileTestSnippet(snippet);
 
-                int counter = 0;
                 for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) {
                     if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) {
                         long disp = ((ConstantLocationNode) rn.location()).getDisplacement();
                         ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object());
                         ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp);
 
-                        if (field != null) {
-                            if (field.getName().equals("x")) {
-                                Assert.assertTrue(rn.object() instanceof LocalNode);
-                            } else {
-                                Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode);
-                            }
-                            counter++;
+                        assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type";
+                        if (field.getName().equals("x")) {
+                            Assert.assertTrue(rn.object() instanceof LocalNode);
+                        } else {
+                            Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode);
                         }
                     }
                 }
-                Assert.assertEquals(2, counter);
 
                 Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1);
             }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Thu Aug 29 17:17:35 2013 +0200
@@ -236,6 +236,7 @@
                 HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase().apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
+                new CanonicalizerPhase(true).apply(graph, context);
                 new PartialEscapePhase(iterativeEscapeAnalysis).apply(graph, context);
                 Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count());
                 ReturnNode returnNode = graph.getNodes(ReturnNode.class).first();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Thu Aug 29 17:17:35 2013 +0200
@@ -124,6 +124,45 @@
         }
     }
 
+    @Test
+    public void testCache() {
+        testMaterialize("testCacheSnippet", 0.5, 1);
+    }
+
+    public static class CacheKey {
+
+        private final int idx;
+        private final Object ref;
+
+        public CacheKey(int idx, Object ref) {
+            this.idx = idx;
+            this.ref = ref;
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 * idx + ref.hashCode();
+        }
+
+        public synchronized boolean equals(CacheKey other) {
+            return idx == other.idx && ref == other.ref;
+        }
+    }
+
+    public static CacheKey cacheKey = null;
+    public static Object value = null;
+
+    private static native Object createValue(CacheKey key);
+
+    public static Object testCacheSnippet(int idx, Object ref) {
+        CacheKey key = new CacheKey(idx, ref);
+        if (!key.equals(cacheKey)) {
+            cacheKey = key;
+            value = createValue(key);
+        }
+        return value;
+    }
+
     @SafeVarargs
     final void testMaterialize(final String snippet, double expectedProbability, int expectedCount, Class<? extends Node>... invalidNodeClasses) {
         StructuredGraph result = processMethod(snippet);
@@ -162,15 +201,14 @@
                 HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase().apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
-                CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-                canonicalizer.apply(graph, context);
+                new CanonicalizerPhase(true).apply(graph, context);
                 new PartialEscapePhase(false).apply(graph, context);
 
                 for (MergeNode merge : graph.getNodes(MergeNode.class)) {
                     merge.setStateAfter(null);
                 }
                 new DeadCodeEliminationPhase().apply(graph);
-                canonicalizer.apply(graph, context);
+                new CanonicalizerPhase(true).apply(graph, context);
                 return graph;
             }
         });
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Aug 29 17:17:35 2013 +0200
@@ -104,29 +104,31 @@
 
     @Override
     public boolean push(PiNode parent) {
-        if (location() instanceof ConstantLocationNode) {
-            long displacement = ((ConstantLocationNode) location()).getDisplacement();
-            if (parent.stamp() instanceof ObjectStamp) {
-                ObjectStamp piStamp = (ObjectStamp) parent.stamp();
-                ResolvedJavaType receiverType = piStamp.type();
-                if (receiverType != null) {
-                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement);
+        if (!(location() instanceof ConstantLocationNode && parent.stamp() instanceof ObjectStamp && parent.object().stamp() instanceof ObjectStamp)) {
+            return false;
+        }
+
+        ObjectStamp piStamp = (ObjectStamp) parent.stamp();
+        ResolvedJavaType receiverType = piStamp.type();
+        if (receiverType == null) {
+            return false;
+        }
 
-                    if (field != null && parent.object().stamp() instanceof ObjectStamp) {
-                        ResolvedJavaType declaringClass = field.getDeclaringClass();
-                        ObjectStamp piValueStamp = (ObjectStamp) parent.object().stamp();
-                        ResolvedJavaType piValueType = ObjectStamp.typeOrNull(piValueStamp);
-                        if (piValueType != null && declaringClass.isAssignableFrom(piValueType)) {
-                            if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) {
-                                replaceFirstInput(parent, parent.object());
-                                return true;
-                            }
-                        }
-                    }
-                }
+        ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(((ConstantLocationNode) location()).getDisplacement());
+        if (field == null) {
+            // field was not declared by receiverType
+            return false;
+        }
+
+        ObjectStamp valueStamp = (ObjectStamp) parent.object().stamp();
+        ResolvedJavaType valueType = ObjectStamp.typeOrNull(valueStamp);
+        if (valueType != null && field.getDeclaringClass().isAssignableFrom(valueType)) {
+            if (piStamp.nonNull() == valueStamp.nonNull() && piStamp.alwaysNull() == valueStamp.alwaysNull()) {
+                replaceFirstInput(parent, parent.object());
+                return true;
             }
+        }
 
-        }
         return false;
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Aug 29 17:17:35 2013 +0200
@@ -233,6 +233,8 @@
                     if (node == beginNode) {
                         loweringTool.setLastFixedNode(beginNode);
                     } else {
+                        assert !(node instanceof Lowerable) : "SchedulingError: Lowerable " + node + " should not float before begin node " + beginNode;
+                        assert node instanceof FloatingNode : "skipped node must be a FloatingNode: " + node;
                         continue;
                     }
                 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Thu Aug 29 17:17:35 2013 +0200
@@ -133,6 +133,8 @@
                 return Kind.Long;
             case Int:
                 return Kind.Int;
+            case Byte:
+                return Kind.Byte;
             case Double:
                 return Kind.Double;
             case Float:
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java	Thu Aug 29 17:17:35 2013 +0200
@@ -26,13 +26,8 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.DoubleEvaluatedNodeFactory;
-import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.EvaluatedNodeFactory;
-import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluatedNodeFactory;
-import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory;
-import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode;
-import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestArguments;
-import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.*;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
@@ -104,4 +99,31 @@
         }
     }
 
+    @Test
+    public void testEvaluatedGeneration() throws UnexpectedResultException {
+        TestRootNode<TestEvaluatedGeneration> root = TestHelper.createRoot(TestEvaluatedGenerationFactory.getInstance());
+
+        Assert.assertEquals(42, root.getNode().executeEvaluated1(null, 42));
+        Assert.assertEquals(42, root.getNode().executeEvaluated2(null, 42));
+        Assert.assertEquals(42, root.getNode().executeEvaluated3(null, 42));
+        Assert.assertEquals(42, root.getNode().executeEvaluated4(null, 42));
+    }
+
+    @NodeChildren({@NodeChild("exp0")})
+    abstract static class TestEvaluatedGeneration extends ValueNode {
+
+        public abstract Object executeEvaluated1(VirtualFrame frame, Object value);
+
+        public abstract Object executeEvaluated2(VirtualFrame frame, int value);
+
+        public abstract int executeEvaluated3(VirtualFrame frame, Object value) throws UnexpectedResultException;
+
+        public abstract int executeEvaluated4(VirtualFrame frame, int value) throws UnexpectedResultException;
+
+        @Specialization
+        int call(int exp0) {
+            return exp0;
+        }
+    }
+
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java	Thu Aug 29 17:17:35 2013 +0200
@@ -47,12 +47,13 @@
         List<ParameterSpec> requiredSpecs = new ArrayList<>(spec.getRequired());
         spec.getRequired().clear();
 
+        List<TypeMirror> allowedTypes = getNode().getTypeSystem().getPrimitiveTypeMirrors();
         for (ParameterSpec originalSpec : requiredSpecs) {
-            spec.addRequired(new ParameterSpec(originalSpec, Arrays.asList(getNode().getTypeSystem().getGenericType())));
+            spec.addRequired(new ParameterSpec(originalSpec, allowedTypes));
         }
 
         spec.setVariableRequiredArguments(true);
-        ParameterSpec other = new ParameterSpec("other", Arrays.asList(getNode().getTypeSystem().getGenericType()));
+        ParameterSpec other = new ParameterSpec("other", allowedTypes);
         other.setCardinality(Cardinality.MANY);
         other.setSignature(true);
         other.setIndexed(true);
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Thu Aug 29 17:17:35 2013 +0200
@@ -324,223 +324,6 @@
         body.string(".").startCall(methodName);
     }
 
-    private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
-                    CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions, boolean forceElse) {
-
-        NodeData node = targetSpecialization.getNode();
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions);
-        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 targetParameter : guard.getParameters()) {
-                    NodeChildData field = node.findChild(targetParameter.getSpecification().getName());
-                    if (field == null) {
-                        continue;
-                    }
-                    TypeData targetType = targetParameter.getTypeSystemType();
-                    ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName());
-                    if (sourceParameter == null) {
-                        sourceParameter = targetParameter;
-                    }
-                    TypeData sourceType = sourceParameter.getTypeSystemType();
-
-                    if (sourceType.needsCastTo(getContext(), targetType)) {
-                        valuesNeedsCast.add(targetParameter.getLocalName());
-                    }
-                }
-            }
-        }
-
-        int ifCount = 0;
-
-        if (implicitGuards != null) {
-            builder.startIf();
-            builder.tree(implicitGuards);
-            builder.end();
-            builder.startBlock();
-            ifCount++;
-        }
-
-        builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization));
-
-        if (explicitGuards != null) {
-            builder.startIf();
-            builder.tree(explicitGuards);
-            builder.end();
-            builder.startBlock();
-            ifCount++;
-        }
-
-        if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
-            builder.startIf();
-            builder.string(conditionPrefix);
-            builder.end().startBlock();
-            ifCount++;
-        }
-
-        builder.tree(guardedStatements);
-
-        builder.end(ifCount);
-        if (elseStatements != null && (forceElse || ifCount > 0)) {
-            builder.tree(elseStatements);
-        }
-        return builder.getRoot();
-    }
-
-    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
-        if (guardedSpecialization.getGuards().size() > 0) {
-            // Explicitly specified guards
-            for (GuardData guard : guardedSpecialization.getGuards()) {
-                builder.string(andOperator);
-                if (guard.isNegated()) {
-                    builder.string("!");
-                }
-                builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null));
-                andOperator = " && ";
-            }
-        }
-
-        return builder.isEmpty() ? null : builder.getRoot();
-    }
-
-    private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        // Implict guards based on method signature
-        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
-            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
-
-            if (valueParam == null) {
-                /*
-                 * If used inside a function execute method. The value param may not exist. In that
-                 * case it assumes that the value is already converted.
-                 */
-                valueParam = guardedParam;
-            }
-
-            if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
-                continue;
-            }
-
-            CodeTree cast = createCast(parent, field, valueParam, guardedParam.getTypeSystemType());
-            if (cast == null) {
-                continue;
-            }
-            builder.tree(cast);
-        }
-
-        return builder.getRoot();
-    }
-
-    private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        // Implict guards based on method signature
-        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
-
-        if (emitAssumptions) {
-            for (String assumption : guardedSpecialization.getAssumptions()) {
-                builder.string(andOperator);
-                builder.string("this");
-                builder.string(".").string(assumption).string(".isValid()");
-                andOperator = " && ";
-            }
-        }
-
-        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
-            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
-
-            if (valueParam == null) {
-                /*
-                 * If used inside a function execute method. The value param may not exist. In that
-                 * case it assumes that the value is already converted.
-                 */
-                valueParam = guardedParam;
-            }
-
-            CodeTree implicitGuard = createTypeGuard(builder, field, valueParam, guardedParam.getTypeSystemType());
-            if (implicitGuard == null) {
-                continue;
-            }
-
-            builder.string(andOperator);
-            builder.tree(implicitGuard);
-            andOperator = " && ";
-        }
-
-        return builder.isEmpty() ? null : builder.getRoot();
-    }
-
-    private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
-        NodeData node = field.getNodeData();
-
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-        TypeData sourceType = source.getTypeSystemType();
-
-        if (!sourceType.needsCastTo(getContext(), targetType)) {
-            return null;
-        }
-
-        builder.startGroup();
-
-        if (field.isShortCircuit()) {
-            ActualParameter shortCircuit = source.getPreviousParameter();
-            assert shortCircuit != null;
-            builder.string("(");
-            builder.string("!").string(valueName(shortCircuit));
-            builder.string(" || ");
-        }
-
-        startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType));
-        builder.string(valueName(source));
-        builder.end().end(); // call
-
-        if (field.isShortCircuit()) {
-            builder.string(")");
-        }
-
-        builder.end(); // group
-
-        return builder.getRoot();
-    }
-
-    private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
-        NodeData node = field.getNodeData();
-        TypeData sourceType = source.getTypeSystemType();
-
-        if (!sourceType.needsCastTo(getContext(), targetType)) {
-            return null;
-        }
-
-        CodeTree condition = null;
-        if (field.isShortCircuit()) {
-            ActualParameter shortCircuit = source.getPreviousParameter();
-            assert shortCircuit != null;
-            condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
-        }
-
-        CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source)));
-
-        return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value);
-    }
-
     /**
      * <pre>
      * variant1 $condition != null
@@ -1444,7 +1227,7 @@
                 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
                     return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar);
                 }
-            }));
+            }, null, false, true));
 
             boolean firstUnreachable = true;
             for (SpecializationData current : node.getSpecializations()) {
@@ -1488,7 +1271,7 @@
                 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
                     return createGenericInvoke(builder, current.getNode().getGenericSpecialization(), current);
                 }
-            }));
+            }, null, false, true));
 
             emitUnreachableSpecializations(builder, node);
 
@@ -1504,39 +1287,47 @@
             }
         }
 
-        private CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState,
-                        final CodeBlock<SpecializationData> guardedblock) {
-            return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Void>() {
-
-                public CodeTree create(CodeTreeBuilder parent, Void value) {
+        protected CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState,
+                        final CodeBlock<SpecializationData> guardedblock, final CodeTree elseBlock, boolean forceElse, final boolean emitAssumptions) {
+            return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Integer>() {
+
+                public CodeTree create(CodeTreeBuilder parent, Integer ifCount) {
                     CodeTreeBuilder builder = parent.create();
 
                     if (group.getSpecialization() != null) {
                         builder.tree(guardedblock.create(builder, group.getSpecialization()));
 
                         assert group.getChildren().isEmpty() : "missed a specialization";
+
                     } else {
                         for (SpecializationGroup childGroup : group.getChildren()) {
-                            builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock));
+                            builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock, null, false, emitAssumptions));
                         }
                     }
 
                     return builder.getRoot();
                 }
-            });
+            }, elseBlock, forceElse, emitAssumptions);
         }
 
-        private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Void> bodyBlock) {
+        private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Integer> bodyBlock, CodeTree elseBlock,
+                        boolean forceElse, boolean emitAssumptions) {
             CodeTreeBuilder builder = parent.create();
 
-            int ifCount = emitGuards(builder, source, group, checkMinimumState);
+            int ifCount = emitGuards(builder, source, group, checkMinimumState, emitAssumptions);
 
             if (isReachableGroup(group, ifCount, checkMinimumState)) {
-                builder.tree(bodyBlock.create(builder, null));
+                builder.tree(bodyBlock.create(builder, ifCount));
             }
 
             builder.end(ifCount);
 
+            if (elseBlock != null) {
+                if (ifCount > 0 || forceElse) {
+                    builder.tree(elseBlock);
+                }
+            }
+
             return builder.getRoot();
         }
 
@@ -1561,7 +1352,7 @@
             return true;
         }
 
-        private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState) {
+        private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, boolean emitAssumptions) {
             NodeData node = source.getNode();
 
             CodeTreeBuilder guardsBuilder = builder.create();
@@ -1601,11 +1392,13 @@
                 }
             }
 
-            for (String assumption : group.getAssumptions()) {
-                guardsBuilder.string(guardsAnd);
-                guardsBuilder.string("this");
-                guardsBuilder.string(".").string(assumption).string(".isValid()");
-                guardsAnd = " && ";
+            if (emitAssumptions) {
+                for (String assumption : group.getAssumptions()) {
+                    guardsBuilder.string(guardsAnd);
+                    guardsBuilder.string("this");
+                    guardsBuilder.string(".").string(assumption).string(".isValid()");
+                    guardsAnd = " && ";
+                }
             }
 
             for (TypeGuard typeGuard : group.getTypeGuards()) {
@@ -1697,7 +1490,7 @@
                         sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName());
                     }
 
-                    if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), requiredType)) {
+                    if (Utils.needsCastTo(getContext(), sourceParameter.getType(), requiredType.getPrimitiveType())) {
                         return true;
                     }
                 }
@@ -1707,6 +1500,60 @@
             return false;
         }
 
+        private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
+            NodeData node = field.getNodeData();
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            TypeData sourceType = source.getTypeSystemType();
+
+            if (!sourceType.needsCastTo(getContext(), targetType)) {
+                return null;
+            }
+
+            builder.startGroup();
+
+            if (field.isShortCircuit()) {
+                ActualParameter shortCircuit = source.getPreviousParameter();
+                assert shortCircuit != null;
+                builder.string("(");
+                builder.string("!").string(valueName(shortCircuit));
+                builder.string(" || ");
+            }
+
+            startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType));
+            builder.string(valueName(source));
+            builder.end().end(); // call
+
+            if (field.isShortCircuit()) {
+                builder.string(")");
+            }
+
+            builder.end(); // group
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
+            NodeData node = field.getNodeData();
+            TypeData sourceType = source.getTypeSystemType();
+
+            if (!sourceType.needsCastTo(getContext(), targetType)) {
+                return null;
+            }
+
+            CodeTree condition = null;
+            if (field.isShortCircuit()) {
+                ActualParameter shortCircuit = source.getPreviousParameter();
+                assert shortCircuit != null;
+                condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
+            }
+
+            CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source)));
+
+            return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value);
+        }
+
         private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) {
             CodeTreeBuilder builder = parent.create();
             builder.string(prefix);
@@ -1918,9 +1765,15 @@
                 }
             }
 
+            // execute names are enforced no cast
+            String[] executeParameterNames = new String[executeParameters.size()];
+            for (int i = 0; i < executeParameterNames.length; i++) {
+                executeParameterNames[i] = valueName(executeParameters.get(i));
+            }
+
             builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true));
 
-            CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null);
+            CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames);
             if (needsTry) {
                 if (!returnVoid) {
                     builder.declaration(primaryType.getPrimitiveType(), "value");
@@ -2011,6 +1864,7 @@
                 ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
 
                 String targetVariableName = valueName(targetParameter);
+
                 CodeTree executionExpression = null;
                 if ((sourceParameter != null && cast) || sourceParameter != null) {
                     TypeData sourceType = sourceParameter.getTypeSystemType();
@@ -2020,7 +1874,7 @@
                         }
                         builder.startStatement();
                         builder.type(targetParameter.getType()).string(" ");
-                        builder.string(valueName(targetParameter)).string(" = ");
+                        builder.string(targetVariableName).string(" = ");
                         builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)));
                         builder.end();
                         continue;
@@ -2055,10 +1909,6 @@
                 cast = true;
             }
 
-            if (specialization.isGeneric() && unexpected) {
-                throw new AssertionError("Generic has unexpected parameters. " + specialization.toString());
-            }
-
             builder.startStatement();
 
             if (!shortCircuit) {
@@ -2459,7 +2309,7 @@
         protected void createCachedExecuteMethods(SpecializationData specialization) {
             NodeData node = specialization.getNode();
             CodeTypeElement clazz = getElement();
-            for (SpecializationData polymorphic : node.getPolymorphicSpecializations()) {
+            for (final SpecializationData polymorphic : node.getPolymorphicSpecializations()) {
                 if (!specialization.getSignature().isCompatibleTo(polymorphic.getSignature())) {
                     continue;
                 }
@@ -2480,10 +2330,14 @@
                     elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic));
                     addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true);
                     elseBuilder.end().end();
-                    CodeTreeBuilder execute = new CodeTreeBuilder(builder);
-                    execute.tree(createGenericInvoke(builder, polymorphic, specialization));
-                    boolean forceElse = !specialization.getExceptions().isEmpty();
-                    builder.tree(createGuardAndCast(builder, null, polymorphic, specialization, true, execute.getRoot(), elseBuilder.getRoot(), true, forceElse));
+
+                    boolean forceElse = specialization.getExceptions().size() > 0;
+                    builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() {
+
+                        public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
+                            return createGenericInvoke(b, polymorphic, current);
+                        }
+                    }, elseBuilder.getRoot(), forceElse, true));
                 }
                 clazz.add(executeMethod);
             }
@@ -2622,7 +2476,7 @@
             return filteredTypes;
         }
 
-        private CodeTree createFunctionalExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable) {
+        private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) {
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
             if (specialization.isUninitialized()) {
                 builder.tree(createDeoptimize(builder));
@@ -2630,8 +2484,6 @@
 
             builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false));
 
-            CodeTree executeNode = createExecute(builder, executable, specialization);
-
             CodeTree returnSpecialized = null;
 
             if (specialization.findNextSpecialization() != null) {
@@ -2641,7 +2493,12 @@
                 returnSpecialized = returnBuilder.getRoot();
             }
 
-            builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false, false));
+            builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() {
+
+                public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
+                    return createExecute(b, executable, specialization);
+                }
+            }, returnSpecialized, false, false));
 
             return builder.getRoot();
         }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java	Thu Aug 29 17:17:35 2013 +0200
@@ -258,6 +258,10 @@
         return false;
     }
 
+    public static SpecializationGroup create(SpecializationData specialization) {
+        return new SpecializationGroup(specialization);
+    }
+
     public static SpecializationGroup create(List<SpecializationData> specializations) {
         List<SpecializationGroup> groups = new ArrayList<>();
         for (SpecializationData specialization : specializations) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java	Thu Aug 29 16:23:14 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java	Thu Aug 29 17:17:35 2013 +0200
@@ -193,10 +193,50 @@
         return b.toString();
     }
 
+    /*
+     * Parameter parsing tries to parse required arguments starting from offset 0 with increasing
+     * offset until it finds a signature end that matches the required specification. If there is no
+     * end matching the required arguments, parsing fails. Parameters prior to the parsed required
+     * ones are cut and used to parse the optional parameters. All those remaining parameters must
+     * be consumed otherwise its an error.
+     */
     private List<ActualParameter> parseParameters(MethodSpec spec, List<TypeMirror> parameterTypes) {
+        List<TypeMirror> implicitTypes = spec.getImplicitRequiredTypes();
+
+        int offset = -1;
+        List<ActualParameter> parsedRequired = null;
+        ConsumableListIterator<TypeMirror> types = null;
+        while (parsedRequired == null && offset < parameterTypes.size()) {
+            offset++;
+            types = new ConsumableListIterator<>(new ArrayList<>(implicitTypes));
+            types.data.addAll(parameterTypes.subList(offset, parameterTypes.size()));
+            parsedRequired = parseParametersRequired(spec, types);
+        }
+
+        if (parsedRequired == null && offset >= 0) {
+            return null;
+        }
+
+        List<TypeMirror> potentialOptionals;
+        if (offset == -1) {
+            potentialOptionals = parameterTypes;
+        } else {
+            potentialOptionals = parameterTypes.subList(0, offset);
+        }
+        types = new ConsumableListIterator<>(potentialOptionals);
+        List<ActualParameter> parsedOptionals = parseParametersOptional(spec, types);
+        if (parsedOptionals == null) {
+            return null;
+        }
+
+        List<ActualParameter> finalParameters = new ArrayList<>();
+        finalParameters.addAll(parsedOptionals);
+        finalParameters.addAll(parsedRequired);
+        return finalParameters;
+    }
+
+    private List<ActualParameter> parseParametersOptional(MethodSpec spec, ConsumableListIterator<TypeMirror> types) {
         List<ActualParameter> parsedParams = new ArrayList<>();
-        ConsumableListIterator<TypeMirror> types = new ConsumableListIterator<>(parameterTypes);
-
         // parse optional parameters
         ConsumableListIterator<ParameterSpec> optionals = new ConsumableListIterator<>(spec.getOptional());
         for (TypeMirror type : types) {
@@ -217,10 +257,14 @@
                 break;
             }
         }
+        if (types.getIndex() <= types.data.size() - 1) {
+            return null;
+        }
+        return parsedParams;
+    }
 
-        List<TypeMirror> typesWithImplicit = new ArrayList<>(spec.getImplicitRequiredTypes());
-        typesWithImplicit.addAll(types.toList());
-        types = new ConsumableListIterator<>(typesWithImplicit);
+    private List<ActualParameter> parseParametersRequired(MethodSpec spec, ConsumableListIterator<TypeMirror> types) {
+        List<ActualParameter> parsedParams = new ArrayList<>();
 
         int specificationParameterIndex = 0;
         ConsumableListIterator<ParameterSpec> required = new ConsumableListIterator<>(spec.getRequired());
@@ -263,8 +307,6 @@
             // additional specifications -> error
             return null;
         }
-
-        // success!
         return parsedParams;
     }