comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.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 8db6e76cb658
children
comparison
equal deleted inserted replaced
16754:55fd5be68a52 16755:bd28da642eea
22 */ 22 */
23 package com.oracle.truffle.dsl.processor.node; 23 package com.oracle.truffle.dsl.processor.node;
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import javax.lang.model.type.*;
28
29 import com.oracle.truffle.api.dsl.*;
30 import com.oracle.truffle.dsl.processor.*; 27 import com.oracle.truffle.dsl.processor.*;
31 import com.oracle.truffle.dsl.processor.template.*; 28 import com.oracle.truffle.dsl.processor.template.*;
32 import com.oracle.truffle.dsl.processor.typesystem.*; 29 import com.oracle.truffle.dsl.processor.typesystem.*;
33 30
34 public class SpecializationData extends TemplateMethod { 31 public final class SpecializationData extends TemplateMethod {
35 32
36 public enum SpecializationKind { 33 public enum SpecializationKind {
37 UNINITIALIZED, 34 UNINITIALIZED,
38 SPECIALIZED, 35 SPECIALIZED,
39 POLYMORPHIC, 36 POLYMORPHIC,
40 GENERIC 37 GENERIC
41 } 38 }
42 39
43 private final NodeData node; 40 private final NodeData node;
44 private final int order;
45 private final SpecializationKind kind; 41 private final SpecializationKind kind;
46 private final List<SpecializationThrowsData> exceptions; 42 private final List<SpecializationThrowsData> exceptions;
47 private List<String> guardDefinitions = Collections.emptyList(); 43 private List<GuardExpression> guards = Collections.emptyList();
48 private List<GuardData> guards = Collections.emptyList();
49 private List<ShortCircuitData> shortCircuits; 44 private List<ShortCircuitData> shortCircuits;
50 private List<String> assumptions = Collections.emptyList(); 45 private List<String> assumptions = Collections.emptyList();
46 private final Set<SpecializationData> contains = new TreeSet<>();
47 private final Set<String> containsNames = new TreeSet<>();
48 private final Set<SpecializationData> excludedBy = new TreeSet<>();
49 private String insertBeforeName;
50 private SpecializationData insertBefore;
51 private boolean reachable; 51 private boolean reachable;
52 52 private int index;
53 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, int order, List<SpecializationThrowsData> exceptions) { 53
54 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, List<SpecializationThrowsData> exceptions) {
54 super(template); 55 super(template);
55 this.node = node; 56 this.node = node;
56 this.order = order;
57 this.kind = kind; 57 this.kind = kind;
58 this.exceptions = exceptions; 58 this.exceptions = exceptions;
59 this.index = template.getNaturalOrder();
59 60
60 for (SpecializationThrowsData exception : exceptions) { 61 for (SpecializationThrowsData exception : exceptions) {
61 exception.setSpecialization(this); 62 exception.setSpecialization(this);
62 } 63 }
63 } 64 }
64 65
66 public void setInsertBefore(SpecializationData insertBefore) {
67 this.insertBefore = insertBefore;
68 }
69
70 public void setInsertBeforeName(String insertBeforeName) {
71 this.insertBeforeName = insertBeforeName;
72 }
73
74 public SpecializationData getInsertBefore() {
75 return insertBefore;
76 }
77
78 public String getInsertBeforeName() {
79 return insertBeforeName;
80 }
81
82 public Set<String> getContainsNames() {
83 return containsNames;
84 }
85
65 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) { 86 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) {
66 this(node, template, kind, Specialization.DEFAULT_ORDER, new ArrayList<SpecializationThrowsData>()); 87 this(node, template, kind, new ArrayList<SpecializationThrowsData>());
88 }
89
90 public Set<SpecializationData> getContains() {
91 return contains;
92 }
93
94 public Set<SpecializationData> getExcludedBy() {
95 return excludedBy;
67 } 96 }
68 97
69 public void setReachable(boolean reachable) { 98 public void setReachable(boolean reachable) {
70 this.reachable = reachable; 99 this.reachable = reachable;
71 } 100 }
83 List<MessageContainer> sinks = new ArrayList<>(); 112 List<MessageContainer> sinks = new ArrayList<>();
84 if (exceptions != null) { 113 if (exceptions != null) {
85 sinks.addAll(exceptions); 114 sinks.addAll(exceptions);
86 } 115 }
87 if (guards != null) { 116 if (guards != null) {
88 sinks.addAll(guards); 117 for (GuardExpression guard : guards) {
118 if (guard.isResolved()) {
119 sinks.add(guard.getResolvedGuard());
120 }
121 }
89 } 122 }
90 return sinks; 123 return sinks;
91 }
92
93 public boolean isGenericSpecialization(ProcessorContext context) {
94 if (isGeneric()) {
95 return true;
96 }
97 if (hasRewrite(context)) {
98 return false;
99 }
100
101 for (ActualParameter parameter : getSignatureParameters()) {
102 ActualParameter genericParameter = getNode().getGenericSpecialization().findParameter(parameter.getLocalName());
103 if (!parameter.getTypeSystemType().equals(genericParameter.getTypeSystemType())) {
104 return false;
105 }
106 }
107 return true;
108 } 124 }
109 125
110 public boolean hasRewrite(ProcessorContext context) { 126 public boolean hasRewrite(ProcessorContext context) {
111 if (!getExceptions().isEmpty()) { 127 if (!getExceptions().isEmpty()) {
112 return true; 128 return true;
120 for (ActualParameter parameter : getSignatureParameters()) { 136 for (ActualParameter parameter : getSignatureParameters()) {
121 ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType()); 137 ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType());
122 if (type.hasUnexpectedValue(context)) { 138 if (type.hasUnexpectedValue(context)) {
123 return true; 139 return true;
124 } 140 }
125 if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) { 141 if (type.getReturnType().getTypeSystemType().needsCastTo(parameter.getTypeSystemType())) {
126 return true; 142 return true;
127 } 143 }
128 144
129 } 145 }
130 return false; 146 return false;
131 } 147 }
132 148
133 @Override 149 @Override
134 public int compareBySignature(TemplateMethod other) { 150 public int compareTo(TemplateMethod other) {
135 if (this == other) { 151 if (this == other) {
136 return 0; 152 return 0;
137 } else if (!(other instanceof SpecializationData)) { 153 } else if (!(other instanceof SpecializationData)) {
138 return super.compareBySignature(other); 154 return super.compareTo(other);
139 } 155 }
140
141 SpecializationData m2 = (SpecializationData) other; 156 SpecializationData m2 = (SpecializationData) other;
142
143 int kindOrder = kind.compareTo(m2.kind); 157 int kindOrder = kind.compareTo(m2.kind);
144 if (kindOrder != 0) { 158 if (kindOrder != 0) {
145 return kindOrder; 159 return kindOrder;
146 } 160 }
147 if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { 161
148 return getOrder() - m2.getOrder(); 162 int compare = 0;
163 int order1 = index;
164 int order2 = m2.index;
165 if (order1 != NO_NATURAL_ORDER && order2 != NO_NATURAL_ORDER) {
166 compare = Integer.compare(order1, order2);
167 if (compare != 0) {
168 return compare;
169 }
170 }
171
172 return super.compareTo(other);
173 }
174
175 public void setIndex(int order) {
176 this.index = order;
177 }
178
179 public int getIndex() {
180 return index;
181 }
182
183 public int compareByConcreteness(SpecializationData m2) {
184 int kindOrder = kind.compareTo(m2.kind);
185 if (kindOrder != 0) {
186 return kindOrder;
149 } 187 }
150 188
151 if (getTemplate() != m2.getTemplate()) { 189 if (getTemplate() != m2.getTemplate()) {
152 throw new UnsupportedOperationException("Cannot compare two specializations with different templates."); 190 throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
153 } 191 }
154 192 boolean intersects = intersects(m2);
155 return super.compareBySignature(m2); 193 int result = 0;
194 if (intersects) {
195 if (this.contains(m2)) {
196 return 1;
197 } else if (m2.contains(this)) {
198 return -1;
199 }
200 }
201
202 result = compareBySignature(m2);
203 if (result != 0) {
204 return result;
205 }
206
207 result = compareGuards(getGuards(), m2.getGuards());
208 if (result != 0) {
209 return result;
210 }
211
212 result = compareAssumptions(getAssumptions(), m2.getAssumptions());
213 if (result != 0) {
214 return result;
215 }
216
217 result = compareParameter(node.getTypeSystem(), getReturnType().getType(), m2.getReturnType().getType());
218 if (result != 0) {
219 return result;
220 }
221
222 result = m2.getExceptions().size() - getExceptions().size();
223 if (result != 0) {
224 return result;
225 }
226
227 return result;
228 }
229
230 public boolean contains(SpecializationData other) {
231 return getContains().contains(other);
232 }
233
234 private int compareAssumptions(List<String> assumptions1, List<String> assumptions2) {
235 Iterator<String> iterator1 = assumptions1.iterator();
236 Iterator<String> iterator2 = assumptions2.iterator();
237 while (iterator1.hasNext() && iterator2.hasNext()) {
238 String a1 = iterator1.next();
239 String a2 = iterator2.next();
240
241 int index1 = getNode().getAssumptions().indexOf(a1);
242 int index2 = getNode().getAssumptions().indexOf(a2);
243 int result = index1 - index2;
244 if (result != 0) {
245 return result;
246 }
247 }
248 if (iterator1.hasNext()) {
249 return -1;
250 } else if (iterator2.hasNext()) {
251 return 1;
252 }
253 return 0;
254 }
255
256 public boolean isContainedBy(SpecializationData next) {
257 if (compareTo(next) > 0) {
258 // must be declared after the current specialization
259 return false;
260 }
261
262 Iterator<ActualParameter> currentSignature = getSignatureParameters().iterator();
263 Iterator<ActualParameter> nextSignature = next.getSignatureParameters().iterator();
264
265 while (currentSignature.hasNext() && nextSignature.hasNext()) {
266 TypeData currentType = currentSignature.next().getTypeSystemType();
267 TypeData prevType = nextSignature.next().getTypeSystemType();
268
269 if (!currentType.isImplicitSubtypeOf(prevType)) {
270 return false;
271 }
272 }
273
274 for (String nextAssumption : next.getAssumptions()) {
275 if (!getAssumptions().contains(nextAssumption)) {
276 return false;
277 }
278 }
279
280 Iterator<GuardExpression> nextGuards = next.getGuards().iterator();
281 while (nextGuards.hasNext()) {
282 GuardExpression nextGuard = nextGuards.next();
283 boolean implied = false;
284 for (GuardExpression currentGuard : getGuards()) {
285 if (currentGuard.implies(nextGuard)) {
286 implied = true;
287 break;
288 }
289 }
290 if (!implied) {
291 return false;
292 }
293 }
294
295 return true;
296 }
297
298 public boolean intersects(SpecializationData other) {
299 return intersectsTypeGuards(other) || intersectsMethodGuards(other);
300 }
301
302 private boolean intersectsTypeGuards(SpecializationData other) {
303 final TypeSystemData typeSystem = getTemplate().getTypeSystem();
304 if (typeSystem != other.getTemplate().getTypeSystem()) {
305 throw new IllegalStateException("Cannot compare two methods with different type systems.");
306 }
307
308 Iterator<ActualParameter> signature1 = getSignatureParameters().iterator();
309 Iterator<ActualParameter> signature2 = other.getSignatureParameters().iterator();
310 while (signature1.hasNext() && signature2.hasNext()) {
311 TypeData parameter1 = signature1.next().getTypeSystemType();
312 TypeData parameter2 = signature2.next().getTypeSystemType();
313 if (parameter1 == null || parameter2 == null) {
314 continue;
315 }
316 if (!parameter1.intersects(parameter2)) {
317 return false;
318 }
319 }
320 return true;
321 }
322
323 private boolean intersectsMethodGuards(SpecializationData other) {
324 for (GuardExpression guard1 : getGuards()) {
325 for (GuardExpression guard2 : other.getGuards()) {
326 if (guard1.impliesNot(guard2) || guard2.impliesNot(guard1)) {
327 return false;
328 }
329 }
330 }
331 return true;
332 }
333
334 private static int compareGuards(List<GuardExpression> guards1, List<GuardExpression> guards2) {
335 Iterator<GuardExpression> signature1 = guards1.iterator();
336 Iterator<GuardExpression> signature2 = guards2.iterator();
337 boolean allSame = true;
338 while (signature1.hasNext() && signature2.hasNext()) {
339 GuardExpression guard1 = signature1.next();
340 GuardExpression guard2 = signature2.next();
341 boolean g1impliesg2 = guard1.implies(guard2);
342 boolean g2impliesg1 = guard2.implies(guard1);
343 if (g1impliesg2 && g2impliesg1) {
344 continue;
345 } else if (g1impliesg2) {
346 return -1;
347 } else if (g2impliesg1) {
348 return 1;
349 } else {
350 allSame = false;
351 }
352 }
353
354 if (allSame) {
355 if (signature1.hasNext()) {
356 return -1;
357 } else if (signature2.hasNext()) {
358 return 1;
359 }
360 }
361
362 return 0;
363 }
364
365 public String createReferenceName() {
366 StringBuilder b = new StringBuilder();
367
368 b.append(getMethodName());
369 b.append("(");
370
371 String sep = "";
372 for (ActualParameter parameter : getParameters()) {
373 b.append(sep);
374 b.append(Utils.getSimpleName(parameter.getType()));
375 sep = ", ";
376 }
377
378 b.append(")");
379 return b.toString();
156 } 380 }
157 381
158 public NodeData getNode() { 382 public NodeData getNode() {
159 return node; 383 return node;
160 } 384 }
161 385
162 public void setGuards(List<GuardData> guards) { 386 public void setGuards(List<GuardExpression> guards) {
163 this.guards = guards; 387 this.guards = guards;
164 }
165
166 public void setGuardDefinitions(List<String> guardDefinitions) {
167 this.guardDefinitions = guardDefinitions;
168 }
169
170 public int getOrder() {
171 return order;
172 } 388 }
173 389
174 public boolean isSpecialized() { 390 public boolean isSpecialized() {
175 return kind == SpecializationKind.SPECIALIZED; 391 return kind == SpecializationKind.SPECIALIZED;
176 } 392 }
185 401
186 public List<SpecializationThrowsData> getExceptions() { 402 public List<SpecializationThrowsData> getExceptions() {
187 return exceptions; 403 return exceptions;
188 } 404 }
189 405
190 public List<String> getGuardDefinitions() { 406 public List<GuardExpression> getGuards() {
191 return guardDefinitions;
192 }
193
194 public List<GuardData> getGuards() {
195 return guards; 407 return guards;
196 } 408 }
197 409
198 public void setShortCircuits(List<ShortCircuitData> shortCircuits) { 410 public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
199 this.shortCircuits = shortCircuits; 411 this.shortCircuits = shortCircuits;
207 return assumptions; 419 return assumptions;
208 } 420 }
209 421
210 void setAssumptions(List<String> assumptions) { 422 void setAssumptions(List<String> assumptions) {
211 this.assumptions = assumptions; 423 this.assumptions = assumptions;
212 }
213
214 public SpecializationData findPreviousSpecialization() {
215 List<SpecializationData> specializations = node.getSpecializations();
216 for (int i = 0; i < specializations.size() - 1; i++) {
217 if (specializations.get(i) == this && i > 0) {
218 return specializations.get(i - 1);
219 }
220 }
221 return null;
222 } 424 }
223 425
224 public SpecializationData findNextSpecialization() { 426 public SpecializationData findNextSpecialization() {
225 List<SpecializationData> specializations = node.getSpecializations(); 427 List<SpecializationData> specializations = node.getSpecializations();
226 for (int i = 0; i < specializations.size() - 1; i++) { 428 for (int i = 0; i < specializations.size() - 1; i++) {
229 } 431 }
230 } 432 }
231 return null; 433 return null;
232 } 434 }
233 435
234 public boolean hasDynamicGuards() {
235 return !getGuards().isEmpty();
236 }
237
238 @Override 436 @Override
239 public String toString() { 437 public String toString() {
240 return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature()); 438 return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature());
241 } 439 }
242 440
243 public void forceFrame(TypeMirror frameType) {
244 if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) {
245 ParameterSpec frameSpec = getSpecification().findParameterSpec("frame");
246 if (frameSpec != null) {
247 getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, -1));
248 }
249 }
250 }
251
252 public boolean equalsGuards(SpecializationData specialization) { 441 public boolean equalsGuards(SpecializationData specialization) {
253 if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getTypeSignature().equalsParameters(specialization.getTypeSignature())) { 442 if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getTypeSignature().equalsParameters(specialization.getTypeSignature())) {
254 return true; 443 return true;
255 } 444 }
256 return false; 445 return false;
263 } 452 }
264 } 453 }
265 return false; 454 return false;
266 } 455 }
267 456
457 public boolean isReachableAfter(SpecializationData prev) {
458 if (!prev.isSpecialized()) {
459 return true;
460 }
461
462 if (!prev.getExceptions().isEmpty()) {
463 return true;
464 }
465
466 Iterator<ActualParameter> currentSignature = getSignatureParameters().iterator();
467 Iterator<ActualParameter> prevSignature = prev.getSignatureParameters().iterator();
468
469 while (currentSignature.hasNext() && prevSignature.hasNext()) {
470 TypeData currentType = currentSignature.next().getTypeSystemType();
471 TypeData prevType = prevSignature.next().getTypeSystemType();
472
473 if (!currentType.isImplicitSubtypeOf(prevType)) {
474 return true;
475 }
476 }
477
478 for (String prevAssumption : prev.getAssumptions()) {
479 if (!getAssumptions().contains(prevAssumption)) {
480 return true;
481 }
482 }
483
484 Iterator<GuardExpression> prevGuards = prev.getGuards().iterator();
485 Iterator<GuardExpression> currentGuards = getGuards().iterator();
486 while (prevGuards.hasNext()) {
487 GuardExpression prevGuard = prevGuards.next();
488 GuardExpression currentGuard = currentGuards.hasNext() ? currentGuards.next() : null;
489 if (currentGuard == null || !currentGuard.implies(prevGuard)) {
490 return true;
491 }
492 }
493
494 return false;
495 }
268 } 496 }