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.constants.SCLConstant;
\r
5 import org.simantics.scl.compiler.internal.codegen.analysis.StatementBrowser;
\r
6 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
\r
7 import org.simantics.scl.compiler.internal.codegen.references.Val;
\r
8 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
\r
9 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
\r
10 import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;
\r
11 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
\r
12 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
\r
14 public enum FoldlBuildFusion implements Optimization {
\r
17 private static final Name BUILD = Name.create("Prelude", "build");
\r
19 private static class Analysis extends StatementBrowser {
\r
22 protected void unanalyzedBrowse() {
\r
23 //System.out.println("- unanalyzedBrowse");
\r
28 protected void handleLoop(SSABlock block,
\r
29 SSAStatement recursiveStatement) {
\r
30 //System.out.println("- loop");
\r
35 protected void visitStatement(SSAStatement statement) {
\r
36 if(statement instanceof LetApply) {
\r
37 LetApply apply = (LetApply)statement;
\r
38 if(apply.hasEffect()) {
\r
39 //System.out.println("- effectful statement between");
\r
48 public void inline(SSASimplificationContext context, LetApply foldlApplication) {
\r
49 ValRef[] foldlParameters = foldlApplication.getParameters();
\r
50 if(foldlParameters.length != 3) // TODO case parameters.length > 3
\r
52 Val list = foldlParameters[2].getBinding();
\r
53 if(!(list instanceof BoundVar))
\r
55 if(list.hasMoreThanOneOccurences())
\r
57 BoundVar listVar = (BoundVar)list;
\r
58 if(!(listVar.getParent() instanceof LetApply))
\r
60 LetApply buildApplication = (LetApply)listVar.getParent();
\r
62 { // Check that buildApplication.getFunction() is Prelude.build
\r
63 if(buildApplication.getParameters().length != 1)
\r
65 Val buildFunction = buildApplication.getFunction().getBinding();
\r
66 if(!(buildFunction instanceof SCLConstant))
\r
68 if(((SCLConstant)buildFunction).getName() != BUILD)
\r
72 if(buildApplication.hasEffect() && foldlApplication.hasEffect())
\r
75 Analysis analysis = new Analysis();
\r
76 analysis.browseBetween(buildApplication, foldlApplication);
\r
77 if(analysis.isStopped())
\r
80 /*PrintingContext cx = new PrintingContext();
\r
81 cx.append("listDef: ");
\r
82 listDef.toString(cx);
\r
83 cx.append("apply: ");
\r
84 apply.toString(cx);*/
\r
86 foldlApplication.setParameters(new ValRef[] {foldlParameters[1], foldlParameters[0]});
\r
87 foldlParameters[2].remove();
\r
88 ValRef foldlFunctionRef = foldlApplication.getFunction();
\r
89 foldlApplication.setFunction(buildApplication.getParameters()[0].createOccurrence(
\r
90 foldlFunctionRef.getTypeParameters()[0], foldlFunctionRef.getTypeParameters()[2]));
\r
91 foldlFunctionRef.remove();
\r
92 buildApplication.remove();
\r
94 /*cx.append("transformed apply: ");
\r
96 System.out.println(cx.toString());*/
\r
98 context.markModified("foldl/build");
\r