comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/SpecializationGroup.java @ 19283:08aa0372dad4

Truffle-DSL: implement new guard expression syntax.
author Christian Humer <christian.humer@gmail.com>
date Fri, 23 Jan 2015 02:55:23 +0100
parents ae81dd154fb6
children 62c43fcf5be2
comparison
equal deleted inserted replaced
19282:ae81dd154fb6 19283:08aa0372dad4
22 */ 22 */
23 package com.oracle.truffle.dsl.processor.parser; 23 package com.oracle.truffle.dsl.processor.parser;
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import javax.lang.model.type.*; 27 import com.oracle.truffle.dsl.processor.generator.*;
28
29 import com.oracle.truffle.dsl.processor.java.*;
30 import com.oracle.truffle.dsl.processor.model.*; 28 import com.oracle.truffle.dsl.processor.model.*;
31 import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature; 29 import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature;
32 30
33 /** 31 /**
34 * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize 32 * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize
108 106
109 if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { 107 if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) {
110 return null; 108 return null;
111 } 109 }
112 110
111 if (previous.mayBeExcluded()) {
112 return null;
113 }
114
113 /* Guard is else branch can be connected in previous specialization. */ 115 /* Guard is else branch can be connected in previous specialization. */
114 if (elseConnectedGuards.contains(guard)) { 116 if (elseConnectedGuards.contains(guard)) {
115 return guard; 117 return guard;
116 } 118 }
117 119
118 GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size()); 120 GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size());
119 if (guard.getResolvedGuard().getMethod().equals(previousGuard.getResolvedGuard().getMethod()) && guard.isNegated() != previousGuard.isNegated()) { 121 if (guard.equalsNegated(previousGuard)) {
120 return guard; 122 return guard;
121 } 123 }
122 return null; 124 return null;
125 }
126
127 private boolean mayBeExcluded() {
128 if (specialization != null) {
129 return NodeGenFactory.mayBeExcluded(specialization);
130 } else {
131 for (SpecializationGroup group : getChildren()) {
132 if (group.mayBeExcluded()) {
133 return true;
134 }
135 }
136 }
137 return false;
123 } 138 }
124 139
125 private void updateChildren(List<SpecializationGroup> childs) { 140 private void updateChildren(List<SpecializationGroup> childs) {
126 if (!children.isEmpty()) { 141 if (!children.isEmpty()) {
127 children.clear(); 142 children.clear();
202 } 217 }
203 218
204 // check for guards for required type casts 219 // check for guards for required type casts
205 for (Iterator<GuardExpression> iterator = guardMatches.iterator(); iterator.hasNext();) { 220 for (Iterator<GuardExpression> iterator = guardMatches.iterator(); iterator.hasNext();) {
206 GuardExpression guardMatch = iterator.next(); 221 GuardExpression guardMatch = iterator.next();
207 222 if (!guardMatch.getExpression().findBoundVariables().isEmpty()) {
208 int signatureIndex = 0;
209 for (Parameter parameter : guardMatch.getResolvedGuard().getParameters()) {
210 signatureIndex++;
211 if (!parameter.getSpecification().isSignature()) {
212 continue;
213 }
214
215 TypeMirror guardType = parameter.getType();
216
217 // object guards can be safely moved up
218 if (ElementUtils.isObject(guardType)) {
219 continue;
220 }
221
222 // generic guards can be safely moved up
223 SpecializationData generic = first.node.getGenericSpecialization();
224 if (generic != null) {
225 Parameter genericParameter = generic.findParameter(parameter.getLocalName());
226 if (genericParameter != null && ElementUtils.typeEquals(genericParameter.getType(), guardType)) {
227 continue;
228 }
229 }
230
231 // signature index required for moving up guards
232 if (containsIndex(typeGuardsMatches, signatureIndex) || (first.getParent() != null && first.getParent().containsTypeGuardIndex(signatureIndex))) {
233 continue;
234 }
235
236 iterator.remove(); 223 iterator.remove();
237 break; 224 }
238 } 225 // TODO we need to be smarter here with bound parameters.
239 } 226 }
240 227
241 if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) { 228 if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) {
242 return null; 229 return null;
243 } 230 }
248 group.guards.removeAll(guardMatches); 235 group.guards.removeAll(guardMatches);
249 } 236 }
250 237
251 List<SpecializationGroup> newChildren = new ArrayList<>(groups); 238 List<SpecializationGroup> newChildren = new ArrayList<>(groups);
252 return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches); 239 return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches);
253 }
254
255 private boolean containsTypeGuardIndex(int index) {
256 if (containsIndex(typeGuards, index)) {
257 return true;
258 }
259 if (parent != null) {
260 return parent.containsTypeGuardIndex(index);
261 }
262 return false;
263 }
264
265 private static boolean containsIndex(List<TypeGuard> typeGuards, int signatureIndex) {
266 for (TypeGuard guard : typeGuards) {
267 if (guard.signatureIndex == signatureIndex) {
268 return true;
269 }
270 }
271 return false;
272 } 240 }
273 241
274 public static SpecializationGroup create(SpecializationData specialization) { 242 public static SpecializationGroup create(SpecializationData specialization) {
275 return new SpecializationGroup(specialization); 243 return new SpecializationGroup(specialization);
276 } 244 }