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