comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java @ 16759:23415229349b

Truffle-DSL: new package structure.
author Christian Humer <christian.humer@gmail.com>
date Mon, 11 Aug 2014 15:57:14 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java@bd28da642eea
children 89f635cbd85e
comparison
equal deleted inserted replaced
16758:c5f8eeb3cbc8 16759:23415229349b
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 com.oracle.truffle.dsl.processor.*;
28 import com.oracle.truffle.dsl.processor.java.*;
29
30 public final class SpecializationData extends TemplateMethod {
31
32 public enum SpecializationKind {
33 UNINITIALIZED,
34 SPECIALIZED,
35 POLYMORPHIC,
36 GENERIC
37 }
38
39 private final NodeData node;
40 private final SpecializationKind kind;
41 private final List<SpecializationThrowsData> exceptions;
42 private List<GuardExpression> guards = Collections.emptyList();
43 private List<ShortCircuitData> shortCircuits;
44 private List<String> assumptions = Collections.emptyList();
45 private final Set<SpecializationData> contains = new TreeSet<>();
46 private final Set<String> containsNames = new TreeSet<>();
47 private final Set<SpecializationData> excludedBy = new TreeSet<>();
48 private String insertBeforeName;
49 private SpecializationData insertBefore;
50 private boolean reachable;
51 private int index;
52
53 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, List<SpecializationThrowsData> exceptions) {
54 super(template);
55 this.node = node;
56 this.kind = kind;
57 this.exceptions = exceptions;
58 this.index = template.getNaturalOrder();
59
60 for (SpecializationThrowsData exception : exceptions) {
61 exception.setSpecialization(this);
62 }
63 }
64
65 public void setInsertBefore(SpecializationData insertBefore) {
66 this.insertBefore = insertBefore;
67 }
68
69 public void setInsertBeforeName(String insertBeforeName) {
70 this.insertBeforeName = insertBeforeName;
71 }
72
73 public SpecializationData getInsertBefore() {
74 return insertBefore;
75 }
76
77 public String getInsertBeforeName() {
78 return insertBeforeName;
79 }
80
81 public Set<String> getContainsNames() {
82 return containsNames;
83 }
84
85 public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) {
86 this(node, template, kind, new ArrayList<SpecializationThrowsData>());
87 }
88
89 public Set<SpecializationData> getContains() {
90 return contains;
91 }
92
93 public Set<SpecializationData> getExcludedBy() {
94 return excludedBy;
95 }
96
97 public void setReachable(boolean reachable) {
98 this.reachable = reachable;
99 }
100
101 public boolean isReachable() {
102 return reachable;
103 }
104
105 public boolean isPolymorphic() {
106 return kind == SpecializationKind.POLYMORPHIC;
107 }
108
109 @Override
110 protected List<MessageContainer> findChildContainers() {
111 List<MessageContainer> sinks = new ArrayList<>();
112 if (exceptions != null) {
113 sinks.addAll(exceptions);
114 }
115 if (guards != null) {
116 for (GuardExpression guard : guards) {
117 if (guard.isResolved()) {
118 sinks.add(guard.getResolvedGuard());
119 }
120 }
121 }
122 return sinks;
123 }
124
125 public boolean hasRewrite(ProcessorContext context) {
126 if (!getExceptions().isEmpty()) {
127 return true;
128 }
129 if (!getGuards().isEmpty()) {
130 return true;
131 }
132 if (!getAssumptions().isEmpty()) {
133 return true;
134 }
135 for (Parameter parameter : getSignatureParameters()) {
136 ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType());
137 if (type.hasUnexpectedValue(context)) {
138 return true;
139 }
140 if (type.getReturnType().getTypeSystemType().needsCastTo(parameter.getTypeSystemType())) {
141 return true;
142 }
143
144 }
145 return false;
146 }
147
148 @Override
149 public int compareTo(TemplateMethod other) {
150 if (this == other) {
151 return 0;
152 } else if (!(other instanceof SpecializationData)) {
153 return super.compareTo(other);
154 }
155 SpecializationData m2 = (SpecializationData) other;
156 int kindOrder = kind.compareTo(m2.kind);
157 if (kindOrder != 0) {
158 return kindOrder;
159 }
160
161 int compare = 0;
162 int order1 = index;
163 int order2 = m2.index;
164 if (order1 != NO_NATURAL_ORDER && order2 != NO_NATURAL_ORDER) {
165 compare = Integer.compare(order1, order2);
166 if (compare != 0) {
167 return compare;
168 }
169 }
170
171 return super.compareTo(other);
172 }
173
174 public void setIndex(int order) {
175 this.index = order;
176 }
177
178 public int getIndex() {
179 return index;
180 }
181
182 public boolean isContainedBy(SpecializationData next) {
183 if (compareTo(next) > 0) {
184 // must be declared after the current specialization
185 return false;
186 }
187
188 Iterator<Parameter> currentSignature = getSignatureParameters().iterator();
189 Iterator<Parameter> nextSignature = next.getSignatureParameters().iterator();
190
191 while (currentSignature.hasNext() && nextSignature.hasNext()) {
192 TypeData currentType = currentSignature.next().getTypeSystemType();
193 TypeData prevType = nextSignature.next().getTypeSystemType();
194
195 if (!currentType.isImplicitSubtypeOf(prevType)) {
196 return false;
197 }
198 }
199
200 for (String nextAssumption : next.getAssumptions()) {
201 if (!getAssumptions().contains(nextAssumption)) {
202 return false;
203 }
204 }
205
206 Iterator<GuardExpression> nextGuards = next.getGuards().iterator();
207 while (nextGuards.hasNext()) {
208 GuardExpression nextGuard = nextGuards.next();
209 boolean implied = false;
210 for (GuardExpression currentGuard : getGuards()) {
211 if (currentGuard.implies(nextGuard)) {
212 implied = true;
213 break;
214 }
215 }
216 if (!implied) {
217 return false;
218 }
219 }
220
221 return true;
222 }
223
224 public String createReferenceName() {
225 StringBuilder b = new StringBuilder();
226
227 b.append(getMethodName());
228 b.append("(");
229
230 String sep = "";
231 for (Parameter parameter : getParameters()) {
232 b.append(sep);
233 b.append(ElementUtils.getSimpleName(parameter.getType()));
234 sep = ", ";
235 }
236
237 b.append(")");
238 return b.toString();
239 }
240
241 public NodeData getNode() {
242 return node;
243 }
244
245 public void setGuards(List<GuardExpression> guards) {
246 this.guards = guards;
247 }
248
249 public boolean isSpecialized() {
250 return kind == SpecializationKind.SPECIALIZED;
251 }
252
253 public boolean isGeneric() {
254 return kind == SpecializationKind.GENERIC;
255 }
256
257 public boolean isUninitialized() {
258 return kind == SpecializationKind.UNINITIALIZED;
259 }
260
261 public List<SpecializationThrowsData> getExceptions() {
262 return exceptions;
263 }
264
265 public List<GuardExpression> getGuards() {
266 return guards;
267 }
268
269 public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
270 this.shortCircuits = shortCircuits;
271 }
272
273 public List<ShortCircuitData> getShortCircuits() {
274 return shortCircuits;
275 }
276
277 public List<String> getAssumptions() {
278 return assumptions;
279 }
280
281 public void setAssumptions(List<String> assumptions) {
282 this.assumptions = assumptions;
283 }
284
285 public SpecializationData findNextSpecialization() {
286 List<SpecializationData> specializations = node.getSpecializations();
287 for (int i = 0; i < specializations.size() - 1; i++) {
288 if (specializations.get(i) == this) {
289 return specializations.get(i + 1);
290 }
291 }
292 return null;
293 }
294
295 @Override
296 public String toString() {
297 return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature());
298 }
299
300 public boolean hasFrame(ProcessorContext context) {
301 for (Parameter param : getParameters()) {
302 if (ElementUtils.typeEquals(param.getType(), context.getTruffleTypes().getFrame())) {
303 return true;
304 }
305 }
306 return false;
307 }
308
309 public boolean isReachableAfter(SpecializationData prev) {
310 if (!prev.isSpecialized()) {
311 return true;
312 }
313
314 if (!prev.getExceptions().isEmpty()) {
315 return true;
316 }
317
318 Iterator<Parameter> currentSignature = getSignatureParameters().iterator();
319 Iterator<Parameter> prevSignature = prev.getSignatureParameters().iterator();
320
321 while (currentSignature.hasNext() && prevSignature.hasNext()) {
322 TypeData currentType = currentSignature.next().getTypeSystemType();
323 TypeData prevType = prevSignature.next().getTypeSystemType();
324
325 if (!currentType.isImplicitSubtypeOf(prevType)) {
326 return true;
327 }
328 }
329
330 for (String prevAssumption : prev.getAssumptions()) {
331 if (!getAssumptions().contains(prevAssumption)) {
332 return true;
333 }
334 }
335
336 Iterator<GuardExpression> prevGuards = prev.getGuards().iterator();
337 Iterator<GuardExpression> currentGuards = getGuards().iterator();
338 while (prevGuards.hasNext()) {
339 GuardExpression prevGuard = prevGuards.next();
340 GuardExpression currentGuard = currentGuards.hasNext() ? currentGuards.next() : null;
341 if (currentGuard == null || !currentGuard.implies(prevGuard)) {
342 return true;
343 }
344 }
345
346 return false;
347 }
348 }