comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java @ 11442:2868b55001d4

Truffle-DSL: fixed specializationg grouping failed with guards using base types.
author Christian Humer <christian.humer@gmail.com>
date Wed, 28 Aug 2013 01:45:13 +0200
parents 7fc3e1fb3965
children b33783cbd8ce
comparison
equal deleted inserted replaced
11441:fc509b6fbfdf 11442:2868b55001d4
22 */ 22 */
23 package com.oracle.truffle.dsl.processor.node; 23 package com.oracle.truffle.dsl.processor.node;
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import javax.lang.model.type.*;
28
29 import com.oracle.truffle.dsl.processor.*;
30 import com.oracle.truffle.dsl.processor.template.*;
27 import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; 31 import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature;
28 import com.oracle.truffle.dsl.processor.typesystem.*; 32 import com.oracle.truffle.dsl.processor.typesystem.*;
29 33
30 /** 34 /**
31 * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize 35 * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize
62 this.guards = guardMatches; 66 this.guards = guardMatches;
63 this.specialization = null; 67 this.specialization = null;
64 updateChildren(children); 68 updateChildren(children);
65 } 69 }
66 70
71 public List<TypeGuard> getAllGuards() {
72 List<TypeGuard> collectedGuards = new ArrayList<>();
73 collectedGuards.addAll(typeGuards);
74 if (parent != null) {
75 collectedGuards.addAll(parent.getAllGuards());
76 }
77 return collectedGuards;
78 }
79
67 public TypeGuard findTypeGuard(int signatureIndex) { 80 public TypeGuard findTypeGuard(int signatureIndex) {
68 for (TypeGuard guard : typeGuards) { 81 for (TypeGuard guard : typeGuards) {
69 if (guard.getSignatureIndex() == signatureIndex) { 82 if (guard.getSignatureIndex() == signatureIndex) {
70 return guard; 83 return guard;
71 } 84 }
72 } 85 }
73 return null; 86 return null;
74 } 87 }
75 88
76 public GuardData getElseConnectableGuard() { 89 public List<GuardData> getElseConnectableGuards() {
77 if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) { 90 if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) {
78 return null; 91 return Collections.emptyList();
79 } 92 }
80 SpecializationGroup previousGroup = getPreviousGroup(); 93
81 if (previousGroup != null && getGuards().size() >= 1 && previousGroup.getGuards().size() == 1) { 94 if (getGuards().isEmpty()) {
82 GuardData guard = getGuards().get(0); 95 return Collections.emptyList();
83 GuardData previousGuard = previousGroup.getGuards().get(0); 96 }
84 97
98 List<GuardData> elseConnectableGuards = new ArrayList<>();
99 int guardIndex = 0;
100 while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) {
101 elseConnectableGuards.add(getGuards().get(guardIndex));
102 guardIndex++;
103 }
104
105 return elseConnectableGuards;
106 }
107
108 private GuardData findNegatedGuardInPrevious(GuardData guard) {
109 SpecializationGroup previous = this;
110 while ((previous = previous.getPreviousGroup()) != null) {
111 List<GuardData> elseConnectedGuards = previous.getElseConnectableGuards();
112
113 if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) {
114 return null;
115 }
116 GuardData previousGuard = previous.getGuards().get(elseConnectedGuards.size());
85 if (guard.getMethod().equals(previousGuard.getMethod())) { 117 if (guard.getMethod().equals(previousGuard.getMethod())) {
86 assert guard.isNegated() != previousGuard.isNegated(); 118 assert guard.isNegated() != previousGuard.isNegated();
87 return guard; 119 return guard;
88 } 120 }
89 } 121 }
167 } 199 }
168 } 200 }
169 guardMatches.add(guard); 201 guardMatches.add(guard);
170 } 202 }
171 203
204 // check for guards for required type casts
205 for (Iterator<GuardData> iterator = guardMatches.iterator(); iterator.hasNext();) {
206 GuardData guardMatch = iterator.next();
207
208 List<TypeMirror> guardTypes = TemplateMethod.getSignatureTypes(guardMatch.getParameters());
209 for (int i = 0; i < guardTypes.size(); i++) {
210 TypeMirror guardType = guardTypes.get(i);
211 int signatureIndex = i + 1;
212
213 // object guards can be safely moved up
214 if (Utils.isObject(guardType)) {
215 continue;
216 }
217
218 // signature index required for moving up guards
219 if (containsIndex(typeGuardsMatches, signatureIndex) || (first.getParent() != null && first.getParent().containsTypeGuardIndex(signatureIndex))) {
220 continue;
221 }
222
223 iterator.remove();
224 break;
225 }
226 }
227
172 if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) { 228 if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) {
173 return null; 229 return null;
174 } 230 }
175 231
176 for (SpecializationGroup group : groups) { 232 for (SpecializationGroup group : groups) {
179 group.guards.removeAll(guardMatches); 235 group.guards.removeAll(guardMatches);
180 } 236 }
181 237
182 List<SpecializationGroup> newChildren = new ArrayList<>(groups); 238 List<SpecializationGroup> newChildren = new ArrayList<>(groups);
183 return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches); 239 return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches);
240 }
241
242 private boolean containsTypeGuardIndex(int index) {
243 if (containsIndex(typeGuards, index)) {
244 return true;
245 }
246 if (parent != null) {
247 return parent.containsTypeGuardIndex(index);
248 }
249 return false;
250 }
251
252 private static boolean containsIndex(List<TypeGuard> typeGuards, int signatureIndex) {
253 for (TypeGuard guard : typeGuards) {
254 if (guard.signatureIndex == signatureIndex) {
255 return true;
256 }
257 }
258 return false;
184 } 259 }
185 260
186 public static SpecializationGroup create(List<SpecializationData> specializations) { 261 public static SpecializationGroup create(List<SpecializationData> specializations) {
187 List<SpecializationGroup> groups = new ArrayList<>(); 262 List<SpecializationGroup> groups = new ArrayList<>();
188 for (SpecializationData specialization : specializations) { 263 for (SpecializationData specialization : specializations) {