mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Better fix for https://github.com/konsoletyper/teavm/issues/85
This commit is contained in:
parent
14dd352cb6
commit
79b805ba6c
|
@ -29,7 +29,13 @@ public class Optimizer {
|
|||
public void optimize(RegularMethodNode method, Program program) {
|
||||
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
||||
stats.analyze(program);
|
||||
OptimizingVisitor optimizer = new OptimizingVisitor(stats);
|
||||
boolean[] preservedVars = new boolean[stats.writes.length];
|
||||
for (int i = 0; i < preservedVars.length; ++i) {
|
||||
if (stats.writes[i] != 1) {
|
||||
preservedVars[i] = true;
|
||||
}
|
||||
}
|
||||
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads);
|
||||
method.getBody().acceptVisitor(optimizer);
|
||||
method.setBody(optimizer.resultStmt);
|
||||
int paramCount = method.getReference().parameterCount();
|
||||
|
@ -44,12 +50,21 @@ public class Optimizer {
|
|||
}
|
||||
|
||||
public void optimize(AsyncMethodNode method, AsyncProgramSplitter splitter) {
|
||||
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
||||
boolean[] preservedVars = new boolean[method.getVariables().size()];
|
||||
int[][] readFrequencies = new int[splitter.size()][];
|
||||
for (int i = 0; i < splitter.size(); ++i) {
|
||||
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
||||
stats.analyze(splitter.getProgram(i));
|
||||
readFrequencies[i] = stats.reads;
|
||||
for (int j = 0; j < stats.writes.length; ++j) {
|
||||
if (stats.readUninitialized[j] || stats.writes[j] != 1 && stats.reads[j] > 0) {
|
||||
preservedVars[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (AsyncMethodPart part : method.getBody()) {
|
||||
OptimizingVisitor optimizer = new OptimizingVisitor(stats.copy());
|
||||
for (int i = 0; i < splitter.size(); ++i) {
|
||||
AsyncMethodPart part = method.getBody().get(i);
|
||||
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, readFrequencies[i]);
|
||||
part.getStatement().acceptVisitor(optimizer);
|
||||
part.setStatement(optimizer.resultStmt);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,13 @@ import org.teavm.javascript.ast.*;
|
|||
class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||
public Expr resultExpr;
|
||||
public Statement resultStmt;
|
||||
private ReadWriteStatsBuilder stats;
|
||||
private boolean[] preservedVars;
|
||||
private int[] readFrequencies;
|
||||
private List<Statement> resultSequence;
|
||||
|
||||
public OptimizingVisitor(ReadWriteStatsBuilder stats) {
|
||||
this.stats = stats;
|
||||
public OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) {
|
||||
this.preservedVars = preservedVars;
|
||||
this.readFrequencies = readFreqencies;
|
||||
}
|
||||
|
||||
private static boolean isZero(Expr expr) {
|
||||
|
@ -121,7 +123,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
public void visit(VariableExpr expr) {
|
||||
int index = expr.getIndex();
|
||||
resultExpr = expr;
|
||||
if (stats.reads[index] != 1 || stats.writes[index] != 1) {
|
||||
if (readFrequencies[index] != 1 || preservedVars[index]) {
|
||||
return;
|
||||
}
|
||||
if (resultSequence.isEmpty()) {
|
||||
|
@ -217,7 +219,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
||||
constructrExpr.setLocation(expr.getLocation());
|
||||
assignment.setRightValue(constructrExpr);
|
||||
stats.reads[var.getIndex()]--;
|
||||
readFrequencies[var.getIndex()]--;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
package org.teavm.javascript;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.teavm.common.Graph;
|
||||
import org.teavm.common.GraphUtils;
|
||||
import org.teavm.common.IntegerStack;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.util.DefinitionExtractor;
|
||||
import org.teavm.model.util.ProgramUtils;
|
||||
import org.teavm.model.util.UsageExtractor;
|
||||
|
||||
/**
|
||||
|
@ -27,6 +31,7 @@ import org.teavm.model.util.UsageExtractor;
|
|||
class ReadWriteStatsBuilder {
|
||||
public int[] reads;
|
||||
public int[] writes;
|
||||
public boolean[] readUninitialized;
|
||||
|
||||
private ReadWriteStatsBuilder() {
|
||||
}
|
||||
|
@ -34,6 +39,7 @@ class ReadWriteStatsBuilder {
|
|||
public ReadWriteStatsBuilder(int variableCount) {
|
||||
reads = new int[variableCount];
|
||||
writes = new int[variableCount];
|
||||
readUninitialized = new boolean[variableCount];
|
||||
}
|
||||
|
||||
public ReadWriteStatsBuilder copy() {
|
||||
|
@ -44,10 +50,15 @@ class ReadWriteStatsBuilder {
|
|||
}
|
||||
|
||||
public void analyze(Program program) {
|
||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||
Graph dom = GraphUtils.buildDominatorGraph(GraphUtils.buildDominatorTree(cfg), cfg.size());
|
||||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||
UsageExtractor useExtractor = new UsageExtractor();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
IntegerStack stack = new IntegerStack(program.basicBlockCount());
|
||||
stack.push(0);
|
||||
while (!stack.isEmpty()) {
|
||||
int node = stack.pop();
|
||||
BasicBlock block = program.basicBlockAt(node);
|
||||
for (Instruction insn : block.getInstructions()) {
|
||||
insn.acceptVisitor(defExtractor);
|
||||
insn.acceptVisitor(useExtractor);
|
||||
|
@ -56,18 +67,27 @@ class ReadWriteStatsBuilder {
|
|||
}
|
||||
for (Variable var : useExtractor.getUsedVariables()) {
|
||||
reads[var.getIndex()]++;
|
||||
if (writes[var.getIndex()] == 0) {
|
||||
readUninitialized[var.getIndex()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Phi phi : block.getPhis()) {
|
||||
writes[phi.getReceiver().getIndex()] += phi.getIncomings().size();
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
reads[incoming.getValue().getIndex()]++;
|
||||
if (writes[incoming.getValue().getIndex()] == 0) {
|
||||
reads[incoming.getValue().getIndex()]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||
writes[tryCatch.getExceptionVariable().getIndex()]++;
|
||||
reads[tryCatch.getExceptionVariable().getIndex()]++;
|
||||
}
|
||||
|
||||
for (int succ : dom.outgoingEdges(node)) {
|
||||
stack.push(succ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user