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());