diff --git a/teavm-classlib/pom.xml b/teavm-classlib/pom.xml index f5e88105d..c3407f71d 100644 --- a/teavm-classlib/pom.xml +++ b/teavm-classlib/pom.xml @@ -52,7 +52,7 @@ process-test-classes - true + false diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index a0aef8f68..0aab4352b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -201,7 +201,7 @@ public class Decompiler { methodNode.getVariables().add(program.variableAt(i).getRegister()); } Optimizer optimizer = new Optimizer(); - optimizer.optimize(methodNode); + optimizer.optimize(methodNode, method.getProgram()); return methodNode; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java index 7e5047432..4938ffcbd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java @@ -37,7 +37,7 @@ public class JavascriptBuilder { private DependencyChecker dependencyChecker; private ClassLoader classLoader; private boolean minifying = true; - private boolean bytecodeLogging; + private boolean bytecodeLogging = true; private OutputStream logStream = System.out; private Map entryPoints = new HashMap<>(); private Map exportedClasses = new HashMap<>(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index d1275438a..1215f0c65 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -16,8 +16,7 @@ package org.teavm.javascript; import org.teavm.javascript.ast.RegularMethodNode; -import org.teavm.javascript.ast.Statement; -import org.teavm.model.MethodHolder; +import org.teavm.model.Program; /** @@ -25,17 +24,9 @@ import org.teavm.model.MethodHolder; * @author Alexey Andreev */ public class Optimizer { - public Statement optimize(MethodHolder method, Statement statement) { - ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getProgram().variableCount()); - statement.acceptVisitor(stats); - OptimizingVisitor optimizer = new OptimizingVisitor(stats); - statement.acceptVisitor(optimizer); - return optimizer.resultStmt; - } - - public void optimize(RegularMethodNode method) { + public void optimize(RegularMethodNode method, Program program) { ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); - method.getBody().acceptVisitor(stats); + stats.analyze(program); OptimizingVisitor optimizer = new OptimizingVisitor(stats); method.getBody().acceptVisitor(optimizer); method.setBody(optimizer.resultStmt); diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index 4a83b85ca..d26635b05 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -377,7 +377,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { WhileStatement result = new WhileStatement(); result.setId(statement.getId()); visitIdentified(statement, result); - List statements = processSequence(statement.getBody(), false); + List statements = processSequence(statement.getBody(), true); if (statement.getCondition() != null) { statement.getCondition().acceptVisitor(this); result.setCondition(resultExpr); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java index 9bf75287f..30eb4c0a5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java @@ -15,13 +15,15 @@ */ package org.teavm.javascript; -import org.teavm.javascript.ast.*; +import org.teavm.model.*; +import org.teavm.model.util.DefinitionExtractor; +import org.teavm.model.util.UsageExtractor; /** * * @author Alexey Andreev */ -class ReadWriteStatsBuilder implements StatementVisitor, ExprVisitor { +class ReadWriteStatsBuilder { public int[] reads; public int[] writes; @@ -30,169 +32,27 @@ class ReadWriteStatsBuilder implements StatementVisitor, ExprVisitor { writes = new int[variableCount]; } - @Override - public void visit(BinaryExpr expr) { - expr.getFirstOperand().acceptVisitor(this); - expr.getSecondOperand().acceptVisitor(this); - } - - @Override - public void visit(UnaryExpr expr) { - expr.getOperand().acceptVisitor(this); - } - - @Override - public void visit(ConditionalExpr expr) { - expr.getCondition().acceptVisitor(this); - expr.getConsequent().acceptVisitor(this); - expr.getAlternative().acceptVisitor(this); - } - - @Override - public void visit(ConstantExpr expr) { - } - - @Override - public void visit(VariableExpr expr) { - reads[expr.getIndex()]++; - } - - @Override - public void visit(SubscriptExpr expr) { - expr.getArray().acceptVisitor(this); - expr.getIndex().acceptVisitor(this); - } - - @Override - public void visit(UnwrapArrayExpr expr) { - expr.getArray().acceptVisitor(this); - } - - @Override - public void visit(InvocationExpr expr) { - for (Expr arg : expr.getArguments()) { - arg.acceptVisitor(this); - } - } - - @Override - public void visit(QualificationExpr expr) { - expr.getQualified().acceptVisitor(this); - } - - @Override - public void visit(NewExpr expr) { - } - - @Override - public void visit(NewArrayExpr expr) { - expr.getLength().acceptVisitor(this); - } - - @Override - public void visit(NewMultiArrayExpr expr) { - for (Expr dimension : expr.getDimensions()) { - dimension.acceptVisitor(this); - } - } - - @Override - public void visit(InstanceOfExpr expr) { - expr.getExpr().acceptVisitor(this); - } - - @Override - public void visit(StaticClassExpr expr) { - } - - @Override - public void visit(AssignmentStatement statement) { - if (statement.getLeftValue() != null) { - if (statement.getLeftValue() instanceof VariableExpr) { - VariableExpr leftVar = (VariableExpr)statement.getLeftValue(); - writes[leftVar.getIndex()]++; - } else { - statement.getLeftValue().acceptVisitor(this); + public void analyze(Program program) { + DefinitionExtractor defExtractor = new DefinitionExtractor(); + UsageExtractor useExtractor = new UsageExtractor(); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + for (Instruction insn : block.getInstructions()) { + insn.acceptVisitor(defExtractor); + insn.acceptVisitor(useExtractor); + for (Variable var : defExtractor.getDefinedVariables()) { + writes[var.getIndex()]++; + } + for (Variable var : useExtractor.getUsedVariables()) { + reads[var.getIndex()]++; + } + } + for (Phi phi : block.getPhis()) { + writes[phi.getReceiver().getIndex()] += phi.getIncomings().size(); + for (Incoming incoming : phi.getIncomings()) { + reads[incoming.getValue().getIndex()]++; + } } } - statement.getRightValue().acceptVisitor(this); - } - - @Override - public void visit(SequentialStatement statement) { - for (Statement part : statement.getSequence()) { - part.acceptVisitor(this); - } - } - - @Override - public void visit(ConditionalStatement statement) { - statement.getCondition().acceptVisitor(this); - statement.getConsequent().acceptVisitor(this); - if (statement.getAlternative() != null) { - statement.getAlternative().acceptVisitor(this); - } - } - - @Override - public void visit(SwitchStatement statement) { - statement.getValue().acceptVisitor(this); - for (SwitchClause clause : statement.getClauses()) { - clause.getStatement().acceptVisitor(this); - } - if (statement.getDefaultClause() != null) { - statement.getDefaultClause().acceptVisitor(this); - } - } - - @Override - public void visit(WhileStatement statement) { - if (statement.getCondition() != null) { - statement.getCondition().acceptVisitor(this); - } - for (Statement part : statement.getBody()) { - part.acceptVisitor(this); - } - } - - @Override - public void visit(BlockStatement statement) { - for (Statement part : statement.getBody()) { - part.acceptVisitor(this); - } - } - - @Override - public void visit(ForStatement statement) { - } - - @Override - public void visit(BreakStatement statement) { - } - - @Override - public void visit(ContinueStatement statement) { - } - - @Override - public void visit(ReturnStatement statement) { - if (statement.getResult() != null) { - statement.getResult().acceptVisitor(this); - } - } - - @Override - public void visit(ThrowStatement statement) { - statement.getException().acceptVisitor(this); - } - - @Override - public void visit(IncrementStatement statement) { - reads[statement.getVar()]++; - writes[statement.getVar()]++; - } - - @Override - public void visit(InitClassStatement statement) { } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java index bfe7c0351..d03e4db90 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java +++ b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java @@ -35,13 +35,11 @@ class GraphColorer { classMembers.get(cls).add(i); } for (int i = 0; i < colors.length; ++i) { - int color = colors[i]; - if (color != -1) { + if (colors[i] >= 0) { int cls = classes[i]; for (int member : classMembers.get(cls)) { - colors[member] = color; + colors[member] = colors[i]; } - classMembers.get(cls).clear(); } } BitSet usedColors = new BitSet(); @@ -49,15 +47,18 @@ class GraphColorer { if (colors[v] >= 0) { continue; } + int cls = classes[v]; usedColors.clear(); usedColors.set(0); - for (int succ : graph.outgoingEdges(v)) { - if (colors[succ] >= 0) { - usedColors.set(colors[succ]); + for (int member : classMembers.get(cls)) { + for (int succ : graph.outgoingEdges(member)) { + if (colors[succ] >= 0) { + usedColors.set(colors[succ]); + } } } int color = usedColors.nextClearBit(0); - for (int member : classMembers.get(classes[v])) { + for (int member : classMembers.get(cls)) { colors[member] = color; } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java b/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java index 5006fb30e..e69a46cee 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java @@ -25,7 +25,7 @@ import org.teavm.model.*; * @author Alexey Andreev */ class InterferenceGraphBuilder { - public Graph build(Program program, LivenessAnalyzer liveness) { + public Graph build(Program program, int paramCount, LivenessAnalyzer liveness) { List> edges = new ArrayList<>(); for (int i = 0; i < program.variableCount(); ++i) { edges.add(new HashSet()); @@ -64,6 +64,11 @@ class InterferenceGraphBuilder { live.add(var.getIndex()); } } + if (block.getIndex() == 0) { + for (int j = 0; j <= paramCount; ++j) { + edges.get(j).addAll(live); + } + } BitSet liveIn = liveness.liveIn(i); live = new HashSet<>(); for (int j = 0; j < liveOut.length(); ++j) { diff --git a/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java b/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java index 1b6865807..b45d5c002 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java +++ b/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java @@ -34,7 +34,7 @@ public class RegisterAllocator { InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder(); LivenessAnalyzer liveness = new LivenessAnalyzer(); liveness.analyze(program); - Graph interferenceGraph = interferenceBuilder.build(program, liveness); + Graph interferenceGraph = interferenceBuilder.build(program, method.parameterCount(), liveness); DisjointSet congruenceClasses = buildPhiCongruenceClasses(program); removeRedundantCopies(program, phiArgsCopies, interferenceGraph, congruenceClasses); int[] classArray = congruenceClasses.pack(program.variableCount());