diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java @ 11201:7fc3e1fb3965

Truffle-DSL: specialization group fixes.
author Christian Humer <christian.humer@gmail.com>
date Mon, 05 Aug 2013 19:50:34 +0200
parents 4f52b08bd2f9
children 2868b55001d4
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java	Mon Aug 05 19:48:15 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java	Mon Aug 05 19:50:34 2013 +0200
@@ -34,7 +34,7 @@
 public final class SpecializationGroup {
 
     private final List<String> assumptions;
-    private final List<TypeData> typeGuards;
+    private final List<TypeGuard> typeGuards;
     private final List<GuardData> guards;
 
     private final SpecializationData specialization;
@@ -51,12 +51,12 @@
         this.assumptions.addAll(data.getAssumptions());
         Signature sig = data.getSignature();
         for (int i = 1; i < sig.size(); i++) {
-            typeGuards.add(sig.get(i));
+            typeGuards.add(new TypeGuard(sig.get(i), i - 1));
         }
         this.guards.addAll(data.getGuards());
     }
 
-    public SpecializationGroup(List<SpecializationGroup> children, List<String> assumptionMatches, List<TypeData> typeGuardsMatches, List<GuardData> guardMatches) {
+    public SpecializationGroup(List<SpecializationGroup> children, List<String> assumptionMatches, List<TypeGuard> typeGuardsMatches, List<GuardData> guardMatches) {
         this.assumptions = assumptionMatches;
         this.typeGuards = typeGuardsMatches;
         this.guards = guardMatches;
@@ -64,6 +64,32 @@
         updateChildren(children);
     }
 
+    public TypeGuard findTypeGuard(int signatureIndex) {
+        for (TypeGuard guard : typeGuards) {
+            if (guard.getSignatureIndex() == signatureIndex) {
+                return guard;
+            }
+        }
+        return null;
+    }
+
+    public GuardData getElseConnectableGuard() {
+        if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) {
+            return null;
+        }
+        SpecializationGroup previousGroup = getPreviousGroup();
+        if (previousGroup != null && getGuards().size() >= 1 && previousGroup.getGuards().size() == 1) {
+            GuardData guard = getGuards().get(0);
+            GuardData previousGuard = previousGroup.getGuards().get(0);
+
+            if (guard.getMethod().equals(previousGuard.getMethod())) {
+                assert guard.isNegated() != previousGuard.isNegated();
+                return guard;
+            }
+        }
+        return null;
+    }
+
     private void updateChildren(List<SpecializationGroup> childs) {
         if (!children.isEmpty()) {
             children.clear();
@@ -74,14 +100,6 @@
         }
     }
 
-    public int getTypeGuardOffset() {
-        return (parent != null ? parent.getTypeGuardOffsetRec() : 0);
-    }
-
-    private int getTypeGuardOffsetRec() {
-        return typeGuards.size() + (parent != null ? parent.getTypeGuardOffsetRec() : 0);
-    }
-
     public SpecializationGroup getParent() {
         return parent;
     }
@@ -90,7 +108,7 @@
         return assumptions;
     }
 
-    public List<TypeData> getTypeGuards() {
+    public List<TypeGuard> getTypeGuards() {
         return typeGuards;
     }
 
@@ -115,7 +133,7 @@
         }
 
         List<String> assumptionMatches = new ArrayList<>();
-        List<TypeData> typeGuardsMatches = new ArrayList<>();
+        List<TypeGuard> typeGuardsMatches = new ArrayList<>();
         List<GuardData> guardMatches = new ArrayList<>();
 
         SpecializationGroup first = groups.get(0);
@@ -131,19 +149,14 @@
             assumptionMatches.add(assumption);
         }
 
-        int typeGuardIndex = 0;
-        outer: for (TypeData typeGuard : first.typeGuards) {
+        outer: for (TypeGuard typeGuard : first.typeGuards) {
             for (SpecializationGroup other : others) {
-                if (typeGuardIndex >= other.typeGuards.size()) {
-                    break outer;
-                }
-
-                if (!other.typeGuards.get(typeGuardIndex).equals(typeGuard)) {
-                    break outer;
+                if (!other.typeGuards.contains(typeGuard)) {
+                    // type guards can be combined unordered
+                    continue outer;
                 }
             }
             typeGuardsMatches.add(typeGuard);
-            typeGuardIndex++;
         }
 
         outer: for (GuardData guard : first.guards) {
@@ -162,7 +175,7 @@
 
         for (SpecializationGroup group : groups) {
             group.assumptions.removeAll(assumptionMatches);
-            group.typeGuards.subList(0, typeGuardIndex).clear();
+            group.typeGuards.removeAll(typeGuardsMatches);
             group.guards.removeAll(guardMatches);
         }
 
@@ -170,12 +183,12 @@
         return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches);
     }
 
-    public static List<SpecializationGroup> create(List<SpecializationData> specializations) {
+    public static SpecializationGroup create(List<SpecializationData> specializations) {
         List<SpecializationGroup> groups = new ArrayList<>();
         for (SpecializationData specialization : specializations) {
             groups.add(new SpecializationGroup(specialization));
         }
-        return createCombinationalGroups(groups);
+        return new SpecializationGroup(createCombinationalGroups(groups), Collections.<String> emptyList(), Collections.<TypeGuard> emptyList(), Collections.<GuardData> emptyList());
     }
 
     @Override
@@ -238,4 +251,51 @@
             return max;
         }
     }
+
+    public static final class TypeGuard {
+
+        private final int signatureIndex;
+        private final TypeData type;
+
+        public TypeGuard(TypeData type, int signatureIndex) {
+            this.type = type;
+            this.signatureIndex = signatureIndex;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + signatureIndex;
+            result = prime * result + type.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            } else if (obj == null) {
+                return false;
+            } else if (getClass() != obj.getClass()) {
+                return false;
+            }
+
+            TypeGuard other = (TypeGuard) obj;
+            if (signatureIndex != other.signatureIndex) {
+                return false;
+            } else if (!type.equals(other.type)) {
+                return false;
+            }
+            return true;
+        }
+
+        public int getSignatureIndex() {
+            return signatureIndex;
+        }
+
+        public TypeData getType() {
+            return type;
+        }
+    }
 }