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