]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / elaboration / profiling / BranchPointInjector.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java
new file mode 100644 (file)
index 0000000..930dfe1
--- /dev/null
@@ -0,0 +1,489 @@
+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.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.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
+import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
+import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
+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.StandardExpressionTransformer;
+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.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<BranchPoint> currentBranchPoints = new ArrayList<BranchPoint>();
+    int codeCounter = 0;
+    
+    public Expression injectBranchPoint(Expression expression) {
+        ArrayList<BranchPoint> oldBranchPoints = currentBranchPoints;
+        currentBranchPoints = new ArrayList<BranchPoint>();
+        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<expression.scrutinee.length;++i)
+            expression.scrutinee[i] = expression.scrutinee[i].accept(this);
+        for(Case case_ : expression.cases)
+            case_.value = injectBranchPoint(case_.value);
+        return expression;
+    }
+    
+    @Override
+    public Expression transform(EIf expression) {
+        ++codeCounter;
+        expression.condition = expression.condition.accept(this);
+        expression.then_ = injectBranchPoint(expression.then_);
+        expression.else_ = injectBranchPoint(expression.else_);
+        return expression;
+    }
+    
+    @Override
+    public Expression transform(EBind expression) {
+        ++codeCounter;
+        expression.pattern = expression.pattern.accept(this);
+        expression.value = expression.value.accept(this);
+        expression.in = injectBranchPoint(expression.in);
+        return expression;
+    }
+    
+    @Override
+    public Expression transform(EListComprehension expression) {
+        ++codeCounter;
+        expression.head = injectBranchPoint(expression.head);
+        expression.qualifier =  expression.qualifier.accept(this);
+        return expression;
+    }
+    
+    @Override
+    public Expression transform(EWhen expression) {
+        ++codeCounter;
+        expression.query = expression.query.accept(this);
+        expression.action = injectBranchPoint(expression.action);
+        return expression;
+    }
+
+    @Override
+    public Expression transform(GuardedExpressionGroup expression) {
+        ++codeCounter;
+        for(GuardedExpression ge : expression.expressions) {
+            for(int i=0;i<ge.guards.length;++i)
+                ge.guards[i] = ge.guards[i].accept(this);
+            ge.value = injectBranchPoint(ge.value);
+        }
+        return expression;
+    }
+    
+    @Override
+    public Expression transform(EApply expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EApplyType expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EAsPattern expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EBinary expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EBlock expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EConstant expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ECoveringBranchPoint expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EEnforce expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EEntityTypeAnnotation expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EError expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EExternalConstant expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EFieldAccess expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EGetConstraint expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EIntegerLiteral expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ELambdaType expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ELet expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EListLiteral expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ELiteral expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EPlaceholder expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EPreLet expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EPreRuleset expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ERange expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ERealLiteral expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ERecord expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ERuleset expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ESelect expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ESimpleLet expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EStringLiteral expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ETransformation expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(ETypeAnnotation expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EVar expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public Expression transform(EVariable expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
+    @Override
+    public ListQualifier transform(ListAssignment qualifier) {
+        ++codeCounter;
+        return super.transform(qualifier);
+    }
+    
+    @Override
+    public ListQualifier transform(ListGenerator qualifier) {
+        ++codeCounter;
+        return super.transform(qualifier);
+    }
+    
+    @Override
+    public ListQualifier transform(ListGuard qualifier) {
+        ++codeCounter;
+        return super.transform(qualifier);
+    }
+    
+    @Override
+    public ListQualifier transform(ListSeq qualifier) {
+        ++codeCounter;
+        return super.transform(qualifier);
+    }
+    
+    @Override
+    public ListQualifier transform(ListThen qualifier) {
+        ++codeCounter;
+        return super.transform(qualifier);
+    }
+    
+    @Override
+    public Query transform(QAlternative query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QAtom query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QConjunction query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QDisjunction query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QExists query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QIf query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QMapping query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QNegation query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QPreBinds query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QPreEquals query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QPreExists query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    @Override
+    public Query transform(QPreGuard query) {
+        ++codeCounter;
+        return super.transform(query);
+    }
+    
+    public BranchPoint[] getAndClearBranchPoints() {
+        BranchPoint[] result = currentBranchPoints.toArray(new BranchPoint[currentBranchPoints.size()]);
+        currentBranchPoints.clear();
+        return result;
+    }
+    
+    @Override
+    public void visit(BindStatement statement) {
+        ++codeCounter;
+        super.visit(statement);
+    }
+    
+    @Override
+    public void visit(GuardStatement statement) {
+        ++codeCounter;
+        super.visit(statement);
+    }
+    
+    @Override
+    public void visit(LetStatement statement) {
+        ++codeCounter;
+        if(statement.pattern.isFunctionDefinitionLhs())
+            statement.value = injectBranchPoint(statement.value);
+        else
+            super.visit(statement);
+    }
+    
+    @Override
+    public void visit(RuleStatement statement) {
+        ++codeCounter;
+        super.visit(statement);
+    }
+    
+}