package org.simantics.scl.compiler.internal.codegen.ssa; import java.util.ArrayList; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.references.ValRef; import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; import org.simantics.scl.compiler.internal.codegen.utils.CopyContext; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.Printable; import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext; import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; public abstract class SSAStatement implements Printable { SSABlock parent; SSAStatement prev; SSAStatement next; public long location; public void detach() { if(prev == null) parent.firstStatement = next; else prev.next = next; if(next == null) parent.lastStatement = prev; else next.prev = prev; } public abstract void generateCode(MethodBuilder mb); public abstract void validate(SSAValidationContext context); public void simplify(SSASimplificationContext context) { } public abstract void destroy(); public SSABlock getParent() { return parent; } public SSAStatement getPrev() { return prev; } public void setAsLastStatement() { this.next = null; parent.lastStatement = this; } public SSAStatement getNext() { return next; } public void remove() { detach(); destroy(); } @Override public String toString() { PrintingContext context = new PrintingContext(); toString(context); return context.toString(); } public void markGenerateOnFly() { } public abstract SSAStatement copy(CopyContext context); public abstract void replace(TVar[] vars, Type[] replacements); public abstract void addBoundVariablesTo(SSAValidationContext context); public abstract void collectFreeVariables(SSAFunction function, ArrayList vars); public SSAFunction getParentFunction() { return parent.parent; } public void lambdaLift(SSALambdaLiftingContext context) { } public void insertBefore(SSAStatement statement) { next = statement; prev = statement.prev; parent = statement.parent; if(prev == null) parent.firstStatement = this; else prev.next = this; statement.prev = this; } public void insertAfter(SSAStatement statement) { prev = statement; next = statement.next; parent = statement.parent; if(next == null) parent.lastStatement = this; else next.prev = this; statement.next = this; } public void replaceByApply(ValRef valRef, Val function, Type[] typeParameters, Val[] parameters) { BoundVar target = new BoundVar(valRef.getBinding().getType()); new LetApply(target, Types.NO_EFFECTS, function.createOccurrence(typeParameters), ValRef.createOccurrences(parameters)).insertBefore(this); valRef.replaceBy(target); } public void prepare(MethodBuilder mb) { } public abstract void forValRefs(ValRefVisitor visitor); public abstract void cleanup(); }