Move optimization logic to OptimizationStage class, don't print summary

This commit is contained in:
aNNiMON 2023-10-02 17:39:31 +03:00 committed by Victor Melnik
parent f0317c44c7
commit 94bbc05b93
4 changed files with 62 additions and 68 deletions

View File

@ -4,7 +4,9 @@ import com.annimon.ownlang.exceptions.OwnLangParserException;
import com.annimon.ownlang.exceptions.StoppedException; import com.annimon.ownlang.exceptions.StoppedException;
import com.annimon.ownlang.parser.*; import com.annimon.ownlang.parser.*;
import com.annimon.ownlang.parser.ast.Statement; import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
import com.annimon.ownlang.parser.linters.LinterStage; import com.annimon.ownlang.parser.linters.LinterStage;
import com.annimon.ownlang.parser.optimization.OptimizationStage;
import com.annimon.ownlang.stages.*; import com.annimon.ownlang.stages.*;
import com.annimon.ownlang.utils.Repl; import com.annimon.ownlang.utils.Repl;
import com.annimon.ownlang.utils.Sandbox; import com.annimon.ownlang.utils.Sandbox;
@ -142,13 +144,13 @@ public final class Main {
final var scopedStages = new ScopedStageFactory(measurement::start, measurement::stop); final var scopedStages = new ScopedStageFactory(measurement::start, measurement::stop);
final var stagesData = new StagesDataMap(); final var stagesData = new StagesDataMap();
stagesData.put(OptimizationStage.TAG_OPTIMIZATION_SUMMARY, options.showAst);
stagesData.put(SourceLoaderStage.TAG_SOURCE, input); stagesData.put(SourceLoaderStage.TAG_SOURCE, input);
try { try {
scopedStages.create("Lexer", new LexerStage()) scopedStages.create("Lexer", new LexerStage())
.then(scopedStages.create("Parser", new ParserStage())) .then(scopedStages.create("Parser", new ParserStage()))
.thenConditional(options.optimizationLevel > 0, .thenConditional(options.optimizationLevel > 0,
scopedStages.create("Optimization", new OptimizationStage(options.optimizationLevel))) scopedStages.create("Optimization",
new OptimizationStage(options.optimizationLevel, options.showAst)))
.thenConditional(options.lintMode, .thenConditional(options.lintMode,
scopedStages.create("Linter", new LinterStage())) scopedStages.create("Linter", new LinterStage()))
.then(scopedStages.create("Function adding", new FunctionAddingStage())) .then(scopedStages.create("Function adding", new FunctionAddingStage()))
@ -173,8 +175,9 @@ public final class Main {
if (options.showAst) { if (options.showAst) {
Statement program = stagesData.get(ParserStage.TAG_PROGRAM); Statement program = stagesData.get(ParserStage.TAG_PROGRAM);
System.out.println(program); System.out.println(program);
System.out.println(stagesData.getOrDefault(OptimizationStage.TAG_OPTIMIZATION_SUMMARY, ""));
} }
if (!options.showMeasurements) { if (options.showMeasurements) {
System.out.println("======================"); System.out.println("======================");
System.out.println(measurement.summary(TimeUnit.MILLISECONDS, true)); System.out.println(measurement.summary(TimeUnit.MILLISECONDS, true));
} }

View File

@ -1,49 +0,0 @@
package com.annimon.ownlang.parser;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
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 com.annimon.ownlang.parser.optimization.SummaryOptimization;
public final class Optimizer {
private Optimizer() { }
public static Statement optimize(Statement statement, int level, boolean showSummary) {
if (level == 0) return statement;
final Optimizable optimization = new SummaryOptimization(new Optimizable[] {
new ConstantFolding(),
new ConstantPropagation(),
new DeadCodeElimination(),
new ExpressionSimplification(),
new InstructionCombining()
});
Node result = statement;
if (level >= 9) {
int iteration = 0, lastModifications = 0;
do {
lastModifications = optimization.optimizationsCount();
result = optimization.optimize(result);
iteration++;
} while (lastModifications != optimization.optimizationsCount());
if (showSummary)
Console.print("Performs " + iteration + " optimization iterations");
} else {
for (int i = 0; i < level; i++) {
result = optimization.optimize(result);
}
}
if (showSummary) {
Console.println(optimization.summaryInfo());
}
return (Statement) result;
}
}

View File

@ -0,0 +1,56 @@
package com.annimon.ownlang.parser.optimization;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.stages.Stage;
import com.annimon.ownlang.stages.StagesData;
public class OptimizationStage implements Stage<Statement, Statement> {
public static final String TAG_OPTIMIZATION_SUMMARY = "optimizationSummary";
private final int level;
private final boolean summary;
private final Optimizable optimization;
public OptimizationStage(int level) {
this(level, false);
}
public OptimizationStage(int level, boolean summary) {
this.level = level;
this.summary = summary;
optimization = new SummaryOptimization(new Optimizable[] {
new ConstantFolding(),
new ConstantPropagation(),
new DeadCodeElimination(),
new ExpressionSimplification(),
new InstructionCombining()
});
}
@Override
public Statement perform(StagesData stagesData, Statement input) {
if (level == 0) return input;
Node result = input;
final int maxIterations = level >= 9 ? Integer.MAX_VALUE : level;
int lastModifications;
int iteration = 0;
do {
lastModifications = optimization.optimizationsCount();
result = optimization.optimize(result);
iteration++;
} while (lastModifications != optimization.optimizationsCount() && iteration < maxIterations);
if (this.summary) {
stagesData.put(TAG_OPTIMIZATION_SUMMARY, """
Performed %d optimization iterations
%s
""".formatted(iteration, optimization.summaryInfo())
);
}
return (Statement) result;
}
}

View File

@ -1,16 +0,0 @@
package com.annimon.ownlang.stages;
import com.annimon.ownlang.parser.Optimizer;
import com.annimon.ownlang.parser.ast.Statement;
public record OptimizationStage(int level)
implements Stage<Statement, Statement> {
public static final String TAG_OPTIMIZATION_SUMMARY = "optimizationSummary";
@Override
public Statement perform(StagesData stagesData, Statement input) {
boolean showSummary = stagesData.getOrDefault(TAG_OPTIMIZATION_SUMMARY, false);
return Optimizer.optimize(input, level, showSummary);
}
}