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.NoRepConstant; 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.SSAUtils; import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor; 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); } public void forValRefs(ValRefVisitor visitor) { for(SSAStatement statement = firstStatement; statement != null; statement = statement.next) statement.forValRefs(visitor); exit.forValRefs(visitor); } }