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 }