X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fssa%2FSSABlock.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fssa%2FSSABlock.java;h=3c6c114cb67909ff793eefc305d83aec8defbabd;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSABlock.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSABlock.java new file mode 100644 index 000000000..3c6c114cb --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSABlock.java @@ -0,0 +1,537 @@ +package org.simantics.scl.compiler.internal.codegen.ssa; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.constants.Constant; +import org.simantics.scl.compiler.constants.SCLConstant; +import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef; +import org.simantics.scl.compiler.internal.codegen.continuations.Cont; +import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; +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.binders.BoundVarBinder; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch; +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.top.SCLCompilerConfiguration; +import org.simantics.scl.compiler.types.TVar; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; + +public final class SSABlock extends Cont implements Printable, BoundVarBinder { + public static final SSABlock[] EMPTY_ARRAY = new SSABlock[0]; + + BoundVar[] parameters; + + SSAFunction parent; + SSABlock prev; + SSABlock next; + SSAStatement firstStatement; + SSAStatement lastStatement; + SSAExit exit; + + public SSABlock(Type ... parameterTypes) { + parameters = new BoundVar[parameterTypes.length]; + for(int i=0;i [a] + * ===> + * [a] + */ + sw.destroy(); + setExit(new Jump(branch.cont.getBinding().createOccurrence())); + } + } + } + return false; + } + + private boolean inlineJump() { + Jump jump = (Jump)exit; + Cont target = jump.getTarget().getBinding(); + if(!(target instanceof SSABlock)) + return false; + if(target.hasMoreThanOneOccurences()) + return false; + SSABlock block = (SSABlock)target; + if(block == parent.firstBlock || block == this) + return false; + + /*System.out.println(">> BEFORE INLINE >>"); + System.out.println(getParent()); + System.out.println(">> THIS BLOCK >>"); + System.out.println(this); + System.out.println(">> TARGET BLOCK >>"); + System.out.println(block);*/ + + mergeStatements(block); + + for(int i=0;i> AFTER INLINE >>"); + System.out.println(getParent()); + System.out.println(">> THIS BLOCK >>"); + System.out.println(this); + System.out.println(">>>>>>>>>>>>>>>>>>");*/ + return true; + } + + private void mergeStatements(SSABlock block) { + if(SCLCompilerConfiguration.DEBUG) { + SSAStatement last = firstStatement; + if(last != null) { + while(last.next != null) + last = last.next; + } + if(last != lastStatement) + throw new InternalCompilerError(); + } + SSAStatement stat = block.firstStatement; + while(stat != null) { + SSAStatement next = stat.next; + addStatement(stat); + stat = next; + } + } + + @Override + public String toString() { + PrintingContext context = new PrintingContext(); + toString(context); + return context.toString(); + } + + public void markGenerateOnFly() { + for(SSAStatement stat = firstStatement; stat != null; stat = stat.next) + stat.markGenerateOnFly(); + } + + public SSABlock copy(CopyContext context) { + SSABlock newBlock = new SSABlock(context.copy(parameters)); + context.put(this, newBlock); + for(SSAStatement statement = firstStatement; + statement != null; statement = statement.next) + newBlock.addStatement(statement.copy(context)); + newBlock.setExit(exit.copy(context)); + return newBlock; + } + + public void setParameters(BoundVar[] parameters) { + for(BoundVar parameter : parameters) + parameter.parent = this; + this.parameters = parameters; + } + + @Override + public void replace(TVar[] vars, Type[] replacements) { + for(BoundVar parameter : parameters) + parameter.replace(vars, replacements); + for(SSAStatement statement = firstStatement; + statement != null; statement = statement.next) + statement.replace(vars, replacements); + exit.replace(vars, replacements); + } + + public void collectFreeVariables(SSAFunction function, ArrayList vars) { + for(SSAStatement statement = firstStatement; + statement != null; statement = statement.next) + statement.collectFreeVariables(function, vars); + exit.collectFreeVariables(function, vars); + } + + @Override + public SSAFunction getParentFunction() { + return parent; + } + + public void lambdaLift(SSALambdaLiftingContext context) { + for(SSAStatement statement = firstStatement; + statement != null; statement = statement.next) + statement.lambdaLift(context); + } + + public SSAStatement getFirstStatement() { + return firstStatement; + } + + public void setParameter(int position, BoundVar target) { + parameters[position] = target; + target.parent = this; + } + + public void prepare(MethodBuilder mb) { + for(SSAStatement stat = firstStatement; stat != null; stat = stat.next) + stat.prepare(mb); + exit.prepare(mb); + } + +}