(refs #7375) Replaced collectFreeVariables method by a visitor
[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.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.block.BindStatement;
50 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
51 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
52 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
53 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
54 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
55 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
56 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
57 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
58 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
59 import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer;
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         if(expression.else_ != null)
124             expression.else_ = injectBranchPoint(expression.else_);
125         return expression;
126     }
127     
128     @Override
129     public Expression transform(EBind expression) {
130         ++codeCounter;
131         expression.pattern = expression.pattern.accept(this);
132         expression.value = expression.value.accept(this);
133         expression.in = injectBranchPoint(expression.in);
134         return expression;
135     }
136     
137     @Override
138     public Expression transform(EListComprehension expression) {
139         ++codeCounter;
140         expression.head = injectBranchPoint(expression.head);
141         expression.qualifier =  expression.qualifier.accept(this);
142         return expression;
143     }
144     
145     @Override
146     public Expression transform(EWhen expression) {
147         ++codeCounter;
148         expression.query = expression.query.accept(this);
149         expression.action = injectBranchPoint(expression.action);
150         return expression;
151     }
152
153     @Override
154     public Expression transform(GuardedExpressionGroup expression) {
155         ++codeCounter;
156         for(GuardedExpression ge : expression.expressions) {
157             for(int i=0;i<ge.guards.length;++i)
158                 ge.guards[i] = ge.guards[i].accept(this);
159             ge.value = injectBranchPoint(ge.value);
160         }
161         return expression;
162     }
163     
164     @Override
165     public Expression transform(EAmbiguous expression) {
166         ++codeCounter;
167         return super.transform(expression);
168     }
169     
170     @Override
171     public Expression transform(EApply expression) {
172         ++codeCounter;
173         return super.transform(expression);
174     }
175     
176     @Override
177     public Expression transform(EApplyType expression) {
178         ++codeCounter;
179         return super.transform(expression);
180     }
181     
182     @Override
183     public Expression transform(EAsPattern expression) {
184         ++codeCounter;
185         return super.transform(expression);
186     }
187     
188     @Override
189     public Expression transform(EBinary expression) {
190         ++codeCounter;
191         return super.transform(expression);
192     }
193     
194     @Override
195     public Expression transform(EBlock expression) {
196         ++codeCounter;
197         return super.transform(expression);
198     }
199     
200     @Override
201     public Expression transform(ECHRRuleset expression) {
202         ++codeCounter;
203         return super.transform(expression);
204     }
205     
206     @Override
207     public Expression transform(EConstant expression) {
208         ++codeCounter;
209         return super.transform(expression);
210     }
211     
212     @Override
213     public Expression transform(ECoveringBranchPoint expression) {
214         ++codeCounter;
215         return super.transform(expression);
216     }
217     
218     @Override
219     public Expression transform(EEnforce expression) {
220         ++codeCounter;
221         return super.transform(expression);
222     }
223     
224     @Override
225     public Expression transform(EError expression) {
226         ++codeCounter;
227         return super.transform(expression);
228     }
229     
230     @Override
231     public Expression transform(EExternalConstant expression) {
232         ++codeCounter;
233         return super.transform(expression);
234     }
235     
236     @Override
237     public Expression transform(EFieldAccess expression) {
238         ++codeCounter;
239         return super.transform(expression);
240     }
241     
242     @Override
243     public Expression transform(EGetConstraint expression) {
244         ++codeCounter;
245         return super.transform(expression);
246     }
247     
248     @Override
249     public Expression transform(EIntegerLiteral expression) {
250         ++codeCounter;
251         return super.transform(expression);
252     }
253     
254     @Override
255     public Expression transform(ELambdaType expression) {
256         ++codeCounter;
257         return super.transform(expression);
258     }
259     
260     @Override
261     public Expression transform(ELet expression) {
262         ++codeCounter;
263         return super.transform(expression);
264     }
265     
266     @Override
267     public Expression transform(EListLiteral expression) {
268         ++codeCounter;
269         return super.transform(expression);
270     }
271     
272     @Override
273     public Expression transform(ELiteral expression) {
274         ++codeCounter;
275         return super.transform(expression);
276     }
277     
278     @Override
279     public Expression transform(EPlaceholder expression) {
280         ++codeCounter;
281         return super.transform(expression);
282     }
283     
284     @Override
285     public Expression transform(EPreLet expression) {
286         ++codeCounter;
287         return super.transform(expression);
288     }
289     
290     @Override
291     public Expression transform(EPreRuleset expression) {
292         ++codeCounter;
293         return super.transform(expression);
294     }
295     
296     @Override
297     public Expression transform(ERange expression) {
298         ++codeCounter;
299         return super.transform(expression);
300     }
301     
302     @Override
303     public Expression transform(ERealLiteral expression) {
304         ++codeCounter;
305         return super.transform(expression);
306     }
307     
308     @Override
309     public Expression transform(ERecord expression) {
310         ++codeCounter;
311         return super.transform(expression);
312     }
313     
314     @Override
315     public Expression transform(ERuleset expression) {
316         ++codeCounter;
317         return super.transform(expression);
318     }
319     
320     @Override
321     public Expression transform(ESelect expression) {
322         ++codeCounter;
323         return super.transform(expression);
324     }
325     
326     @Override
327     public Expression transform(ESimpleLet expression) {
328         ++codeCounter;
329         return super.transform(expression);
330     }
331     
332     @Override
333     public Expression transform(EStringLiteral expression) {
334         ++codeCounter;
335         return super.transform(expression);
336     }
337     
338     @Override
339     public Expression transform(ETransformation expression) {
340         ++codeCounter;
341         return super.transform(expression);
342     }
343     
344     @Override
345     public Expression transform(ETypeAnnotation expression) {
346         ++codeCounter;
347         return super.transform(expression);
348     }
349     
350     @Override
351     public Expression transform(EVar expression) {
352         ++codeCounter;
353         return super.transform(expression);
354     }
355     
356     @Override
357     public Expression transform(EVariable expression) {
358         ++codeCounter;
359         return super.transform(expression);
360     }
361     
362     @Override
363     public ListQualifier transform(ListAssignment qualifier) {
364         ++codeCounter;
365         return super.transform(qualifier);
366     }
367     
368     @Override
369     public ListQualifier transform(ListGenerator qualifier) {
370         ++codeCounter;
371         return super.transform(qualifier);
372     }
373     
374     @Override
375     public ListQualifier transform(ListGuard qualifier) {
376         ++codeCounter;
377         return super.transform(qualifier);
378     }
379     
380     @Override
381     public ListQualifier transform(ListSeq qualifier) {
382         ++codeCounter;
383         return super.transform(qualifier);
384     }
385     
386     @Override
387     public ListQualifier transform(ListThen qualifier) {
388         ++codeCounter;
389         return super.transform(qualifier);
390     }
391     
392     @Override
393     public Query transform(QAlternative query) {
394         ++codeCounter;
395         return super.transform(query);
396     }
397     
398     @Override
399     public Query transform(QAtom query) {
400         ++codeCounter;
401         return super.transform(query);
402     }
403     
404     @Override
405     public Query transform(QConjunction query) {
406         ++codeCounter;
407         return super.transform(query);
408     }
409     
410     @Override
411     public Query transform(QDisjunction query) {
412         ++codeCounter;
413         return super.transform(query);
414     }
415     
416     @Override
417     public Query transform(QExists query) {
418         ++codeCounter;
419         return super.transform(query);
420     }
421     
422     @Override
423     public Query transform(QIf query) {
424         ++codeCounter;
425         return super.transform(query);
426     }
427     
428     @Override
429     public Query transform(QMapping query) {
430         ++codeCounter;
431         return super.transform(query);
432     }
433     
434     @Override
435     public Query transform(QNegation query) {
436         ++codeCounter;
437         return super.transform(query);
438     }
439     
440     @Override
441     public Query transform(QPreBinds query) {
442         ++codeCounter;
443         return super.transform(query);
444     }
445     
446     @Override
447     public Query transform(QPreEquals query) {
448         ++codeCounter;
449         return super.transform(query);
450     }
451     
452     @Override
453     public Query transform(QPreExists query) {
454         ++codeCounter;
455         return super.transform(query);
456     }
457     
458     @Override
459     public Query transform(QPreGuard query) {
460         ++codeCounter;
461         return super.transform(query);
462     }
463     
464     public BranchPoint[] getAndClearBranchPoints() {
465         BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
466         currentBranchPoints.clear();
467         return result;
468     }
469     
470     @Override
471     public void visit(BindStatement statement) {
472         ++codeCounter;
473         super.visit(statement);
474     }
475     
476     @Override
477     public void visit(GuardStatement statement) {
478         ++codeCounter;
479         super.visit(statement);
480     }
481     
482     @Override
483     public void visit(LetStatement statement) {
484         ++codeCounter;
485         if(statement.pattern.isFunctionDefinitionLhs())
486             statement.value = injectBranchPoint(statement.value);
487         else
488             super.visit(statement);
489     }
490     
491     @Override
492     public void visit(RuleStatement statement) {
493         ++codeCounter;
494         super.visit(statement);
495     }
496     
497 }