package org.simantics.scl.compiler.internal.elaboration.profiling; import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.expressions.Case; import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EApplyType; import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; import org.simantics.scl.compiler.elaboration.expressions.EBinary; import org.simantics.scl.compiler.elaboration.expressions.EBind; import org.simantics.scl.compiler.elaboration.expressions.EBlock; import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint; import org.simantics.scl.compiler.elaboration.expressions.EEnforce; import org.simantics.scl.compiler.elaboration.expressions.EError; import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess; import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint; import org.simantics.scl.compiler.elaboration.expressions.EIf; import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELambda; import org.simantics.scl.compiler.elaboration.expressions.ELambdaType; import org.simantics.scl.compiler.elaboration.expressions.ELet; import org.simantics.scl.compiler.elaboration.expressions.EListComprehension; import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EMatch; import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; import org.simantics.scl.compiler.elaboration.expressions.EPreLet; import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset; import org.simantics.scl.compiler.elaboration.expressions.ERange; import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral; import org.simantics.scl.compiler.elaboration.expressions.ERecord; import org.simantics.scl.compiler.elaboration.expressions.ERuleset; import org.simantics.scl.compiler.elaboration.expressions.ESelect; import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet; import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral; import org.simantics.scl.compiler.elaboration.expressions.ETransformation; import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.EWhen; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup; import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement; import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement; import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement; import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment; import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator; import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard; import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier; import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq; import org.simantics.scl.compiler.elaboration.expressions.list.ListThen; import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer; import org.simantics.scl.compiler.elaboration.query.QAlternative; import org.simantics.scl.compiler.elaboration.query.QAtom; import org.simantics.scl.compiler.elaboration.query.QConjunction; import org.simantics.scl.compiler.elaboration.query.QDisjunction; import org.simantics.scl.compiler.elaboration.query.QExists; import org.simantics.scl.compiler.elaboration.query.QIf; import org.simantics.scl.compiler.elaboration.query.QMapping; import org.simantics.scl.compiler.elaboration.query.QNegation; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds; import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals; import org.simantics.scl.compiler.elaboration.query.pre.QPreExists; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.runtime.profiling.BranchPoint; public class BranchPointInjector extends StandardExpressionTransformer { public ArrayList currentBranchPoints = new ArrayList(); int codeCounter = 0; public Expression injectBranchPoint(Expression expression) { ArrayList oldBranchPoints = currentBranchPoints; currentBranchPoints = new ArrayList(); int beginCodeCounter = codeCounter; expression = expression.accept(this); BranchPoint branchPoint = new BranchPoint(expression.location, codeCounter - beginCodeCounter, currentBranchPoints.isEmpty() ? BranchPoint.EMPTY_ARRAY : currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()])); oldBranchPoints.add(branchPoint); currentBranchPoints = oldBranchPoints; return new ECoveringBranchPoint(expression, branchPoint); } @Override public Expression transform(ESimpleLambda expression) { ++codeCounter; expression.value = injectBranchPoint(expression.value); return expression; } @Override public Expression transform(ELambda expression) { ++codeCounter; for(Case case_ : expression.cases) case_.value = injectBranchPoint(case_.value); return expression; } @Override public Expression transform(EMatch expression) { ++codeCounter; for(int i=0;i