This commit is contained in:
konsoletyper 2015-03-12 21:20:36 +03:00
parent 14dd352cb6
commit 79b805ba6c
3 changed files with 49 additions and 12 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}
}
}
}