]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/FoldlBuildFusion.java
Merge "List the unsatisfied dependencies in CanvasContext"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / optimization / FoldlBuildFusion.java
1 package org.simantics.scl.compiler.internal.codegen.optimization;\r
2 \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
14 \r
15 public enum FoldlBuildFusion implements Optimization {\r
16     INSTANCE;\r
17     \r
18     private static class Analysis extends StatementBrowser {\r
19         \r
20         @Override\r
21         protected void unanalyzedBrowse() {\r
22             //System.out.println("- unanalyzedBrowse");\r
23             stopBrowse();\r
24         }\r
25         \r
26         @Override\r
27         protected void handleLoop(SSABlock block,\r
28                 SSAStatement recursiveStatement) {\r
29             //System.out.println("- loop");\r
30             stopBrowse();\r
31         }\r
32         \r
33         @Override\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
39                     stopBrowse();\r
40                 }\r
41             }\r
42         }\r
43                 \r
44     }\r
45     \r
46     @Override\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
50             return;\r
51         Val list = foldlParameters[2].getBinding();\r
52         if(!(list instanceof BoundVar))\r
53             return;\r
54         if(list.hasMoreThanOneOccurences())\r
55             return;\r
56         BoundVar listVar = (BoundVar)list;\r
57         if(!(listVar.getParent() instanceof LetApply))\r
58             return;\r
59         LetApply buildApplication = (LetApply)listVar.getParent();\r
60                 \r
61         { // Check that buildApplication.getFunction() is Prelude.build\r
62             if(buildApplication.getParameters().length != 1)\r
63                 return;\r
64             Val buildFunction = buildApplication.getFunction().getBinding();\r
65             if(!(buildFunction instanceof SCLConstant))\r
66                 return;\r
67             if(((SCLConstant)buildFunction).getName() != Names.Prelude_build)\r
68                 return;\r
69         }\r
70 \r
71         if(buildApplication.hasEffect() && foldlApplication.hasEffect())\r
72             return;\r
73         \r
74         Analysis analysis = new Analysis();\r
75         analysis.browseBetween(buildApplication, foldlApplication);\r
76         if(analysis.isStopped())\r
77             return;\r
78         \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
84                 \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
92         \r
93         /*cx.append("transformed apply: ");\r
94         apply.toString(cx);\r
95         System.out.println(cx.toString());*/\r
96         \r
97         context.markModified("foldl/build");\r
98     }\r
99 }\r