]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / elaboration / profiling / BranchPointInjector.java
1 package org.simantics.scl.compiler.internal.elaboration.profiling;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.elaboration.expressions.Case;
6 import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;
8 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
9 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
10 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
11 import org.simantics.scl.compiler.elaboration.expressions.EBind;
12 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
13 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
14 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
15 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
16 import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
17 import org.simantics.scl.compiler.elaboration.expressions.EError;
18 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
19 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
20 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
21 import org.simantics.scl.compiler.elaboration.expressions.EIf;
22 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
23 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
24 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
25 import org.simantics.scl.compiler.elaboration.expressions.ELet;
26 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
27 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
28 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
29 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
30 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
31 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
32 import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset;
33 import org.simantics.scl.compiler.elaboration.expressions.ERange;
34 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
35 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
36 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
37 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
38 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
39 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
40 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
41 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
42 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
43 import org.simantics.scl.compiler.elaboration.expressions.EVar;
44 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
45 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
46 import org.simantics.scl.compiler.elaboration.expressions.Expression;
47 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
48 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
49 import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionTransformer;
50 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
51 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
52 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
53 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
54 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
55 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
56 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
57 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
58 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
59 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
60 import org.simantics.scl.compiler.elaboration.query.QAlternative;
61 import org.simantics.scl.compiler.elaboration.query.QAtom;
62 import org.simantics.scl.compiler.elaboration.query.QConjunction;
63 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
64 import org.simantics.scl.compiler.elaboration.query.QExists;
65 import org.simantics.scl.compiler.elaboration.query.QIf;
66 import org.simantics.scl.compiler.elaboration.query.QMapping;
67 import org.simantics.scl.compiler.elaboration.query.QNegation;
68 import org.simantics.scl.compiler.elaboration.query.Query;
69 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
70 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
71 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
72 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
73 import org.simantics.scl.runtime.profiling.BranchPoint;
74
75 public class BranchPointInjector extends StandardExpressionTransformer {
76     public ArrayList<BranchPoint> currentBranchPoints = new ArrayList<BranchPoint>();
77     int codeCounter = 0;
78     
79     public Expression injectBranchPoint(Expression expression) {
80         ArrayList<BranchPoint> oldBranchPoints = currentBranchPoints;
81         currentBranchPoints = new ArrayList<BranchPoint>();
82         int beginCodeCounter = codeCounter;
83         expression = expression.accept(this);
84         BranchPoint branchPoint = new BranchPoint(expression.location,
85                 codeCounter - beginCodeCounter,
86                 currentBranchPoints.isEmpty() ? BranchPoint.EMPTY_ARRAY
87                         : currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]));
88         oldBranchPoints.add(branchPoint);
89         currentBranchPoints = oldBranchPoints;
90         return new ECoveringBranchPoint(expression, branchPoint);
91     }
92     
93     @Override
94     public Expression transform(ESimpleLambda expression) {
95         ++codeCounter;
96         expression.value = injectBranchPoint(expression.value);
97         return expression;
98     }
99     
100     @Override
101     public Expression transform(ELambda expression) {
102         ++codeCounter;
103         for(Case case_ : expression.cases)
104             case_.value = injectBranchPoint(case_.value);
105         return expression;
106     }
107     
108     @Override
109     public Expression transform(EMatch expression) {
110         ++codeCounter;
111         for(int i=0;i<expression.scrutinee.length;++i)
112             expression.scrutinee[i] = expression.scrutinee[i].accept(this);
113         for(Case case_ : expression.cases)
114             case_.value = injectBranchPoint(case_.value);
115         return expression;
116     }
117     
118     @Override
119     public Expression transform(EIf expression) {
120         ++codeCounter;
121         expression.condition = expression.condition.accept(this);
122         expression.then_ = injectBranchPoint(expression.then_);
123         expression.else_ = injectBranchPoint(expression.else_);
124         return expression;
125     }
126     
127     @Override
128     public Expression transform(EBind expression) {
129         ++codeCounter;
130         expression.pattern = expression.pattern.accept(this);
131         expression.value = expression.value.accept(this);
132         expression.in = injectBranchPoint(expression.in);
133         return expression;
134     }
135     
136     @Override
137     public Expression transform(EListComprehension expression) {
138         ++codeCounter;
139         expression.head = injectBranchPoint(expression.head);
140         expression.qualifier =  expression.qualifier.accept(this);
141         return expression;
142     }
143     
144     @Override
145     public Expression transform(EWhen expression) {
146         ++codeCounter;
147         expression.query = expression.query.accept(this);
148         expression.action = injectBranchPoint(expression.action);
149         return expression;
150     }
151
152     @Override
153     public Expression transform(GuardedExpressionGroup expression) {
154         ++codeCounter;
155         for(GuardedExpression ge : expression.expressions) {
156             for(int i=0;i<ge.guards.length;++i)
157                 ge.guards[i] = ge.guards[i].accept(this);
158             ge.value = injectBranchPoint(ge.value);
159         }
160         return expression;
161     }
162     
163     @Override
164     public Expression transform(EAmbiguous expression) {
165         ++codeCounter;
166         return super.transform(expression);
167     }
168     
169     @Override
170     public Expression transform(EApply expression) {
171         ++codeCounter;
172         return super.transform(expression);
173     }
174     
175     @Override
176     public Expression transform(EApplyType expression) {
177         ++codeCounter;
178         return super.transform(expression);
179     }
180     
181     @Override
182     public Expression transform(EAsPattern expression) {
183         ++codeCounter;
184         return super.transform(expression);
185     }
186     
187     @Override
188     public Expression transform(EBinary expression) {
189         ++codeCounter;
190         return super.transform(expression);
191     }
192     
193     @Override
194     public Expression transform(EBlock expression) {
195         ++codeCounter;
196         return super.transform(expression);
197     }
198     
199     @Override
200     public Expression transform(EConstant expression) {
201         ++codeCounter;
202         return super.transform(expression);
203     }
204     
205     @Override
206     public Expression transform(ECoveringBranchPoint expression) {
207         ++codeCounter;
208         return super.transform(expression);
209     }
210     
211     @Override
212     public Expression transform(EEnforce expression) {
213         ++codeCounter;
214         return super.transform(expression);
215     }
216     
217     @Override
218     public Expression transform(EEntityTypeAnnotation expression) {
219         ++codeCounter;
220         return super.transform(expression);
221     }
222     
223     @Override
224     public Expression transform(EError expression) {
225         ++codeCounter;
226         return super.transform(expression);
227     }
228     
229     @Override
230     public Expression transform(EExternalConstant expression) {
231         ++codeCounter;
232         return super.transform(expression);
233     }
234     
235     @Override
236     public Expression transform(EFieldAccess expression) {
237         ++codeCounter;
238         return super.transform(expression);
239     }
240     
241     @Override
242     public Expression transform(EGetConstraint expression) {
243         ++codeCounter;
244         return super.transform(expression);
245     }
246     
247     @Override
248     public Expression transform(EIntegerLiteral expression) {
249         ++codeCounter;
250         return super.transform(expression);
251     }
252     
253     @Override
254     public Expression transform(ELambdaType expression) {
255         ++codeCounter;
256         return super.transform(expression);
257     }
258     
259     @Override
260     public Expression transform(ELet expression) {
261         ++codeCounter;
262         return super.transform(expression);
263     }
264     
265     @Override
266     public Expression transform(EListLiteral expression) {
267         ++codeCounter;
268         return super.transform(expression);
269     }
270     
271     @Override
272     public Expression transform(ELiteral expression) {
273         ++codeCounter;
274         return super.transform(expression);
275     }
276     
277     @Override
278     public Expression transform(EPlaceholder expression) {
279         ++codeCounter;
280         return super.transform(expression);
281     }
282     
283     @Override
284     public Expression transform(EPreLet expression) {
285         ++codeCounter;
286         return super.transform(expression);
287     }
288     
289     @Override
290     public Expression transform(EPreRuleset expression) {
291         ++codeCounter;
292         return super.transform(expression);
293     }
294     
295     @Override
296     public Expression transform(ERange expression) {
297         ++codeCounter;
298         return super.transform(expression);
299     }
300     
301     @Override
302     public Expression transform(ERealLiteral expression) {
303         ++codeCounter;
304         return super.transform(expression);
305     }
306     
307     @Override
308     public Expression transform(ERecord expression) {
309         ++codeCounter;
310         return super.transform(expression);
311     }
312     
313     @Override
314     public Expression transform(ERuleset expression) {
315         ++codeCounter;
316         return super.transform(expression);
317     }
318     
319     @Override
320     public Expression transform(ESelect expression) {
321         ++codeCounter;
322         return super.transform(expression);
323     }
324     
325     @Override
326     public Expression transform(ESimpleLet expression) {
327         ++codeCounter;
328         return super.transform(expression);
329     }
330     
331     @Override
332     public Expression transform(EStringLiteral expression) {
333         ++codeCounter;
334         return super.transform(expression);
335     }
336     
337     @Override
338     public Expression transform(ETransformation expression) {
339         ++codeCounter;
340         return super.transform(expression);
341     }
342     
343     @Override
344     public Expression transform(ETypeAnnotation expression) {
345         ++codeCounter;
346         return super.transform(expression);
347     }
348     
349     @Override
350     public Expression transform(EVar expression) {
351         ++codeCounter;
352         return super.transform(expression);
353     }
354     
355     @Override
356     public Expression transform(EVariable expression) {
357         ++codeCounter;
358         return super.transform(expression);
359     }
360     
361     @Override
362     public ListQualifier transform(ListAssignment qualifier) {
363         ++codeCounter;
364         return super.transform(qualifier);
365     }
366     
367     @Override
368     public ListQualifier transform(ListGenerator qualifier) {
369         ++codeCounter;
370         return super.transform(qualifier);
371     }
372     
373     @Override
374     public ListQualifier transform(ListGuard qualifier) {
375         ++codeCounter;
376         return super.transform(qualifier);
377     }
378     
379     @Override
380     public ListQualifier transform(ListSeq qualifier) {
381         ++codeCounter;
382         return super.transform(qualifier);
383     }
384     
385     @Override
386     public ListQualifier transform(ListThen qualifier) {
387         ++codeCounter;
388         return super.transform(qualifier);
389     }
390     
391     @Override
392     public Query transform(QAlternative query) {
393         ++codeCounter;
394         return super.transform(query);
395     }
396     
397     @Override
398     public Query transform(QAtom query) {
399         ++codeCounter;
400         return super.transform(query);
401     }
402     
403     @Override
404     public Query transform(QConjunction query) {
405         ++codeCounter;
406         return super.transform(query);
407     }
408     
409     @Override
410     public Query transform(QDisjunction query) {
411         ++codeCounter;
412         return super.transform(query);
413     }
414     
415     @Override
416     public Query transform(QExists query) {
417         ++codeCounter;
418         return super.transform(query);
419     }
420     
421     @Override
422     public Query transform(QIf query) {
423         ++codeCounter;
424         return super.transform(query);
425     }
426     
427     @Override
428     public Query transform(QMapping query) {
429         ++codeCounter;
430         return super.transform(query);
431     }
432     
433     @Override
434     public Query transform(QNegation query) {
435         ++codeCounter;
436         return super.transform(query);
437     }
438     
439     @Override
440     public Query transform(QPreBinds query) {
441         ++codeCounter;
442         return super.transform(query);
443     }
444     
445     @Override
446     public Query transform(QPreEquals query) {
447         ++codeCounter;
448         return super.transform(query);
449     }
450     
451     @Override
452     public Query transform(QPreExists query) {
453         ++codeCounter;
454         return super.transform(query);
455     }
456     
457     @Override
458     public Query transform(QPreGuard query) {
459         ++codeCounter;
460         return super.transform(query);
461     }
462     
463     public BranchPoint[] getAndClearBranchPoints() {
464         BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
465         currentBranchPoints.clear();
466         return result;
467     }
468     
469     @Override
470     public void visit(BindStatement statement) {
471         ++codeCounter;
472         super.visit(statement);
473     }
474     
475     @Override
476     public void visit(GuardStatement statement) {
477         ++codeCounter;
478         super.visit(statement);
479     }
480     
481     @Override
482     public void visit(LetStatement statement) {
483         ++codeCounter;
484         if(statement.pattern.isFunctionDefinitionLhs())
485             statement.value = injectBranchPoint(statement.value);
486         else
487             super.visit(statement);
488     }
489     
490     @Override
491     public void visit(RuleStatement statement) {
492         ++codeCounter;
493         super.visit(statement);
494     }
495     
496 }