1 package org.simantics.scl.compiler.internal.codegen.optimization;
3 import org.simantics.scl.compiler.common.names.Name;
4 import org.simantics.scl.compiler.common.names.Names;
5 import org.simantics.scl.compiler.constants.SCLConstant;
6 import org.simantics.scl.compiler.internal.codegen.analysis.StatementBrowser;
7 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
8 import org.simantics.scl.compiler.internal.codegen.references.Val;
9 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
10 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
11 import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;
12 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
13 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
15 public enum FoldlBuildFusion implements Optimization {
18 private static class Analysis extends StatementBrowser {
21 protected void unanalyzedBrowse() {
22 //System.out.println("- unanalyzedBrowse");
27 protected void handleLoop(SSABlock block,
28 SSAStatement recursiveStatement) {
29 //System.out.println("- loop");
34 protected void visitStatement(SSAStatement statement) {
35 if(statement instanceof LetApply) {
36 LetApply apply = (LetApply)statement;
37 if(apply.hasEffect()) {
38 //System.out.println("- effectful statement between");
47 public void inline(SSASimplificationContext context, LetApply foldlApplication) {
48 ValRef[] foldlParameters = foldlApplication.getParameters();
49 if(foldlParameters.length != 3) // TODO case parameters.length > 3
51 Val list = foldlParameters[2].getBinding();
52 if(!(list instanceof BoundVar))
54 if(list.hasMoreThanOneOccurences())
56 BoundVar listVar = (BoundVar)list;
57 if(!(listVar.getParent() instanceof LetApply))
59 LetApply buildApplication = (LetApply)listVar.getParent();
61 { // Check that buildApplication.getFunction() is Prelude.build
62 if(buildApplication.getParameters().length != 1)
64 Val buildFunction = buildApplication.getFunction().getBinding();
65 if(!(buildFunction instanceof SCLConstant))
67 if(((SCLConstant)buildFunction).getName() != Names.Prelude_build)
71 if(buildApplication.hasEffect() && foldlApplication.hasEffect())
74 Analysis analysis = new Analysis();
75 analysis.browseBetween(buildApplication, foldlApplication);
76 if(analysis.isStopped())
79 /*PrintingContext cx = new PrintingContext();
80 cx.append("listDef: ");
85 foldlApplication.setParameters(new ValRef[] {foldlParameters[1], foldlParameters[0]});
86 foldlParameters[2].remove();
87 ValRef foldlFunctionRef = foldlApplication.getFunction();
88 foldlApplication.setFunction(buildApplication.getParameters()[0].createOccurrence(
89 foldlFunctionRef.getTypeParameters()[0], foldlFunctionRef.getTypeParameters()[2]));
90 foldlFunctionRef.remove();
91 buildApplication.remove();
93 /*cx.append("transformed apply: ");
95 System.out.println(cx.toString());*/
97 context.markModified("foldl/build");