-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
+package org.simantics.scl.compiler.internal.codegen.optimization;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.constants.SCLConstant;
+import org.simantics.scl.compiler.internal.codegen.analysis.StatementBrowser;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
+
+public enum FoldlBuildFusion implements Optimization {
+ INSTANCE;
+
+ private static class Analysis extends StatementBrowser {
+
+ @Override
+ protected void unanalyzedBrowse() {
+ //System.out.println("- unanalyzedBrowse");
+ stopBrowse();
+ }
+
+ @Override
+ protected void handleLoop(SSABlock block,
+ SSAStatement recursiveStatement) {
+ //System.out.println("- loop");
+ stopBrowse();
+ }
+
+ @Override
+ protected void visitStatement(SSAStatement statement) {
+ if(statement instanceof LetApply) {
+ LetApply apply = (LetApply)statement;
+ if(apply.hasEffect()) {
+ //System.out.println("- effectful statement between");
+ stopBrowse();
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void inline(SSASimplificationContext context, LetApply foldlApplication) {
+ ValRef[] foldlParameters = foldlApplication.getParameters();
+ if(foldlParameters.length != 3) // TODO case parameters.length > 3
+ return;
+ Val list = foldlParameters[2].getBinding();
+ if(!(list instanceof BoundVar))
+ return;
+ if(list.hasMoreThanOneOccurences())
+ return;
+ BoundVar listVar = (BoundVar)list;
+ if(!(listVar.getParent() instanceof LetApply))
+ return;
+ LetApply buildApplication = (LetApply)listVar.getParent();
+
+ { // Check that buildApplication.getFunction() is Prelude.build
+ if(buildApplication.getParameters().length != 1)
+ return;
+ Val buildFunction = buildApplication.getFunction().getBinding();
+ if(!(buildFunction instanceof SCLConstant))
+ return;
+ if(((SCLConstant)buildFunction).getName() != Names.Prelude_build)
+ return;
+ }
+
+ if(buildApplication.hasEffect() && foldlApplication.hasEffect())
+ return;
+
+ Analysis analysis = new Analysis();
+ analysis.browseBetween(buildApplication, foldlApplication);
+ if(analysis.isStopped())
+ return;
+
+ /*PrintingContext cx = new PrintingContext();
+ cx.append("listDef: ");
+ listDef.toString(cx);
+ cx.append("apply: ");
+ apply.toString(cx);*/
+
+ foldlApplication.setParameters(new ValRef[] {foldlParameters[1], foldlParameters[0]});
+ foldlParameters[2].remove();
+ ValRef foldlFunctionRef = foldlApplication.getFunction();
+ foldlApplication.setFunction(buildApplication.getParameters()[0].createOccurrence(
+ foldlFunctionRef.getTypeParameters()[0], foldlFunctionRef.getTypeParameters()[2]));
+ foldlFunctionRef.remove();
+ buildApplication.remove();
+
+ /*cx.append("transformed apply: ");
+ apply.toString(cx);
+ System.out.println(cx.toString());*/
+
+ context.markModified("foldl/build");
+ }
+}