1 package org.simantics.scl.compiler.internal.elaboration.profiling;
3 import java.util.ArrayList;
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.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;
75 public class BranchPointInjector extends StandardExpressionTransformer {
76 public ArrayList<BranchPoint> currentBranchPoints = new ArrayList<BranchPoint>();
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);
94 public Expression transform(ESimpleLambda expression) {
96 expression.value = injectBranchPoint(expression.value);
101 public Expression transform(ELambda expression) {
103 for(Case case_ : expression.cases)
104 case_.value = injectBranchPoint(case_.value);
109 public Expression transform(EMatch expression) {
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);
119 public Expression transform(EIf expression) {
121 expression.condition = expression.condition.accept(this);
122 expression.then_ = injectBranchPoint(expression.then_);
123 if(expression.else_ != null)
124 expression.else_ = injectBranchPoint(expression.else_);
129 public Expression transform(EBind expression) {
131 expression.pattern = expression.pattern.accept(this);
132 expression.value = expression.value.accept(this);
133 expression.in = injectBranchPoint(expression.in);
138 public Expression transform(EListComprehension expression) {
140 expression.head = injectBranchPoint(expression.head);
141 expression.qualifier = expression.qualifier.accept(this);
146 public Expression transform(EWhen expression) {
148 expression.query = expression.query.accept(this);
149 expression.action = injectBranchPoint(expression.action);
154 public Expression transform(GuardedExpressionGroup expression) {
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);
165 public Expression transform(EAmbiguous expression) {
167 return super.transform(expression);
171 public Expression transform(EApply expression) {
173 return super.transform(expression);
177 public Expression transform(EApplyType expression) {
179 return super.transform(expression);
183 public Expression transform(EAsPattern expression) {
185 return super.transform(expression);
189 public Expression transform(EBinary expression) {
191 return super.transform(expression);
195 public Expression transform(EBlock expression) {
197 return super.transform(expression);
201 public Expression transform(ECHRRuleset expression) {
203 return super.transform(expression);
207 public Expression transform(EConstant expression) {
209 return super.transform(expression);
213 public Expression transform(ECoveringBranchPoint expression) {
215 return super.transform(expression);
219 public Expression transform(EEnforce expression) {
221 return super.transform(expression);
225 public Expression transform(EError expression) {
227 return super.transform(expression);
231 public Expression transform(EExternalConstant expression) {
233 return super.transform(expression);
237 public Expression transform(EFieldAccess expression) {
239 return super.transform(expression);
243 public Expression transform(EGetConstraint expression) {
245 return super.transform(expression);
249 public Expression transform(EIntegerLiteral expression) {
251 return super.transform(expression);
255 public Expression transform(ELambdaType expression) {
257 return super.transform(expression);
261 public Expression transform(ELet expression) {
263 return super.transform(expression);
267 public Expression transform(EListLiteral expression) {
269 return super.transform(expression);
273 public Expression transform(ELiteral expression) {
275 return super.transform(expression);
279 public Expression transform(EPlaceholder expression) {
281 return super.transform(expression);
285 public Expression transform(EPreLet expression) {
287 return super.transform(expression);
291 public Expression transform(EPreRuleset expression) {
293 return super.transform(expression);
297 public Expression transform(ERange expression) {
299 return super.transform(expression);
303 public Expression transform(ERealLiteral expression) {
305 return super.transform(expression);
309 public Expression transform(ERecord expression) {
311 return super.transform(expression);
315 public Expression transform(ERuleset expression) {
317 return super.transform(expression);
321 public Expression transform(ESelect expression) {
323 return super.transform(expression);
327 public Expression transform(ESimpleLet expression) {
329 return super.transform(expression);
333 public Expression transform(EStringLiteral expression) {
335 return super.transform(expression);
339 public Expression transform(ETransformation expression) {
341 return super.transform(expression);
345 public Expression transform(ETypeAnnotation expression) {
347 return super.transform(expression);
351 public Expression transform(EVar expression) {
353 return super.transform(expression);
357 public Expression transform(EVariable expression) {
359 return super.transform(expression);
363 public ListQualifier transform(ListAssignment qualifier) {
365 return super.transform(qualifier);
369 public ListQualifier transform(ListGenerator qualifier) {
371 return super.transform(qualifier);
375 public ListQualifier transform(ListGuard qualifier) {
377 return super.transform(qualifier);
381 public ListQualifier transform(ListSeq qualifier) {
383 return super.transform(qualifier);
387 public ListQualifier transform(ListThen qualifier) {
389 return super.transform(qualifier);
393 public Query transform(QAlternative query) {
395 return super.transform(query);
399 public Query transform(QAtom query) {
401 return super.transform(query);
405 public Query transform(QConjunction query) {
407 return super.transform(query);
411 public Query transform(QDisjunction query) {
413 return super.transform(query);
417 public Query transform(QExists query) {
419 return super.transform(query);
423 public Query transform(QIf query) {
425 return super.transform(query);
429 public Query transform(QMapping query) {
431 return super.transform(query);
435 public Query transform(QNegation query) {
437 return super.transform(query);
441 public Query transform(QPreBinds query) {
443 return super.transform(query);
447 public Query transform(QPreEquals query) {
449 return super.transform(query);
453 public Query transform(QPreExists query) {
455 return super.transform(query);
459 public Query transform(QPreGuard query) {
461 return super.transform(query);
464 public BranchPoint[] getAndClearBranchPoints() {
465 BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
466 currentBranchPoints.clear();
471 public void visit(BindStatement statement) {
473 super.visit(statement);
477 public void visit(GuardStatement statement) {
479 super.visit(statement);
483 public void visit(LetStatement statement) {
485 if(statement.pattern.isFunctionDefinitionLhs())
486 statement.value = injectBranchPoint(statement.value);
488 super.visit(statement);
492 public void visit(RuleStatement statement) {
494 super.visit(statement);