changeset 8592:a80bf36c6a1e

Refactor to shared template method signature comparison.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Apr 2013 11:52:38 +0200
parents 5c58da5b8233
children 54e227b2e199
files graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java
diffstat 19 files changed, 172 insertions(+), 188 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java	Mon Apr 01 11:52:38 2013 +0200
@@ -83,7 +83,7 @@
         }
 
         @Override
-        Object execute() {
+        public Object execute() {
             return arguments[index];
         }
 
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java	Mon Apr 01 11:52:38 2013 +0200
@@ -50,7 +50,6 @@
         }
 
         abstract Object execute();
-
     }
 
     @TypeSystemReference(SimpleTypes.class)
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -47,10 +47,10 @@
         types.addAll(getNode().getTypeSystem().getPrimitiveTypeMirrors());
         types.add(getContext().getType(void.class));
 
-        ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types, false, Cardinality.ONE);
+        ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types, false, Cardinality.ONE, true);
 
         List<ParameterSpec> parameters = new ArrayList<>();
-        parameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true));
+        parameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true, false));
         return new MethodSpec(new ArrayList<TypeMirror>(), returnTypeSpec, parameters);
     }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -51,7 +51,7 @@
         for (ExecutableTypeData type : execTypes) {
             types.add(type.getType().getPrimitiveType());
         }
-        return new ParameterSpec(valueName, types, false, Cardinality.ONE);
+        return new ParameterSpec(valueName, types, false, Cardinality.ONE, true);
     }
 
     @Override
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -43,7 +43,7 @@
     }
 
     protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, boolean optional) {
-        return new ParameterSpec(valueName, nodeData, optional, Cardinality.ONE);
+        return new ParameterSpec(valueName, nodeData, optional, Cardinality.ONE, true);
     }
 
     protected ParameterSpec createReturnParameterSpec() {
@@ -60,7 +60,7 @@
         List<ParameterSpec> defaultParameters = new ArrayList<>();
 
         if (getNode().supportsFrame()) {
-            defaultParameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true));
+            defaultParameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true, false));
         }
 
         TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
@@ -73,7 +73,7 @@
 
         for (NodeFieldData field : getNode().getFields()) {
             if (field.getKind() == FieldKind.FIELD) {
-                ParameterSpec spec = new ParameterSpec(field.getName(), field.getType(), true);
+                ParameterSpec spec = new ParameterSpec(field.getName(), field.getType(), true, false);
                 spec.setLocal(true);
                 defaultParameters.add(spec);
             }
@@ -97,7 +97,7 @@
                     break;
                 }
 
-                defaultParameters.add(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class), false));
+                defaultParameters.add(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class), false, false));
                 defaultParameters.add(createValueParameterSpec(valueName, field.getNodeData(), false));
             } else {
                 assert false;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Apr 01 11:52:38 2013 +0200
@@ -262,7 +262,7 @@
 
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, valueSpecialization, guardedSpecialization);
-        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization, onSpecialization);
+        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization);
 
         int ifCount = 0;
 
@@ -302,17 +302,15 @@
         return builder.getRoot();
     }
 
-    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization) {
+    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
         if (guardedSpecialization.getGuards().size() > 0) {
             // Explicitly specified guards
-            for (SpecializationGuardData guard : guardedSpecialization.getGuards()) {
-                if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) {
-                    builder.string(andOperator);
-                    builder.tree(createTemplateMethodCall(parent, guard.getGuardDeclaration(), valueSpecialization, guardedSpecialization, null));
-                    andOperator = " && ";
-                }
+            for (GuardData guard : guardedSpecialization.getGuards()) {
+                builder.string(andOperator);
+                builder.tree(createTemplateMethodCall(parent, guard, valueSpecialization, guardedSpecialization, null));
+                andOperator = " && ";
             }
         }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Apr 01 11:52:38 2013 +0200
@@ -187,22 +187,11 @@
 
         methods.addAll(getSpecializationListeners());
         methods.addAll(getExecutableTypes());
-        methods.addAll(getGuards());
         methods.addAll(getShortCircuits());
 
         return methods;
     }
 
-    public List<GuardData> findGuards(String name) {
-        List<GuardData> foundGuards = new ArrayList<>();
-        for (GuardData guardData : getGuards()) {
-            if (guardData.getMethodName().equals(name)) {
-                foundGuards.add(guardData);
-            }
-        }
-        return foundGuards;
-    }
-
     public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) {
         List<ExecutableTypeData> types = findGenericExecutableTypes(context);
         for (ExecutableTypeData availableType : types) {
@@ -312,6 +301,7 @@
         return null;
     }
 
+    @Override
     public TypeSystemData getTypeSystem() {
         return typeSystem;
     }
@@ -334,7 +324,6 @@
         dumpProperty(builder, indent, "fields", getFields());
         dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
         dumpProperty(builder, indent, "specializations", getSpecializations());
-        dumpProperty(builder, indent, "guards", getGuards());
         dumpProperty(builder, indent, "messages", collectMessages());
         if (getDeclaredChildren().size() > 0) {
             builder.append(String.format("\n%s  children = [", indent));
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -186,7 +186,7 @@
         }
 
         for (NodeData splittedNode : nodes) {
-            finalizeSpecializations(splittedNode);
+            finalizeSpecializations(elements, splittedNode);
             verifyNode(splittedNode);
         }
 
@@ -254,7 +254,6 @@
     }
 
     private void parseMethods(final NodeData node, List<Element> elements) {
-        node.setGuards(new GuardParser(context, node, node.getTypeSystem()).parse(elements));
         node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements));
         node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements));
         List<SpecializationData> generics = new GenericParser(context, node).parse(elements);
@@ -267,13 +266,17 @@
         node.setSpecializations(allSpecializations);
     }
 
-    private void finalizeSpecializations(final NodeData node) {
+    private void finalizeSpecializations(List<Element> elements, final NodeData node) {
         List<SpecializationData> specializations = new ArrayList<>(node.getSpecializations());
 
         if (specializations.isEmpty()) {
             return;
         }
 
+        for (SpecializationData specialization : specializations) {
+            matchGuards(elements, specialization);
+        }
+
         List<SpecializationData> generics = new ArrayList<>();
         for (SpecializationData spec : specializations) {
             if (spec.isGeneric()) {
@@ -336,7 +339,7 @@
 
             @Override
             public int compare(SpecializationData o1, SpecializationData o2) {
-                return compareSpecialization(node.getTypeSystem(), o1, o2);
+                return compareSpecialization(o1, o2);
             }
         });
 
@@ -358,6 +361,45 @@
         }
     }
 
+    private void matchGuards(List<Element> elements, SpecializationData specialization) {
+        if (specialization.getGuardDefinitions().isEmpty()) {
+            specialization.setGuards(Collections.<GuardData> emptyList());
+            return;
+        }
+
+        List<GuardData> foundGuards = new ArrayList<>();
+        List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
+        for (String guardDefinition : specialization.getGuardDefinitions()) {
+            GuardParser parser = new GuardParser(context, specialization, guardDefinition);
+            List<GuardData> guards = parser.parse(methods);
+            Collections.sort(guards, new Comparator<GuardData>() {
+
+                @Override
+                public int compare(GuardData o1, GuardData o2) {
+                    int compare = o1.compareBySignature(o2);
+                    if (compare == 0) {
+                        compare = o1.getId().compareTo(o2.getId());
+                    }
+                    if (compare == 0) {
+                        TypeElement enclosingType1 = Utils.findNearestEnclosingType(o1.getMethod());
+                        TypeElement enclosingType2 = Utils.findNearestEnclosingType(o2.getMethod());
+                        compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString());
+                    }
+                    return compare;
+                }
+            });
+            if (!guards.isEmpty()) {
+                foundGuards.add(guards.get(0));
+            } else {
+                // error no guard found
+                specialization.addError("No guard found with with name '%s'.", guardDefinition);
+            }
+        }
+
+        specialization.setGuards(foundGuards);
+
+    }
+
     private static List<String> calculateSpecializationIds(List<SpecializationData> specializations) {
         int lastSize = -1;
         List<List<String>> signatureChunks = new ArrayList<>();
@@ -927,14 +969,12 @@
     }
 
     private static void verifySpecializationOrder(NodeData node) {
-        TypeSystemData typeSystem = node.getTypeSystem();
         List<SpecializationData> specializations = node.getSpecializations();
-
         for (int i = 0; i < specializations.size(); i++) {
             SpecializationData m1 = specializations.get(i);
             for (int j = i + 1; j < specializations.size(); j++) {
                 SpecializationData m2 = specializations.get(j);
-                int inferredOrder = compareSpecializationWithoutOrder(typeSystem, m1, m2);
+                int inferredOrder = compareSpecialization(m1, m2);
 
                 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
                     int specOrder = m1.getOrder() - m2.getOrder();
@@ -974,70 +1014,24 @@
         }
     }
 
-    private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
-        if (m1 == m2) {
-            return 0;
-        }
-        int result = compareSpecializationWithoutOrder(typeSystem, m1, m2);
-        if (result == 0) {
-            if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
-                return m1.getOrder() - m2.getOrder();
-            }
-        }
-        return result;
-    }
-
-    private static int compareSpecializationWithoutOrder(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
+    private static int compareSpecialization(SpecializationData m1, SpecializationData m2) {
         if (m1 == m2) {
             return 0;
         }
 
         if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
             return m1.getOrder() - m2.getOrder();
-        } else if (m1.isUninitialized() && !m2.isUninitialized()) {
-            return -1;
-        } else if (!m1.isUninitialized() && m2.isUninitialized()) {
-            return 1;
-        } else if (m1.isGeneric() && !m2.isGeneric()) {
-            return 1;
-        } else if (!m1.isGeneric() && m2.isGeneric()) {
-            return -1;
+        } else if (m1.isUninitialized() ^ m2.isUninitialized()) {
+            return m1.isUninitialized() ? -1 : 1;
+        } else if (m1.isGeneric() ^ m2.isGeneric()) {
+            return m1.isGeneric() ? 1 : -1;
         }
 
         if (m1.getTemplate() != m2.getTemplate()) {
             throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
         }
 
-        int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType());
-
-        for (ActualParameter p1 : m1.getParameters()) {
-            NodeFieldData field = m1.getNode().findField(p1.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ActualParameter p2 = m2.findParameter(p1.getLocalName());
-
-            if (p1 != null && p2 != null && !Utils.typeEquals(p1.getActualType(), p2.getActualType())) {
-                int typeResult = compareActualParameter(typeSystem, p1, p2);
-                if (result == 0) {
-                    result = typeResult;
-                } else if (Math.signum(result) != Math.signum(typeResult)) {
-                    // We cannot define an order.
-                    return 0;
-                }
-            }
-        }
-        return result;
-    }
-
-    private static int compareActualParameter(TypeSystemData typeSystem, ActualParameter p1, ActualParameter p2) {
-        int index1 = typeSystem.findType(p1.getActualType());
-        int index2 = typeSystem.findType(p2.getActualType());
-
-        assert index1 != index2;
-        assert !(index1 == -1 ^ index2 == -1);
-
-        return index1 - index2;
+        return m1.compareBySignature(m2);
     }
 
     @Override
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -54,7 +54,7 @@
 
     @Override
     protected ParameterSpec createReturnParameterSpec() {
-        return new ParameterSpec("has", getContext().getType(boolean.class), false);
+        return new ParameterSpec("has", getContext().getType(boolean.class), false, false);
     }
 
     @Override
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Mon Apr 01 11:52:38 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.truffle.codegen.processor.*;
 import com.oracle.truffle.codegen.processor.node.NodeFieldData.*;
 import com.oracle.truffle.codegen.processor.template.*;
+import com.oracle.truffle.codegen.processor.typesystem.*;
 
 public class SpecializationData extends TemplateMethod {
 
@@ -35,7 +36,8 @@
     private final boolean generic;
     private final boolean uninitialized;
     private final List<SpecializationThrowsData> exceptions;
-    private List<SpecializationGuardData> guards;
+    private List<String> guardDefinitions = Collections.emptyList();
+    private List<GuardData> guards;
     private List<ShortCircuitData> shortCircuits;
     private boolean useSpecializationsForGeneric = true;
     private NodeData node;
@@ -101,10 +103,14 @@
         this.node = node;
     }
 
-    public void setGuards(List<SpecializationGuardData> guards) {
+    public void setGuards(List<GuardData> guards) {
         this.guards = guards;
     }
 
+    public void setGuardDefinitions(List<String> guardDefinitions) {
+        this.guardDefinitions = guardDefinitions;
+    }
+
     public int getOrder() {
         return order;
     }
@@ -121,7 +127,11 @@
         return exceptions;
     }
 
-    public List<SpecializationGuardData> getGuards() {
+    public List<String> getGuardDefinitions() {
+        return guardDefinitions;
+    }
+
+    public List<GuardData> getGuards() {
         return guards;
     }
 
@@ -152,12 +162,7 @@
     }
 
     public boolean hasDynamicGuards() {
-        for (SpecializationGuardData guard : getGuards()) {
-            if (guard.isOnExecution()) {
-                return true;
-            }
-        }
-        return false;
+        return !getGuards().isEmpty();
     }
 
 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -43,7 +43,7 @@
 
     @Override
     protected ParameterSpec createReturnParameterSpec() {
-        return new ParameterSpec("void", getContext().getType(void.class), false);
+        return new ParameterSpec("void", getContext().getType(void.class), false, false);
     }
 
     @Override
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -31,7 +31,6 @@
 import com.oracle.truffle.api.codegen.*;
 import com.oracle.truffle.codegen.processor.*;
 import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
 
 public class SpecializationMethodParser extends MethodParser<SpecializationData> {
 
@@ -54,7 +53,7 @@
         return Specialization.class;
     }
 
-    private SpecializationData parseSpecialization(TemplateMethod method) {
+    private static SpecializationData parseSpecialization(TemplateMethod method) {
         int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order");
         if (order < 0 && order != Specialization.DEFAULT_ORDER) {
             method.addError("Invalid order attribute %d. The value must be >= 0 or the default value.");
@@ -80,76 +79,10 @@
             }
         });
         SpecializationData specialization = new SpecializationData(method, order, exceptionData);
-        AnnotationValue guardsValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "guards");
         List<String> guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
-        List<SpecializationGuardData> guardData = new ArrayList<>(guardDefs.size());
-        for (int i = 0; i < guardDefs.size(); i++) {
-            String guardMethod = guardDefs.get(i);
-
-            SpecializationGuardData assignedGuard = new SpecializationGuardData(specialization, guardsValue, guardMethod, true, true);
-
-            guardData.add(assignedGuard);
-
-            GuardData compatibleGuard = matchSpecializationGuard(specialization, assignedGuard);
-            if (compatibleGuard != null) {
-                assignedGuard.setGuardDeclaration(compatibleGuard);
-            }
-        }
-
-        specialization.setGuards(guardData);
+        specialization.setGuardDefinitions(guardDefs);
 
         return specialization;
     }
 
-    private GuardData matchSpecializationGuard(SpecializationData specialization, SpecializationGuardData specializationGuard) {
-        List<GuardData> foundGuards = getNode().findGuards(specializationGuard.getGuardMethod());
-
-        GuardData compatibleGuard = null;
-        for (GuardData guardData : foundGuards) {
-            if (isGuardCompatible(specialization, guardData)) {
-                compatibleGuard = guardData;
-                break;
-            }
-        }
-
-        if (compatibleGuard == null) {
-            ParameterSpec returnTypeSpec = new ParameterSpec("returnValue", getContext().getType(boolean.class), false);
-            List<ParameterSpec> expectedParameterSpecs = new ArrayList<>();
-
-            for (ActualParameter param : specialization.getParameters()) {
-                ParameterSpec spec = param.getSpecification();
-                expectedParameterSpecs.add(new ParameterSpec(spec.getName(), param.getActualType(), false));
-            }
-            List<TypeDef> typeDefs = createTypeDefinitions(returnTypeSpec, expectedParameterSpecs);
-            String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs, typeDefs);
-            specializationGuard.addError("No guard with signature '%s' found in type system.", expectedSignature);
-        }
-
-        return compatibleGuard;
-    }
-
-    private static boolean isGuardCompatible(SpecializationData specialization, GuardData guard) {
-        Iterator<ActualParameter> guardParameters = guard.getParameters().iterator();
-        for (ActualParameter param : specialization.getParameters()) {
-            if (param.getSpecification().isOptional()) {
-                continue;
-            }
-            if (!guardParameters.hasNext()) {
-                return false;
-            }
-            ActualParameter guardParam = guardParameters.next();
-            if (!Utils.typeEquals(guardParam.getActualType(), param.getActualType()) && !guardParam.getSpecification().isOptional()) {
-                return false;
-            }
-        }
-        while (guardParameters.hasNext()) {
-            ActualParameter param = guardParameters.next();
-            if (!param.getSpecification().isOptional()) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Mon Apr 01 11:52:38 2013 +0200
@@ -38,37 +38,43 @@
 
     private final String name;
     private final List<TypeMirror> allowedTypes;
+    private Cardinality cardinality;
     private final boolean optional;
-    private Cardinality cardinality;
+    private final boolean signature;
     private boolean indexed;
     private boolean local;
 
-    public ParameterSpec(String name, List<TypeMirror> allowedTypes, boolean optional, Cardinality cardinality) {
+    public ParameterSpec(String name, List<TypeMirror> allowedTypes, boolean optional, Cardinality cardinality, boolean signature) {
         this.allowedTypes = allowedTypes;
         this.name = name;
         this.optional = optional;
         this.cardinality = cardinality;
+        this.signature = signature;
     }
 
     /** Type constructor. */
-    public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional) {
-        this(name, Arrays.asList(singleFixedType), optional, Cardinality.ONE);
+    public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional, boolean signature) {
+        this(name, Arrays.asList(singleFixedType), optional, Cardinality.ONE, signature);
     }
 
     /** Type system value constructor. */
-    public ParameterSpec(String name, TypeSystemData typeSystem, boolean optional, Cardinality cardinality) {
-        this(name, typeSystem.getPrimitiveTypeMirrors(), optional, cardinality);
+    public ParameterSpec(String name, TypeSystemData typeSystem, boolean optional, Cardinality cardinality, boolean signature) {
+        this(name, typeSystem.getPrimitiveTypeMirrors(), optional, cardinality, signature);
     }
 
     /** Node value constructor. */
-    public ParameterSpec(String name, NodeData nodeData, boolean optional, Cardinality cardinality) {
-        this(name, nodeTypeMirrors(nodeData), optional, cardinality);
+    public ParameterSpec(String name, NodeData nodeData, boolean optional, Cardinality cardinality, boolean signature) {
+        this(name, nodeTypeMirrors(nodeData), optional, cardinality, signature);
     }
 
     public void setLocal(boolean local) {
         this.local = local;
     }
 
+    public boolean isSignature() {
+        return signature;
+    }
+
     public boolean isLocal() {
         return local;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java	Mon Apr 01 11:52:38 2013 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.truffle.codegen.processor.*;
 import com.oracle.truffle.codegen.processor.api.element.*;
+import com.oracle.truffle.codegen.processor.typesystem.*;
 
 public abstract class Template extends MessageContainer {
 
@@ -43,6 +44,8 @@
         this.annotation = annotation;
     }
 
+    public abstract TypeSystemData getTypeSystem();
+
     @Override
     public Element getMessageElement() {
         return templateType;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Mon Apr 01 11:52:38 2013 +0200
@@ -28,6 +28,7 @@
 import javax.lang.model.type.*;
 
 import com.oracle.truffle.codegen.processor.*;
+import com.oracle.truffle.codegen.processor.typesystem.*;
 
 public class TemplateMethod extends MessageContainer {
 
@@ -161,4 +162,51 @@
         }
         return prev;
     }
+
+    public List<TypeData> getSignature(TypeSystemData typeSystem) {
+        List<TypeData> types = new ArrayList<>();
+        for (ActualParameter parameter : getReturnTypeAndParameters()) {
+            if (!parameter.getSpecification().isSignature()) {
+                continue;
+            }
+            TypeData typeData = parameter.getActualTypeData(typeSystem);
+            if (typeData != null) {
+                types.add(typeData);
+            }
+        }
+        return types;
+    }
+
+    public int compareBySignature(TemplateMethod compareMethod) {
+        TypeSystemData typeSystem = getTemplate().getTypeSystem();
+        if (typeSystem != compareMethod.getTemplate().getTypeSystem()) {
+            throw new IllegalStateException("Cannot compare two methods with different type systems.");
+        }
+
+        List<TypeData> signature1 = getSignature(typeSystem);
+        List<TypeData> signature2 = compareMethod.getSignature(typeSystem);
+        if (signature1.size() != signature2.size()) {
+            return signature1.size() - signature2.size();
+        }
+
+        int result = 0;
+        for (int i = 0; i < signature1.size(); i++) {
+            int typeResult = compareActualParameter(typeSystem, signature1.get(i), signature2.get(i));
+            if (result == 0) {
+                result = typeResult;
+            } else if (Math.signum(result) != Math.signum(typeResult)) {
+                // We cannot define an order.
+                return 0;
+            }
+        }
+
+        return result;
+    }
+
+    private static int compareActualParameter(TypeSystemData typeSystem, TypeData t1, TypeData t2) {
+        int index1 = typeSystem.findType(t1);
+        int index2 = typeSystem.findType(t2);
+        return index1 - index2;
+    }
+
 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -29,16 +29,18 @@
 import javax.lang.model.type.*;
 
 import com.oracle.truffle.codegen.processor.*;
+import com.oracle.truffle.codegen.processor.node.*;
 import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality;
 
 public class GuardParser extends TemplateMethodParser<Template, GuardData> {
 
-    private final TypeSystemData typeSystem;
+    private final SpecializationData specialization;
+    private final String guardName;
 
-    public GuardParser(ProcessorContext context, Template template, TypeSystemData typeSystem) {
-        super(context, template);
-        this.typeSystem = typeSystem;
+    public GuardParser(ProcessorContext context, SpecializationData specialization, String guardName) {
+        super(context, specialization.getNode());
+        this.specialization = specialization;
+        this.guardName = guardName;
         setEmitErrors(false);
         setParseNullOnError(false);
     }
@@ -46,14 +48,16 @@
     @Override
     public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
         List<ParameterSpec> specs = new ArrayList<>();
-        specs.add(new ParameterSpec("valueN", typeSystem, false, Cardinality.MULTIPLE));
-        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false);
+        for (ActualParameter parameter : specialization.getParameters()) {
+            specs.add(new ParameterSpec(parameter.getSpecification().getName(), parameter.getActualType(), true, true));
+        }
+        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false, false);
         return new MethodSpec(Collections.<TypeMirror> emptyList(), returnTypeSpec, specs);
     }
 
     @Override
     public boolean isParsable(ExecutableElement method) {
-        return true;
+        return method.getSimpleName().toString().equals(guardName);
     }
 
     @Override
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -46,8 +46,8 @@
             return null;
         }
         List<ParameterSpec> specs = new ArrayList<>();
-        specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE));
-        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetType.getPrimitiveType(), false);
+        specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE, true));
+        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetType.getPrimitiveType(), false, true);
         MethodSpec spec = new MethodSpec(Collections.<TypeMirror> emptyList(), returnTypeSpec, specs);
         return spec;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java	Mon Apr 01 11:52:38 2013 +0200
@@ -46,8 +46,8 @@
             return null;
         }
         List<ParameterSpec> specs = new ArrayList<>();
-        specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE));
-        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false);
+        specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE, true));
+        ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false, true);
         MethodSpec spec = new MethodSpec(Collections.<TypeMirror> emptyList(), returnTypeSpec, specs);
         return spec;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Fri Mar 29 21:39:54 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Mon Apr 01 11:52:38 2013 +0200
@@ -43,6 +43,11 @@
         super(templateType, null, annotation);
     }
 
+    @Override
+    public TypeSystemData getTypeSystem() {
+        return this;
+    }
+
     void setTypes(List<TypeData> types) {
         this.types = types;
         if (types != null) {