From deab3beaf85064ee1c5ff56eb7627610ad5ba715 Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 30 Jul 2016 12:58:13 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B4=D0=B0=D0=BC=D0=BF=D0=B5=D1=80=20=D1=88=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ownlang/utils/OptimizationDumper.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/main/java/com/annimon/ownlang/utils/OptimizationDumper.java diff --git a/src/main/java/com/annimon/ownlang/utils/OptimizationDumper.java b/src/main/java/com/annimon/ownlang/utils/OptimizationDumper.java new file mode 100644 index 0000000..52bb463 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/utils/OptimizationDumper.java @@ -0,0 +1,107 @@ +package com.annimon.ownlang.utils; + +import com.annimon.ownlang.parser.Lexer; +import com.annimon.ownlang.parser.Parser; +import com.annimon.ownlang.parser.SourceLoader; +import com.annimon.ownlang.parser.ast.Node; +import com.annimon.ownlang.parser.optimization.ConstantFolding; +import com.annimon.ownlang.parser.optimization.ConstantPropagation; +import com.annimon.ownlang.parser.optimization.DeadCodeElimination; +import com.annimon.ownlang.parser.optimization.ExpressionSimplification; +import com.annimon.ownlang.parser.optimization.InstructionCombining; +import com.annimon.ownlang.parser.optimization.Optimizable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +public final class OptimizationDumper { + + private static final Optimizable[] OPTIMIZATIONS = new Optimizable[] { + new ConstantFolding(), + new ConstantPropagation(), + new DeadCodeElimination(), + new ExpressionSimplification(), + new InstructionCombining() + }; + private static final File WORK_DIR = new File("optimizations"); + + public static void main(String[] args) throws Exception { + WORK_DIR.mkdir(); + final String input = (args.length >= 1) ? args[0] : "program.own"; + final Map optimizationSteps = getOptimizationSteps(input); + writeStepsToFile(optimizationSteps); + writeSummary(optimizationSteps); + } + + private static Map getOptimizationSteps(String input) throws IOException { + final Map result = new LinkedHashMap<>(); + Node node = Parser.parse(Lexer.tokenize(SourceLoader.readSource(input))); + int optimizationPasses = 1; + int lastBatchModificationCount; + int batchModificationCount = 0; + result.put("Source", node.toString()); + do { + lastBatchModificationCount = batchModificationCount; + batchModificationCount = 0; + for (Optimizable optimization : OPTIMIZATIONS) { + final String lastSource = node.toString(); + node = optimization.optimize(node); + final String currentSource = node.toString(); + if (!lastSource.equals(currentSource)) { + final String optName = String.format("%s, %d pass", + optimization.getClass().getSimpleName(), + optimizationPasses); + result.put(optName, node.toString()); + } + batchModificationCount += optimization.optimizationsCount(); + } + optimizationPasses++; + } while (lastBatchModificationCount != batchModificationCount); + return result; + } + + private static void writeStepsToFile(Map optimizationSteps) throws IOException { + Arrays.stream(WORK_DIR.listFiles((d, name) -> name.endsWith(".txt"))) + .forEach(File::delete); + + int counter = 1; + for (Map.Entry entry : optimizationSteps.entrySet()) { + final String filename = String.format("file_%d.txt", counter++); + final File file = new File(WORK_DIR, filename); + writeContent(file, writer -> { + writer.append(entry.getKey()); + writer.append("\n\n"); + writer.append(entry.getValue()); + }); + } + } + + private static void writeSummary(final Map optimizationSteps) throws IOException { + final StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : optimizationSteps.entrySet()) { + sb.append(entry.getKey()); + sb.append("\n\n"); + sb.append(entry.getValue()); + sb.append("\n\n-----------\n\n"); + } + writeContent(new File(WORK_DIR, "summary.txt"), + writer -> writer.write(sb.toString())); + } + + private static void writeContent(File file, ThrowableConsumer consumer) throws IOException { + try (OutputStream out = new FileOutputStream(file); + OutputStreamWriter writer = new OutputStreamWriter(out)) { + consumer.accept(writer); + } + } + + interface ThrowableConsumer { + void accept(T t) throws IOException; + } +}