Mercurial > hg > graal-compiler
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 } |