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.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;
76 public class BranchPointInjector extends StandardExpressionTransformer {
77 public ArrayList<BranchPoint> currentBranchPoints = new ArrayList<BranchPoint>();
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);
95 public Expression transform(ESimpleLambda expression) {
97 expression.value = injectBranchPoint(expression.value);
102 public Expression transform(ELambda expression) {
104 for(Case case_ : expression.cases)
105 case_.value = injectBranchPoint(case_.value);
110 public Expression transform(EMatch expression) {
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);
120 public Expression transform(EIf expression) {
122 expression.condition = expression.condition.accept(this);
123 expression.then_ = injectBranchPoint(expression.then_);
124 if(expression.else_ != null)
125 expression.else_ = injectBranchPoint(expression.else_);
130 public Expression transform(EBind expression) {
132 expression.pattern = expression.pattern.accept(this);
133 expression.value = expression.value.accept(this);
134 expression.in = injectBranchPoint(expression.in);
139 public Expression transform(EListComprehension expression) {
141 expression.head = injectBranchPoint(expression.head);
142 expression.qualifier = expression.qualifier.accept(this);
147 public Expression transform(EWhen expression) {
149 expression.query = expression.query.accept(this);
150 expression.action = injectBranchPoint(expression.action);
155 public Expression transform(GuardedExpressionGroup expression) {
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);
166 public Expression transform(EAmbiguous expression) {
168 return super.transform(expression);
172 public Expression transform(EApply expression) {
174 return super.transform(expression);
178 public Expression transform(EApplyType expression) {
180 return super.transform(expression);
184 public Expression transform(EAsPattern expression) {
186 return super.transform(expression);
190 public Expression transform(EBinary expression) {
192 return super.transform(expression);
196 public Expression transform(EBlock expression) {
198 return super.transform(expression);
202 public Expression transform(ECHRRuleset expression) {
204 return super.transform(expression);
208 public Expression transform(EConstant expression) {
210 return super.transform(expression);
214 public Expression transform(ECoveringBranchPoint expression) {
216 return super.transform(expression);
220 public Expression transform(EEnforce expression) {
222 return super.transform(expression);
226 public Expression transform(EEntityTypeAnnotation expression) {
228 return super.transform(expression);
232 public Expression transform(EError expression) {
234 return super.transform(expression);
238 public Expression transform(EExternalConstant expression) {
240 return super.transform(expression);
244 public Expression transform(EFieldAccess expression) {
246 return super.transform(expression);
250 public Expression transform(EGetConstraint expression) {
252 return super.transform(expression);
256 public Expression transform(EIntegerLiteral expression) {
258 return super.transform(expression);
262 public Expression transform(ELambdaType expression) {
264 return super.transform(expression);
268 public Expression transform(ELet expression) {
270 return super.transform(expression);
274 public Expression transform(EListLiteral expression) {
276 return super.transform(expression);
280 public Expression transform(ELiteral expression) {
282 return super.transform(expression);
286 public Expression transform(EPlaceholder expression) {
288 return super.transform(expression);
292 public Expression transform(EPreLet expression) {
294 return super.transform(expression);
298 public Expression transform(EPreRuleset expression) {
300 return super.transform(expression);
304 public Expression transform(ERange expression) {
306 return super.transform(expression);
310 public Expression transform(ERealLiteral expression) {
312 return super.transform(expression);
316 public Expression transform(ERecord expression) {
318 return super.transform(expression);
322 public Expression transform(ERuleset expression) {
324 return super.transform(expression);
328 public Expression transform(ESelect expression) {
330 return super.transform(expression);
334 public Expression transform(ESimpleLet expression) {
336 return super.transform(expression);
340 public Expression transform(EStringLiteral expression) {
342 return super.transform(expression);
346 public Expression transform(ETransformation expression) {
348 return super.transform(expression);
352 public Expression transform(ETypeAnnotation expression) {
354 return super.transform(expression);
358 public Expression transform(EVar expression) {
360 return super.transform(expression);
364 public Expression transform(EVariable expression) {
366 return super.transform(expression);
370 public ListQualifier transform(ListAssignment qualifier) {
372 return super.transform(qualifier);
376 public ListQualifier transform(ListGenerator qualifier) {
378 return super.transform(qualifier);
382 public ListQualifier transform(ListGuard qualifier) {
384 return super.transform(qualifier);
388 public ListQualifier transform(ListSeq qualifier) {
390 return super.transform(qualifier);
394 public ListQualifier transform(ListThen qualifier) {
396 return super.transform(qualifier);
400 public Query transform(QAlternative query) {
402 return super.transform(query);
406 public Query transform(QAtom query) {
408 return super.transform(query);
412 public Query transform(QConjunction query) {
414 return super.transform(query);
418 public Query transform(QDisjunction query) {
420 return super.transform(query);
424 public Query transform(QExists query) {
426 return super.transform(query);
430 public Query transform(QIf query) {
432 return super.transform(query);
436 public Query transform(QMapping query) {
438 return super.transform(query);
442 public Query transform(QNegation query) {
444 return super.transform(query);
448 public Query transform(QPreBinds query) {
450 return super.transform(query);
454 public Query transform(QPreEquals query) {
456 return super.transform(query);
460 public Query transform(QPreExists query) {
462 return super.transform(query);
466 public Query transform(QPreGuard query) {
468 return super.transform(query);
471 public BranchPoint[] getAndClearBranchPoints() {
472 BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
473 currentBranchPoints.clear();
478 public void visit(BindStatement statement) {
480 super.visit(statement);
484 public void visit(GuardStatement statement) {
486 super.visit(statement);
490 public void visit(LetStatement statement) {
492 if(statement.pattern.isFunctionDefinitionLhs())
493 statement.value = injectBranchPoint(statement.value);
495 super.visit(statement);
499 public void visit(RuleStatement statement) {
501 super.visit(statement);