comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java @ 11195:4f52b08bd2f9

Truffle-DSL: Implemented specialization grouping for generic cases.
author Christian Humer <christian.humer@gmail.com>
date Thu, 01 Aug 2013 20:53:54 +0200
parents
children 7fc3e1fb3965
comparison
equal deleted inserted replaced
11194:14d5ff4683e0 11195:4f52b08bd2f9
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.node;
24
25 import java.util.*;
26
27 import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature;
28 import com.oracle.truffle.dsl.processor.typesystem.*;
29
30 /**
31 * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize
32 * and generic execute methods.
33 */
34 public final class SpecializationGroup {
35
36 private final List<String> assumptions;
37 private final List<TypeData> typeGuards;
38 private final List<GuardData> guards;
39
40 private final SpecializationData specialization;
41 private final List<SpecializationGroup> children = new ArrayList<>();
42
43 private SpecializationGroup parent;
44
45 private SpecializationGroup(SpecializationData data) {
46 this.assumptions = new ArrayList<>();
47 this.typeGuards = new ArrayList<>();
48 this.guards = new ArrayList<>();
49 this.specialization = data;
50
51 this.assumptions.addAll(data.getAssumptions());
52 Signature sig = data.getSignature();
53 for (int i = 1; i < sig.size(); i++) {
54 typeGuards.add(sig.get(i));
55 }
56 this.guards.addAll(data.getGuards());
57 }
58
59 public SpecializationGroup(List<SpecializationGroup> children, List<String> assumptionMatches, List<TypeData> typeGuardsMatches, List<GuardData> guardMatches) {
60 this.assumptions = assumptionMatches;
61 this.typeGuards = typeGuardsMatches;
62 this.guards = guardMatches;
63 this.specialization = null;
64 updateChildren(children);
65 }
66
67 private void updateChildren(List<SpecializationGroup> childs) {
68 if (!children.isEmpty()) {
69 children.clear();
70 }
71 this.children.addAll(childs);
72 for (SpecializationGroup child : childs) {
73 child.parent = this;
74 }
75 }
76
77 public int getTypeGuardOffset() {
78 return (parent != null ? parent.getTypeGuardOffsetRec() : 0);
79 }
80
81 private int getTypeGuardOffsetRec() {
82 return typeGuards.size() + (parent != null ? parent.getTypeGuardOffsetRec() : 0);
83 }
84
85 public SpecializationGroup getParent() {
86 return parent;
87 }
88
89 public List<String> getAssumptions() {
90 return assumptions;
91 }
92
93 public List<TypeData> getTypeGuards() {
94 return typeGuards;
95 }
96
97 public List<GuardData> getGuards() {
98 return guards;
99 }
100
101 public List<SpecializationGroup> getChildren() {
102 return children;
103 }
104
105 public SpecializationData getSpecialization() {
106 return specialization;
107 }
108
109 private static SpecializationGroup combine(List<SpecializationGroup> groups) {
110 if (groups.isEmpty()) {
111 throw new IllegalArgumentException("empty combinations");
112 }
113 if (groups.size() == 1) {
114 return null;
115 }
116
117 List<String> assumptionMatches = new ArrayList<>();
118 List<TypeData> typeGuardsMatches = new ArrayList<>();
119 List<GuardData> guardMatches = new ArrayList<>();
120
121 SpecializationGroup first = groups.get(0);
122 List<SpecializationGroup> others = groups.subList(1, groups.size());
123
124 outer: for (String assumption : first.assumptions) {
125 for (SpecializationGroup other : others) {
126 if (!other.assumptions.contains(assumption)) {
127 // assumptions can be combined unordered
128 continue outer;
129 }
130 }
131 assumptionMatches.add(assumption);
132 }
133
134 int typeGuardIndex = 0;
135 outer: for (TypeData typeGuard : first.typeGuards) {
136 for (SpecializationGroup other : others) {
137 if (typeGuardIndex >= other.typeGuards.size()) {
138 break outer;
139 }
140
141 if (!other.typeGuards.get(typeGuardIndex).equals(typeGuard)) {
142 break outer;
143 }
144 }
145 typeGuardsMatches.add(typeGuard);
146 typeGuardIndex++;
147 }
148
149 outer: for (GuardData guard : first.guards) {
150 for (SpecializationGroup other : others) {
151 if (!other.guards.contains(guard)) {
152 // we must break here. One guard may depend on the other.
153 break outer;
154 }
155 }
156 guardMatches.add(guard);
157 }
158
159 if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) {
160 return null;
161 }
162
163 for (SpecializationGroup group : groups) {
164 group.assumptions.removeAll(assumptionMatches);
165 group.typeGuards.subList(0, typeGuardIndex).clear();
166 group.guards.removeAll(guardMatches);
167 }
168
169 List<SpecializationGroup> newChildren = new ArrayList<>(groups);
170 return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches);
171 }
172
173 public static List<SpecializationGroup> create(List<SpecializationData> specializations) {
174 List<SpecializationGroup> groups = new ArrayList<>();
175 for (SpecializationData specialization : specializations) {
176 groups.add(new SpecializationGroup(specialization));
177 }
178 return createCombinationalGroups(groups);
179 }
180
181 @Override
182 public String toString() {
183 return "SpecializationGroup [assumptions=" + assumptions + ", typeGuards=" + typeGuards + ", guards=" + guards + "]";
184 }
185
186 private static List<SpecializationGroup> createCombinationalGroups(List<SpecializationGroup> groups) {
187 if (groups.size() <= 1) {
188 return groups;
189 }
190 List<SpecializationGroup> newGroups = new ArrayList<>();
191
192 int i = 0;
193 for (i = 0; i < groups.size();) {
194 SpecializationGroup combined = null;
195 for (int j = groups.size(); j > i + 1; j--) {
196 combined = combine(groups.subList(i, j));
197 if (combined != null) {
198 break;
199 }
200 }
201 SpecializationGroup newGroup;
202 if (combined == null) {
203 newGroup = groups.get(i);
204 i++;
205 } else {
206 newGroup = combined;
207 List<SpecializationGroup> originalGroups = new ArrayList<>(combined.children);
208 combined.updateChildren(createCombinationalGroups(originalGroups));
209 i += originalGroups.size();
210 }
211
212 newGroups.add(newGroup);
213
214 }
215
216 return newGroups;
217 }
218
219 public SpecializationGroup getPreviousGroup() {
220 if (parent == null || parent.children.isEmpty()) {
221 return null;
222 }
223 int index = parent.children.indexOf(this);
224 if (index <= 0) {
225 return null;
226 }
227 return parent.children.get(index - 1);
228 }
229
230 public int getMaxSpecializationIndex() {
231 if (specialization != null) {
232 return specialization.getNode().getSpecializations().indexOf(specialization);
233 } else {
234 int max = Integer.MIN_VALUE;
235 for (SpecializationGroup childGroup : getChildren()) {
236 max = Math.max(max, childGroup.getMaxSpecializationIndex());
237 }
238 return max;
239 }
240 }
241 }