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.EApply;
7 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
8 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
9 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
10 import org.simantics.scl.compiler.elaboration.expressions.EBind;
11 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
12 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
13 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
14 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
15 import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
16 import org.simantics.scl.compiler.elaboration.expressions.EError;
17 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
18 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
19 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
20 import org.simantics.scl.compiler.elaboration.expressions.EIf;
21 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
22 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
23 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
24 import org.simantics.scl.compiler.elaboration.expressions.ELet;
25 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
26 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
27 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
28 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
29 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
30 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
31 import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset;
32 import org.simantics.scl.compiler.elaboration.expressions.ERange;
33 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
34 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
35 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
36 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
37 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
38 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
39 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
40 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
41 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
42 import org.simantics.scl.compiler.elaboration.expressions.EVar;
43 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
44 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
45 import org.simantics.scl.compiler.elaboration.expressions.Expression;
46 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
47 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
48 import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionTransformer;
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.query.QAlternative;
60 import org.simantics.scl.compiler.elaboration.query.QAtom;
61 import org.simantics.scl.compiler.elaboration.query.QConjunction;
62 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
63 import org.simantics.scl.compiler.elaboration.query.QExists;
64 import org.simantics.scl.compiler.elaboration.query.QIf;
65 import org.simantics.scl.compiler.elaboration.query.QMapping;
66 import org.simantics.scl.compiler.elaboration.query.QNegation;
67 import org.simantics.scl.compiler.elaboration.query.Query;
68 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
69 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
70 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
71 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
72 import org.simantics.scl.runtime.profiling.BranchPoint;
74 public class BranchPointInjector extends StandardExpressionTransformer {
75 public ArrayList<BranchPoint> currentBranchPoints = new ArrayList<BranchPoint>();
78 public Expression injectBranchPoint(Expression expression) {
79 ArrayList<BranchPoint> oldBranchPoints = currentBranchPoints;
80 currentBranchPoints = new ArrayList<BranchPoint>();
81 int beginCodeCounter = codeCounter;
82 expression = expression.accept(this);
83 BranchPoint branchPoint = new BranchPoint(expression.location,
84 codeCounter - beginCodeCounter,
85 currentBranchPoints.isEmpty() ? BranchPoint.EMPTY_ARRAY
86 : currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]));
87 oldBranchPoints.add(branchPoint);
88 currentBranchPoints = oldBranchPoints;
89 return new ECoveringBranchPoint(expression, branchPoint);
93 public Expression transform(ESimpleLambda expression) {
95 expression.value = injectBranchPoint(expression.value);
100 public Expression transform(ELambda expression) {
102 for(Case case_ : expression.cases)
103 case_.value = injectBranchPoint(case_.value);
108 public Expression transform(EMatch expression) {
110 for(int i=0;i<expression.scrutinee.length;++i)
111 expression.scrutinee[i] = expression.scrutinee[i].accept(this);
112 for(Case case_ : expression.cases)
113 case_.value = injectBranchPoint(case_.value);
118 public Expression transform(EIf expression) {
120 expression.condition = expression.condition.accept(this);
121 expression.then_ = injectBranchPoint(expression.then_);
122 expression.else_ = injectBranchPoint(expression.else_);
127 public Expression transform(EBind expression) {
129 expression.pattern = expression.pattern.accept(this);
130 expression.value = expression.value.accept(this);
131 expression.in = injectBranchPoint(expression.in);
136 public Expression transform(EListComprehension expression) {
138 expression.head = injectBranchPoint(expression.head);
139 expression.qualifier = expression.qualifier.accept(this);
144 public Expression transform(EWhen expression) {
146 expression.query = expression.query.accept(this);
147 expression.action = injectBranchPoint(expression.action);
152 public Expression transform(GuardedExpressionGroup expression) {
154 for(GuardedExpression ge : expression.expressions) {
155 for(int i=0;i<ge.guards.length;++i)
156 ge.guards[i] = ge.guards[i].accept(this);
157 ge.value = injectBranchPoint(ge.value);
163 public Expression transform(EApply expression) {
165 return super.transform(expression);
169 public Expression transform(EApplyType expression) {
171 return super.transform(expression);
175 public Expression transform(EAsPattern expression) {
177 return super.transform(expression);
181 public Expression transform(EBinary expression) {
183 return super.transform(expression);
187 public Expression transform(EBlock expression) {
189 return super.transform(expression);
193 public Expression transform(EConstant expression) {
195 return super.transform(expression);
199 public Expression transform(ECoveringBranchPoint expression) {
201 return super.transform(expression);
205 public Expression transform(EEnforce expression) {
207 return super.transform(expression);
211 public Expression transform(EEntityTypeAnnotation expression) {
213 return super.transform(expression);
217 public Expression transform(EError expression) {
219 return super.transform(expression);
223 public Expression transform(EExternalConstant expression) {
225 return super.transform(expression);
229 public Expression transform(EFieldAccess expression) {
231 return super.transform(expression);
235 public Expression transform(EGetConstraint expression) {
237 return super.transform(expression);
241 public Expression transform(EIntegerLiteral expression) {
243 return super.transform(expression);
247 public Expression transform(ELambdaType expression) {
249 return super.transform(expression);
253 public Expression transform(ELet expression) {
255 return super.transform(expression);
259 public Expression transform(EListLiteral expression) {
261 return super.transform(expression);
265 public Expression transform(ELiteral expression) {
267 return super.transform(expression);
271 public Expression transform(EPlaceholder expression) {
273 return super.transform(expression);
277 public Expression transform(EPreLet expression) {
279 return super.transform(expression);
283 public Expression transform(EPreRuleset expression) {
285 return super.transform(expression);
289 public Expression transform(ERange expression) {
291 return super.transform(expression);
295 public Expression transform(ERealLiteral expression) {
297 return super.transform(expression);
301 public Expression transform(ERecord expression) {
303 return super.transform(expression);
307 public Expression transform(ERuleset expression) {
309 return super.transform(expression);
313 public Expression transform(ESelect expression) {
315 return super.transform(expression);
319 public Expression transform(ESimpleLet expression) {
321 return super.transform(expression);
325 public Expression transform(EStringLiteral expression) {
327 return super.transform(expression);
331 public Expression transform(ETransformation expression) {
333 return super.transform(expression);
337 public Expression transform(ETypeAnnotation expression) {
339 return super.transform(expression);
343 public Expression transform(EVar expression) {
345 return super.transform(expression);
349 public Expression transform(EVariable expression) {
351 return super.transform(expression);
355 public ListQualifier transform(ListAssignment qualifier) {
357 return super.transform(qualifier);
361 public ListQualifier transform(ListGenerator qualifier) {
363 return super.transform(qualifier);
367 public ListQualifier transform(ListGuard qualifier) {
369 return super.transform(qualifier);
373 public ListQualifier transform(ListSeq qualifier) {
375 return super.transform(qualifier);
379 public ListQualifier transform(ListThen qualifier) {
381 return super.transform(qualifier);
385 public Query transform(QAlternative query) {
387 return super.transform(query);
391 public Query transform(QAtom query) {
393 return super.transform(query);
397 public Query transform(QConjunction query) {
399 return super.transform(query);
403 public Query transform(QDisjunction query) {
405 return super.transform(query);
409 public Query transform(QExists query) {
411 return super.transform(query);
415 public Query transform(QIf query) {
417 return super.transform(query);
421 public Query transform(QMapping query) {
423 return super.transform(query);
427 public Query transform(QNegation query) {
429 return super.transform(query);
433 public Query transform(QPreBinds query) {
435 return super.transform(query);
439 public Query transform(QPreEquals query) {
441 return super.transform(query);
445 public Query transform(QPreExists query) {
447 return super.transform(query);
451 public Query transform(QPreGuard query) {
453 return super.transform(query);
456 public BranchPoint[] getAndClearBranchPoints() {
457 BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
458 currentBranchPoints.clear();
463 public void visit(BindStatement statement) {
465 super.visit(statement);
469 public void visit(GuardStatement statement) {
471 super.visit(statement);
475 public void visit(LetStatement statement) {
477 if(statement.pattern.isFunctionDefinitionLhs())
478 statement.value = injectBranchPoint(statement.value);
480 super.visit(statement);
484 public void visit(RuleStatement statement) {
486 super.visit(statement);