Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java @ 11442:2868b55001d4
Truffle-DSL: fixed specializationg grouping failed with guards using base types.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Wed, 28 Aug 2013 01:45:13 +0200 |
parents | 7fc3e1fb3965 |
children | b33783cbd8ce |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Aug 27 23:06:24 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Wed Aug 28 01:45:13 2013 +0200 @@ -24,6 +24,10 @@ import java.util.*; +import javax.lang.model.type.*; + +import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; import com.oracle.truffle.dsl.processor.typesystem.*; @@ -64,6 +68,15 @@ updateChildren(children); } + public List<TypeGuard> getAllGuards() { + List<TypeGuard> collectedGuards = new ArrayList<>(); + collectedGuards.addAll(typeGuards); + if (parent != null) { + collectedGuards.addAll(parent.getAllGuards()); + } + return collectedGuards; + } + public TypeGuard findTypeGuard(int signatureIndex) { for (TypeGuard guard : typeGuards) { if (guard.getSignatureIndex() == signatureIndex) { @@ -73,15 +86,34 @@ return null; } - public GuardData getElseConnectableGuard() { + public List<GuardData> getElseConnectableGuards() { if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) { - return null; + return Collections.emptyList(); + } + + if (getGuards().isEmpty()) { + return Collections.emptyList(); } - SpecializationGroup previousGroup = getPreviousGroup(); - if (previousGroup != null && getGuards().size() >= 1 && previousGroup.getGuards().size() == 1) { - GuardData guard = getGuards().get(0); - GuardData previousGuard = previousGroup.getGuards().get(0); + + List<GuardData> elseConnectableGuards = new ArrayList<>(); + int guardIndex = 0; + while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { + elseConnectableGuards.add(getGuards().get(guardIndex)); + guardIndex++; + } + return elseConnectableGuards; + } + + private GuardData findNegatedGuardInPrevious(GuardData guard) { + SpecializationGroup previous = this; + while ((previous = previous.getPreviousGroup()) != null) { + List<GuardData> elseConnectedGuards = previous.getElseConnectableGuards(); + + if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { + return null; + } + GuardData previousGuard = previous.getGuards().get(elseConnectedGuards.size()); if (guard.getMethod().equals(previousGuard.getMethod())) { assert guard.isNegated() != previousGuard.isNegated(); return guard; @@ -169,6 +201,30 @@ guardMatches.add(guard); } + // check for guards for required type casts + for (Iterator<GuardData> iterator = guardMatches.iterator(); iterator.hasNext();) { + GuardData guardMatch = iterator.next(); + + List<TypeMirror> guardTypes = TemplateMethod.getSignatureTypes(guardMatch.getParameters()); + for (int i = 0; i < guardTypes.size(); i++) { + TypeMirror guardType = guardTypes.get(i); + int signatureIndex = i + 1; + + // object guards can be safely moved up + if (Utils.isObject(guardType)) { + continue; + } + + // signature index required for moving up guards + if (containsIndex(typeGuardsMatches, signatureIndex) || (first.getParent() != null && first.getParent().containsTypeGuardIndex(signatureIndex))) { + continue; + } + + iterator.remove(); + break; + } + } + if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) { return null; } @@ -183,6 +239,25 @@ return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches); } + private boolean containsTypeGuardIndex(int index) { + if (containsIndex(typeGuards, index)) { + return true; + } + if (parent != null) { + return parent.containsTypeGuardIndex(index); + } + return false; + } + + private static boolean containsIndex(List<TypeGuard> typeGuards, int signatureIndex) { + for (TypeGuard guard : typeGuards) { + if (guard.signatureIndex == signatureIndex) { + return true; + } + } + return false; + } + public static SpecializationGroup create(List<SpecializationData> specializations) { List<SpecializationGroup> groups = new ArrayList<>(); for (SpecializationData specialization : specializations) {