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