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