Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java @ 16755:bd28da642eea
Truffle-DSL: Several new features implemented:
Implementation of a new code generation layout which shares code between generated nodes.
Declaration order of specializations is now used as specialization order.
Specializations do no longer perform fallthrough on respecialization, they now always respecialize from the first specialization.
Implemented support for contains relations between specializations.
Improved reachability error messages.
Preliminary support for @Implies.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 11 Aug 2014 15:53:05 +0200 |
parents | 25ecb47a6d0e |
children |
comparison
equal
deleted
inserted
replaced
16754:55fd5be68a52 | 16755:bd28da642eea |
---|---|
37 */ | 37 */ |
38 public final class SpecializationGroup { | 38 public final class SpecializationGroup { |
39 | 39 |
40 private final List<String> assumptions; | 40 private final List<String> assumptions; |
41 private final List<TypeGuard> typeGuards; | 41 private final List<TypeGuard> typeGuards; |
42 private final List<GuardData> guards; | 42 private final List<GuardExpression> guards; |
43 | 43 |
44 private final NodeData node; | 44 private final NodeData node; |
45 private final SpecializationData specialization; | 45 private final SpecializationData specialization; |
46 private final List<SpecializationGroup> children = new ArrayList<>(); | 46 private final List<SpecializationGroup> children = new ArrayList<>(); |
47 | 47 |
60 typeGuards.add(new TypeGuard(sig.get(i), i - 1)); | 60 typeGuards.add(new TypeGuard(sig.get(i), i - 1)); |
61 } | 61 } |
62 this.guards.addAll(data.getGuards()); | 62 this.guards.addAll(data.getGuards()); |
63 } | 63 } |
64 | 64 |
65 public SpecializationGroup(List<SpecializationGroup> children, List<String> assumptionMatches, List<TypeGuard> typeGuardsMatches, List<GuardData> guardMatches) { | 65 public SpecializationGroup(List<SpecializationGroup> children, List<String> assumptionMatches, List<TypeGuard> typeGuardsMatches, List<GuardExpression> guardMatches) { |
66 assert !children.isEmpty() : "children must not be empty"; | 66 assert !children.isEmpty() : "children must not be empty"; |
67 this.assumptions = assumptionMatches; | 67 this.assumptions = assumptionMatches; |
68 this.typeGuards = typeGuardsMatches; | 68 this.typeGuards = typeGuardsMatches; |
69 this.guards = guardMatches; | 69 this.guards = guardMatches; |
70 this.node = children.get(0).node; | 70 this.node = children.get(0).node; |
88 } | 88 } |
89 } | 89 } |
90 return null; | 90 return null; |
91 } | 91 } |
92 | 92 |
93 public List<GuardData> findElseConnectableGuards(boolean minimumStateCheck) { | 93 public List<GuardExpression> findElseConnectableGuards() { |
94 if (minimumStateCheck) { | |
95 /* | |
96 * TODO investigate further if we really cannot else connect guards if minimum state is | |
97 * required | |
98 */ | |
99 return Collections.emptyList(); | |
100 } | |
101 if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) { | 94 if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) { |
102 return Collections.emptyList(); | 95 return Collections.emptyList(); |
103 } | 96 } |
104 | 97 |
105 if (getGuards().isEmpty()) { | 98 if (getGuards().isEmpty()) { |
106 return Collections.emptyList(); | 99 return Collections.emptyList(); |
107 } | 100 } |
108 | 101 |
109 List<GuardData> elseConnectableGuards = new ArrayList<>(); | 102 List<GuardExpression> elseConnectableGuards = new ArrayList<>(); |
110 int guardIndex = 0; | 103 int guardIndex = 0; |
111 while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex), minimumStateCheck) != null) { | 104 while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { |
112 elseConnectableGuards.add(getGuards().get(guardIndex)); | 105 elseConnectableGuards.add(getGuards().get(guardIndex)); |
113 guardIndex++; | 106 guardIndex++; |
114 } | 107 } |
115 | 108 |
116 return elseConnectableGuards; | 109 return elseConnectableGuards; |
117 } | 110 } |
118 | 111 |
119 private GuardData findNegatedGuardInPrevious(GuardData guard, boolean minimumStateCheck) { | 112 private GuardExpression findNegatedGuardInPrevious(GuardExpression guard) { |
120 SpecializationGroup previous = this.getPreviousGroup(); | 113 SpecializationGroup previous = this.getPreviousGroup(); |
121 if (previous == null) { | 114 if (previous == null) { |
122 return null; | 115 return null; |
123 } | 116 } |
124 List<GuardData> elseConnectedGuards = previous.findElseConnectableGuards(minimumStateCheck); | 117 List<GuardExpression> elseConnectedGuards = previous.findElseConnectableGuards(); |
125 | 118 |
126 if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { | 119 if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { |
127 return null; | 120 return null; |
128 } | 121 } |
129 | 122 |
130 /* Guard is else branch can be connected in previous specialization. */ | 123 /* Guard is else branch can be connected in previous specialization. */ |
131 if (elseConnectedGuards.contains(guard)) { | 124 if (elseConnectedGuards.contains(guard)) { |
132 return guard; | 125 return guard; |
133 } | 126 } |
134 | 127 |
135 GuardData previousGuard = previous.getGuards().get(elseConnectedGuards.size()); | 128 GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size()); |
136 if (guard.getMethod().equals(previousGuard.getMethod()) && guard.isNegated() != previousGuard.isNegated()) { | 129 if (guard.getResolvedGuard().getMethod().equals(previousGuard.getResolvedGuard().getMethod()) && guard.isNegated() != previousGuard.isNegated()) { |
137 return guard; | 130 return guard; |
138 } | 131 } |
139 return null; | 132 return null; |
140 } | 133 } |
141 | 134 |
159 | 152 |
160 public List<TypeGuard> getTypeGuards() { | 153 public List<TypeGuard> getTypeGuards() { |
161 return typeGuards; | 154 return typeGuards; |
162 } | 155 } |
163 | 156 |
164 public List<GuardData> getGuards() { | 157 public List<GuardExpression> getGuards() { |
165 return guards; | 158 return guards; |
166 } | 159 } |
167 | 160 |
168 public List<SpecializationGroup> getChildren() { | 161 public List<SpecializationGroup> getChildren() { |
169 return children; | 162 return children; |
181 return null; | 174 return null; |
182 } | 175 } |
183 | 176 |
184 List<String> assumptionMatches = new ArrayList<>(); | 177 List<String> assumptionMatches = new ArrayList<>(); |
185 List<TypeGuard> typeGuardsMatches = new ArrayList<>(); | 178 List<TypeGuard> typeGuardsMatches = new ArrayList<>(); |
186 List<GuardData> guardMatches = new ArrayList<>(); | 179 List<GuardExpression> guardMatches = new ArrayList<>(); |
187 | 180 |
188 SpecializationGroup first = groups.get(0); | 181 SpecializationGroup first = groups.get(0); |
189 List<SpecializationGroup> others = groups.subList(1, groups.size()); | 182 List<SpecializationGroup> others = groups.subList(1, groups.size()); |
190 | 183 |
191 outer: for (String assumption : first.assumptions) { | 184 outer: for (String assumption : first.assumptions) { |
206 } | 199 } |
207 } | 200 } |
208 typeGuardsMatches.add(typeGuard); | 201 typeGuardsMatches.add(typeGuard); |
209 } | 202 } |
210 | 203 |
211 outer: for (GuardData guard : first.guards) { | 204 outer: for (GuardExpression guard : first.guards) { |
212 for (SpecializationGroup other : others) { | 205 for (SpecializationGroup other : others) { |
213 if (!other.guards.contains(guard)) { | 206 if (!other.guards.contains(guard)) { |
214 // we must break here. One guard may depend on the other. | 207 // we must break here. One guard may depend on the other. |
215 break outer; | 208 break outer; |
216 } | 209 } |
217 } | 210 } |
218 guardMatches.add(guard); | 211 guardMatches.add(guard); |
219 } | 212 } |
220 | 213 |
221 // check for guards for required type casts | 214 // check for guards for required type casts |
222 for (Iterator<GuardData> iterator = guardMatches.iterator(); iterator.hasNext();) { | 215 for (Iterator<GuardExpression> iterator = guardMatches.iterator(); iterator.hasNext();) { |
223 GuardData guardMatch = iterator.next(); | 216 GuardExpression guardMatch = iterator.next(); |
224 | 217 |
225 int signatureIndex = 0; | 218 int signatureIndex = 0; |
226 for (ActualParameter parameter : guardMatch.getParameters()) { | 219 for (ActualParameter parameter : guardMatch.getResolvedGuard().getParameters()) { |
227 signatureIndex++; | 220 signatureIndex++; |
228 if (!parameter.getSpecification().isSignature()) { | 221 if (!parameter.getSpecification().isSignature()) { |
229 continue; | 222 continue; |
230 } | 223 } |
231 | 224 |
295 public static SpecializationGroup create(List<SpecializationData> specializations) { | 288 public static SpecializationGroup create(List<SpecializationData> specializations) { |
296 List<SpecializationGroup> groups = new ArrayList<>(); | 289 List<SpecializationGroup> groups = new ArrayList<>(); |
297 for (SpecializationData specialization : specializations) { | 290 for (SpecializationData specialization : specializations) { |
298 groups.add(new SpecializationGroup(specialization)); | 291 groups.add(new SpecializationGroup(specialization)); |
299 } | 292 } |
300 return new SpecializationGroup(createCombinationalGroups(groups), Collections.<String> emptyList(), Collections.<TypeGuard> emptyList(), Collections.<GuardData> emptyList()); | 293 return new SpecializationGroup(createCombinationalGroups(groups), Collections.<String> emptyList(), Collections.<TypeGuard> emptyList(), Collections.<GuardExpression> emptyList()); |
301 } | 294 } |
302 | 295 |
303 @Override | 296 @Override |
304 public String toString() { | 297 public String toString() { |
305 return "SpecializationGroup [assumptions=" + assumptions + ", typeGuards=" + typeGuards + ", guards=" + guards + "]"; | 298 return "SpecializationGroup [assumptions=" + assumptions + ", typeGuards=" + typeGuards + ", guards=" + guards + "]"; |
427 | 420 |
428 public TypeData getType() { | 421 public TypeData getType() { |
429 return type; | 422 return type; |
430 } | 423 } |
431 } | 424 } |
425 | |
426 public boolean isTypeGuardUsedInAnyGuardBelow(ProcessorContext context, SpecializationData source, TypeGuard typeGuard) { | |
427 | |
428 for (GuardExpression guard : guards) { | |
429 ActualParameter guardParameter = guard.getResolvedGuard().getSignatureParameter(typeGuard.getSignatureIndex()); | |
430 if (guardParameter == null) { | |
431 // guardParameters are optional | |
432 continue; | |
433 } | |
434 ActualParameter sourceParameter = source.getSignatureParameter(typeGuard.getSignatureIndex()); | |
435 if (sourceParameter.getTypeSystemType().needsCastTo(guardParameter.getType())) { | |
436 return true; | |
437 } | |
438 } | |
439 | |
440 for (SpecializationGroup group : getChildren()) { | |
441 if (group.isTypeGuardUsedInAnyGuardBelow(context, source, typeGuard)) { | |
442 return true; | |
443 } | |
444 } | |
445 | |
446 return false; | |
447 } | |
432 } | 448 } |