comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java @ 7502:6343a09b2ec1

Codegen operation generation is inferred from the node type hierarchy.
author Christian Humer <christian.humer@gmail.com>
date Fri, 18 Jan 2013 13:28:12 +0100
parents
children 9beb22bd83c3
comparison
equal deleted inserted replaced
7497:0f8c6dbf68be 7502:6343a09b2ec1
1 /*
2 * Copyright (c) 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.codegen.processor.node;
24
25 import java.util.*;
26
27 import javax.lang.model.element.*;
28 import javax.lang.model.type.*;
29
30 import com.oracle.truffle.codegen.processor.*;
31 import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
32 import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind;
33 import com.oracle.truffle.codegen.processor.template.*;
34 import com.oracle.truffle.codegen.processor.typesystem.*;
35
36
37 public class NodeData extends Template {
38
39 private NodeData parent;
40 private List<NodeData> declaredChildren;
41
42 private final TypeSystemData typeSystem;
43
44 private NodeFieldData[] fields;
45 private SpecializationData[] specializations;
46 private TemplateMethod[] specializationListeners;
47 private GuardData[] guards;
48 private ExecutableTypeData[] executableTypes;
49
50 private TypeMirror nodeType;
51
52 public NodeData(TypeElement type, TypeSystemData typeSystem) {
53 super(type, null);
54 this.typeSystem = typeSystem;
55 }
56
57 public TypeMirror getNodeType() {
58 if (nodeType != null) {
59 return nodeType;
60 }
61 return getTemplateType().asType();
62 }
63
64 public boolean needsFactory() {
65 if (specializations == null) {
66 return false;
67 }
68 boolean noSpecialization = true;
69 for (SpecializationData specialization : specializations) {
70 noSpecialization = noSpecialization && specialization.isGeneric() || specialization.isUninitialized();
71 }
72 return !noSpecialization;
73 }
74
75 void setDeclaredChildren(List<NodeData> declaredChildren) {
76 this.declaredChildren = declaredChildren;
77
78 for (NodeData child : declaredChildren) {
79 child.parent = this;
80 }
81 }
82
83 public NodeData getParent() {
84 return parent;
85 }
86
87 public List<NodeData> getDeclaredChildren() {
88 return declaredChildren;
89 }
90
91 public void setNodeType(TypeMirror nodeType) {
92 this.nodeType = nodeType;
93 }
94
95 public List<TemplateMethod> getAllTemplateMethods() {
96 List<TemplateMethod> methods = new ArrayList<>();
97
98 for (SpecializationData specialization : getSpecializations()) {
99 methods.add(specialization);
100 if (specialization.getShortCircuits() != null) {
101 methods.addAll(Arrays.asList(specialization.getShortCircuits()));
102 }
103 }
104
105 methods.addAll(Arrays.asList(getSpecializationListeners()));
106 methods.addAll(Arrays.asList(getExecutableTypes()));
107 methods.addAll(Arrays.asList(getGuards()));
108
109 return methods;
110 }
111
112
113 public TemplateMethod[] getSpecializationListeners() {
114 return specializationListeners;
115 }
116
117 public List<GuardData> findGuards(String name) {
118 List<GuardData> foundGuards = new ArrayList<>();
119 for (GuardData guardData : getGuards()) {
120 if (guardData.getMethodName().equals(name)) {
121 foundGuards.add(guardData);
122 }
123 }
124 return foundGuards;
125 }
126
127 public ExecutableTypeData[] getExecutableTypes() {
128 return executableTypes;
129 }
130
131 public ExecutableTypeData findGenericExecutableType(ProcessorContext context) {
132 List<ExecutableTypeData> types = findGenericExecutableTypes(context);
133 if (types.size() == 1) {
134 return types.get(0);
135 } else {
136 ExecutableTypeData execType = null;
137 for (ExecutableTypeData type : types) {
138 if (!type.getReturnType().getActualTypeData(getTypeSystem()).isVoid()) {
139 if (execType != null) {
140 // multiple generic types not allowed
141 return null;
142 }
143 execType = type;
144 }
145 }
146 return execType;
147 }
148 }
149
150 private List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context) {
151 List<ExecutableTypeData> types = new ArrayList<>();
152 for (ExecutableTypeData type : executableTypes) {
153 if (!type.hasUnexpectedValue(context)) {
154 types.add(type);
155 }
156 }
157 return types;
158 }
159
160 public ExecutableTypeData findExecutableType(TypeData prmitiveType) {
161 for (ExecutableTypeData type : executableTypes) {
162 if (Utils.typeEquals(type.getType().getPrimitiveType(), prmitiveType.getPrimitiveType())) {
163 return type;
164 }
165 }
166 return null;
167 }
168
169 public SpecializationData findUniqueSpecialization(TypeData type) {
170 SpecializationData result = null;
171 for (SpecializationData specialization : specializations) {
172 if (specialization.getReturnType().getActualTypeData(getTypeSystem()) == type) {
173 if (result != null) {
174 // Result not unique;
175 return null;
176 }
177 result = specialization;
178 }
179 }
180 return result;
181 }
182
183 public TypeMirror[] getExecutablePrimitiveTypeMirrors() {
184 TypeMirror[] typeMirrors = new TypeMirror[executableTypes.length];
185 for (int i = 0; i < executableTypes.length; i++) {
186 typeMirrors[i] = executableTypes[i].getType().getPrimitiveType();
187 }
188 return typeMirrors;
189 }
190
191 void setExecutableTypes(ExecutableTypeData[] declaredExecuableTypes) {
192 this.executableTypes = declaredExecuableTypes;
193 }
194
195 void setFields(NodeFieldData[] fields) {
196 this.fields = fields;
197 }
198
199 void setSpecializations(SpecializationData[] specializations) {
200 this.specializations = specializations;
201 }
202
203 void setSpecializationListeners(TemplateMethod[] specializationListeners) {
204 this.specializationListeners = specializationListeners;
205 }
206
207 void setGuards(GuardData[] guards) {
208 this.guards = guards;
209 }
210
211 public GuardData[] getGuards() {
212 return guards;
213 }
214
215 public NodeFieldData[] filterFields(FieldKind fieldKind, ExecutionKind usage) {
216 List<NodeFieldData> filteredFields = new ArrayList<>();
217 NodeFieldData[] resolvedFields = getFields();
218 if (fields != null) {
219 for (NodeFieldData field : resolvedFields) {
220 if (usage == null || field.getExecutionKind() == usage) {
221 if (fieldKind == null || field.getKind() == fieldKind) {
222 filteredFields.add(field);
223 }
224 }
225 }
226 }
227 return filteredFields.toArray(new NodeFieldData[filteredFields.size()]);
228 }
229
230 public boolean hasUnexpectedExecutableTypes(ProcessorContext context) {
231 for (ExecutableTypeData type : getExecutableTypes()) {
232 if (type.hasUnexpectedValue(context)) {
233 return true;
234 }
235 }
236 return false;
237 }
238
239 public boolean needsRewrites(ProcessorContext context) {
240 boolean needsRewrites = false;
241 for (NodeFieldData field : getFields()) {
242 if (field.getExecutionKind() == ExecutionKind.DEFAULT
243 || field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
244 if (!field.getNodeData().hasUnexpectedExecutableTypes(context)) {
245 continue;
246 }
247
248 needsRewrites = true;
249 break;
250 }
251 }
252
253 needsRewrites &= specializations.length >= 2;
254 return needsRewrites;
255 }
256
257 public SpecializationData getGenericSpecialization() {
258 for (SpecializationData specialization : specializations) {
259 if (specialization.isGeneric()) {
260 return specialization;
261 }
262 }
263 return null;
264 }
265
266 public TypeSystemData getTypeSystem() {
267 if (typeSystem != null) {
268 return typeSystem;
269 } else {
270 return null;
271 }
272 }
273
274 public NodeFieldData[] getFields() {
275 return fields;
276 }
277
278 public NodeFieldData[] getDeclaredFields() {
279 return fields;
280 }
281
282 public SpecializationData[] getSpecializations() {
283 return specializations;
284 }
285
286 public String dump() {
287 StringBuilder b = new StringBuilder();
288 b.append(String.format("[name = %s\n" +
289 " typeSystem = %s\n" +
290 " fields = %s\n" +
291 " types = %s\n" +
292 " specializations = %s\n" +
293 " guards = %s\n" +
294 "]", Utils.getQualifiedName(getTemplateType()),
295 getTypeSystem(),
296 dumpList(fields),
297 dumpList(getExecutableTypes()),
298 dumpList(getSpecializations()),
299 dumpList(guards)
300 ));
301 return b.toString();
302 }
303
304 private static String dumpList(Object[] array) {
305 if (array == null) {
306 return "null";
307 }
308
309 StringBuilder b = new StringBuilder();
310 b.append("[");
311 for (Object object : array) {
312 b.append("\n");
313 b.append(" ");
314 b.append(object);
315 b.append(", ");
316 }
317 b.append("\n ]");
318 return b.toString();
319 }
320
321 public NodeFieldData findField(String name) {
322 for (NodeFieldData field : getFields()) {
323 if (field.getName().equals(name)) {
324 return field;
325 }
326 }
327 return null;
328 }
329
330
331
332 }