comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java@6361fa2e3321
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.dsl.processor.model;
24
25 import java.util.*;
26
27 import javax.lang.model.element.*;
28 import javax.lang.model.type.*;
29
30 import com.oracle.truffle.dsl.processor.*;
31 import com.oracle.truffle.dsl.processor.expression.*;
32 import com.oracle.truffle.dsl.processor.java.*;
33
34 public final class SpecializationData extends TemplateMethod {
35
36 public enum SpecializationKind {
37 UNINITIALIZED,
38 SPECIALIZED,
39 POLYMORPHIC,
40 FALLBACK
41 }
42
43 private final NodeData node;
44 private SpecializationKind kind;
45 private final List<SpecializationThrowsData> exceptions;
46 private List<GuardExpression> guards = Collections.emptyList();
47 private List<CacheExpression> caches = Collections.emptyList();
48 private List<AssumptionExpression> assumptionExpressions = Collections.emptyList();
49 private List<ShortCircuitData> shortCircuits;
50 private final Set<SpecializationData> contains = new TreeSet<>();
51 private final Set<String> containsNames = new TreeSet<>();
52 private final Set<SpecializationData> excludedBy = new TreeSet<>();
53 private String insertBeforeName;
54 private SpecializationData insertBefore;
55 private boolean reachable;
56 private int index;
57 private DSLExpression limitExpression;
58
59 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, List<SpecializationThrowsData> exceptions) {
60 super(template);
61 this.node = node;
62 this.kind = kind;
63 this.exceptions = exceptions;
64 this.index = template.getNaturalOrder();
65
66 for (SpecializationThrowsData exception : exceptions) {
67 exception.setSpecialization(this);
68 }
69 }
70
71 public boolean isCacheBoundByGuard(CacheExpression cacheExpression) {
72 for (GuardExpression expression : getGuards()) {
73 if (expression.getExpression().findBoundVariableElements().contains(cacheExpression.getParameter().getVariableElement())) {
74 return true;
75 }
76 }
77
78 // check all next binding caches if they are bound by guard
79 Set<VariableElement> boundVariables = cacheExpression.getExpression().findBoundVariableElements();
80 boolean found = false;
81 for (CacheExpression expression : getCaches()) {
82 if (cacheExpression == expression) {
83 found = true;
84 } else if (found) {
85 if (boundVariables.contains(expression.getParameter().getVariableElement())) {
86 if (isCacheBoundByGuard(expression)) {
87 return true;
88 }
89 }
90 }
91 }
92 return false;
93 }
94
95 public void setKind(SpecializationKind kind) {
96 this.kind = kind;
97 }
98
99 public boolean isDynamicParameterBound(DSLExpression expression) {
100 Set<VariableElement> boundVariables = expression.findBoundVariableElements();
101 for (Parameter parameter : getDynamicParameters()) {
102 if (boundVariables.contains(parameter.getVariableElement())) {
103 return true;
104 }
105 }
106 return false;
107 }
108
109 public Parameter findByVariable(VariableElement variable) {
110 for (Parameter parameter : getParameters()) {
111 if (ElementUtils.variableEquals(parameter.getVariableElement(), variable)) {
112 return parameter;
113 }
114 }
115 return null;
116 }
117
118 public DSLExpression getLimitExpression() {
119 return limitExpression;
120 }
121
122 public void setLimitExpression(DSLExpression limitExpression) {
123 this.limitExpression = limitExpression;
124 }
125
126 public void setInsertBefore(SpecializationData insertBefore) {
127 this.insertBefore = insertBefore;
128 }
129
130 public void setInsertBeforeName(String insertBeforeName) {
131 this.insertBeforeName = insertBeforeName;
132 }
133
134 public SpecializationData getInsertBefore() {
135 return insertBefore;
136 }
137
138 public String getInsertBeforeName() {
139 return insertBeforeName;
140 }
141
142 public Set<String> getContainsNames() {
143 return containsNames;
144 }
145
146 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) {
147 this(node, template, kind, new ArrayList<SpecializationThrowsData>());
148 }
149
150 public Set<SpecializationData> getContains() {
151 return contains;
152 }
153
154 public Set<SpecializationData> getExcludedBy() {
155 return excludedBy;
156 }
157
158 public void setReachable(boolean reachable) {
159 this.reachable = reachable;
160 }
161
162 public boolean isReachable() {
163 return reachable;
164 }
165
166 public boolean isPolymorphic() {
167 return kind == SpecializationKind.POLYMORPHIC;
168 }
169
170 @Override
171 protected List<MessageContainer> findChildContainers() {
172 List<MessageContainer> sinks = new ArrayList<>();
173 if (exceptions != null) {
174 sinks.addAll(exceptions);
175 }
176 if (guards != null) {
177 sinks.addAll(guards);
178 }
179 if (caches != null) {
180 sinks.addAll(caches);
181 }
182 if (assumptionExpressions != null) {
183 sinks.addAll(assumptionExpressions);
184 }
185 return sinks;
186 }
187
188 public boolean hasRewrite(ProcessorContext context) {
189 if (!getExceptions().isEmpty()) {
190 return true;
191 }
192 if (!getGuards().isEmpty()) {
193 return true;
194 }
195 if (!getAssumptionExpressions().isEmpty()) {
196 return true;
197 }
198
199 for (Parameter parameter : getSignatureParameters()) {
200 NodeChildData child = parameter.getSpecification().getExecution().getChild();
201 if (child != null) {
202 ExecutableTypeData type = child.findExecutableType(parameter.getType());
203 if (type == null) {
204 type = child.findAnyGenericExecutableType(context);
205 }
206 if (type.hasUnexpectedValue(context)) {
207 return true;
208 }
209 if (ElementUtils.needsCastTo(type.getReturnType(), parameter.getType())) {
210 return true;
211 }
212 }
213 }
214 return false;
215 }
216
217 @Override
218 public int compareTo(TemplateMethod other) {
219 if (this == other) {
220 return 0;
221 } else if (!(other instanceof SpecializationData)) {
222 return super.compareTo(other);
223 }
224 SpecializationData m2 = (SpecializationData) other;
225 int kindOrder = kind.compareTo(m2.kind);
226 if (kindOrder != 0) {
227 return kindOrder;
228 }
229
230 int compare = 0;
231 int order1 = index;
232 int order2 = m2.index;
233 if (order1 != NO_NATURAL_ORDER && order2 != NO_NATURAL_ORDER) {
234 compare = Integer.compare(order1, order2);
235 if (compare != 0) {
236 return compare;
237 }
238 }
239
240 return super.compareTo(other);
241 }
242
243 public void setIndex(int order) {
244 this.index = order;
245 }
246
247 public int getIndex() {
248 return index;
249 }
250
251 public NodeData getNode() {
252 return node;
253 }
254
255 public void setGuards(List<GuardExpression> guards) {
256 this.guards = guards;
257 }
258
259 public boolean isSpecialized() {
260 return kind == SpecializationKind.SPECIALIZED;
261 }
262
263 public boolean isFallback() {
264 return kind == SpecializationKind.FALLBACK;
265 }
266
267 public boolean isUninitialized() {
268 return kind == SpecializationKind.UNINITIALIZED;
269 }
270
271 public List<SpecializationThrowsData> getExceptions() {
272 return exceptions;
273 }
274
275 public List<GuardExpression> getGuards() {
276 return guards;
277 }
278
279 public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
280 this.shortCircuits = shortCircuits;
281 }
282
283 public List<ShortCircuitData> getShortCircuits() {
284 return shortCircuits;
285 }
286
287 public SpecializationData findNextSpecialization() {
288 List<SpecializationData> specializations = node.getSpecializations();
289 for (int i = 0; i < specializations.size() - 1; i++) {
290 if (specializations.get(i) == this) {
291 return specializations.get(i + 1);
292 }
293 }
294 return null;
295 }
296
297 @Override
298 public String toString() {
299 return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getDynamicTypes());
300 }
301
302 public boolean isFrameUsed() {
303 return getFrame() != null;
304 }
305
306 public List<CacheExpression> getCaches() {
307 return caches;
308 }
309
310 public void setCaches(List<CacheExpression> caches) {
311 this.caches = caches;
312 }
313
314 public void setAssumptionExpressions(List<AssumptionExpression> assumptionExpressions) {
315 this.assumptionExpressions = assumptionExpressions;
316 }
317
318 public List<AssumptionExpression> getAssumptionExpressions() {
319 return assumptionExpressions;
320 }
321
322 public boolean hasMultipleInstances() {
323 if (!getCaches().isEmpty()) {
324 for (GuardExpression guard : getGuards()) {
325 DSLExpression guardExpression = guard.getExpression();
326 Set<VariableElement> boundVariables = guardExpression.findBoundVariableElements();
327 if (isDynamicParameterBound(guardExpression)) {
328 for (CacheExpression cache : getCaches()) {
329 if (boundVariables.contains(cache.getParameter().getVariableElement())) {
330 return true;
331 }
332 }
333 }
334 }
335 }
336 return false;
337 }
338
339 public boolean isReachableAfter(SpecializationData prev) {
340 if (!prev.isSpecialized()) {
341 return true;
342 }
343
344 if (!prev.getExceptions().isEmpty()) {
345 // may get excluded by exception
346 return true;
347 }
348
349 if (hasMultipleInstances()) {
350 // may fallthrough due to limit
351 return true;
352 }
353
354 Iterator<Parameter> currentSignature = getSignatureParameters().iterator();
355 Iterator<Parameter> prevSignature = prev.getSignatureParameters().iterator();
356
357 TypeSystemData typeSystem = prev.getNode().getTypeSystem();
358 while (currentSignature.hasNext() && prevSignature.hasNext()) {
359 TypeMirror currentType = currentSignature.next().getType();
360 TypeMirror prevType = prevSignature.next().getType();
361
362 if (!typeSystem.isImplicitSubtypeOf(currentType, prevType)) {
363 return true;
364 }
365 }
366
367 if (!prev.getAssumptionExpressions().isEmpty()) {
368 // TODO: chumer: we could at least check reachability after trivial assumptions
369 // not sure if this is worth it.
370 return true;
371 }
372
373 Iterator<GuardExpression> prevGuards = prev.getGuards().iterator();
374 Iterator<GuardExpression> currentGuards = getGuards().iterator();
375 while (prevGuards.hasNext()) {
376 GuardExpression prevGuard = prevGuards.next();
377 GuardExpression currentGuard = currentGuards.hasNext() ? currentGuards.next() : null;
378 if (currentGuard == null || !currentGuard.implies(prevGuard)) {
379 return true;
380 }
381 }
382
383 return false;
384 }
385
386 public CacheExpression findCache(Parameter resolvedParameter) {
387 for (CacheExpression cache : getCaches()) {
388 if (cache.getParameter() == resolvedParameter) {
389 return cache;
390 }
391 }
392 return null;
393 }
394
395 }