]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/FoldlBuildFusion.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / optimization / FoldlBuildFusion.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/FoldlBuildFusion.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/FoldlBuildFusion.java
new file mode 100644 (file)
index 0000000..4b287fa
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.scl.compiler.internal.codegen.optimization;\r
+\r
+import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.constants.SCLConstant;\r
+import org.simantics.scl.compiler.internal.codegen.analysis.StatementBrowser;\r
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
+import org.simantics.scl.compiler.internal.codegen.references.Val;\r
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
+\r
+public enum FoldlBuildFusion implements Optimization {\r
+    INSTANCE;\r
+\r
+    private static final Name BUILD = Name.create("Prelude", "build");\r
+    \r
+    private static class Analysis extends StatementBrowser {\r
+        \r
+        @Override\r
+        protected void unanalyzedBrowse() {\r
+            //System.out.println("- unanalyzedBrowse");\r
+            stopBrowse();\r
+        }\r
+        \r
+        @Override\r
+        protected void handleLoop(SSABlock block,\r
+                SSAStatement recursiveStatement) {\r
+            //System.out.println("- loop");\r
+            stopBrowse();\r
+        }\r
+        \r
+        @Override\r
+        protected void visitStatement(SSAStatement statement) {\r
+            if(statement instanceof LetApply) {\r
+                LetApply apply = (LetApply)statement;\r
+                if(apply.hasEffect()) {\r
+                    //System.out.println("- effectful statement between");\r
+                    stopBrowse();\r
+                }\r
+            }\r
+        }\r
+                \r
+    }\r
+    \r
+    @Override\r
+    public void inline(SSASimplificationContext context, LetApply foldlApplication) {        \r
+        ValRef[] foldlParameters = foldlApplication.getParameters();\r
+        if(foldlParameters.length != 3) // TODO case parameters.length > 3\r
+            return;\r
+        Val list = foldlParameters[2].getBinding();\r
+        if(!(list instanceof BoundVar))\r
+            return;\r
+        if(list.hasMoreThanOneOccurences())\r
+            return;\r
+        BoundVar listVar = (BoundVar)list;\r
+        if(!(listVar.getParent() instanceof LetApply))\r
+            return;\r
+        LetApply buildApplication = (LetApply)listVar.getParent();\r
+                \r
+        { // Check that buildApplication.getFunction() is Prelude.build\r
+            if(buildApplication.getParameters().length != 1)\r
+                return;\r
+            Val buildFunction = buildApplication.getFunction().getBinding();\r
+            if(!(buildFunction instanceof SCLConstant))\r
+                return;\r
+            if(((SCLConstant)buildFunction).getName() != BUILD)\r
+                return;\r
+        }\r
+\r
+        if(buildApplication.hasEffect() && foldlApplication.hasEffect())\r
+            return;\r
+        \r
+        Analysis analysis = new Analysis();\r
+        analysis.browseBetween(buildApplication, foldlApplication);\r
+        if(analysis.isStopped())\r
+            return;\r
+        \r
+        /*PrintingContext cx = new PrintingContext();\r
+        cx.append("listDef: ");\r
+        listDef.toString(cx);\r
+        cx.append("apply: ");\r
+        apply.toString(cx);*/\r
+                \r
+        foldlApplication.setParameters(new ValRef[] {foldlParameters[1], foldlParameters[0]});\r
+        foldlParameters[2].remove();\r
+        ValRef foldlFunctionRef = foldlApplication.getFunction();\r
+        foldlApplication.setFunction(buildApplication.getParameters()[0].createOccurrence(\r
+                foldlFunctionRef.getTypeParameters()[0], foldlFunctionRef.getTypeParameters()[2]));\r
+        foldlFunctionRef.remove();        \r
+        buildApplication.remove();\r
+        \r
+        /*cx.append("transformed apply: ");\r
+        apply.toString(cx);\r
+        System.out.println(cx.toString());*/\r
+        \r
+        context.markModified("foldl/build");\r
+    }\r
+}\r