Slightly improves AST optimizer

This commit is contained in:
konsoletyper 2014-01-28 17:29:36 +04:00
parent 24921c6e80
commit d93883296e

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.javascript; package org.teavm.javascript;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.teavm.javascript.ast.*; import org.teavm.javascript.ast.*;
@ -53,8 +54,8 @@ class ConditionalOptimizer {
return stmt; return stmt;
} }
SequentialStatement altBody = new SequentialStatement(); SequentialStatement altBody = new SequentialStatement();
for (int i = 1; i < stmt.getBody().size(); ++i) { for (int j = 1; j < stmt.getBody().size(); ++j) {
altBody.getSequence().add(stmt.getBody().get(i)); altBody.getSequence().add(stmt.getBody().get(j));
} }
if (!altBody.getSequence().isEmpty()) { if (!altBody.getSequence().isEmpty()) {
condStmt.setAlternative(altBody.getSequence().size() != 1 ? condStmt.setAlternative(altBody.getSequence().size() != 1 ?
@ -75,51 +76,47 @@ class ConditionalOptimizer {
} }
public Statement tryOptimize(BlockStatement stmt) { public Statement tryOptimize(BlockStatement stmt) {
Expr condition = null; for (int i = 0; i < stmt.getBody().size(); ++i) {
while (true) {
if (stmt.getBody().isEmpty()) { if (stmt.getBody().isEmpty()) {
break; continue;
} }
if (!(stmt.getBody().get(0) instanceof ConditionalStatement)) { if (!(stmt.getBody().get(i) instanceof ConditionalStatement)) {
break; continue;
} }
ConditionalStatement condStmt = (ConditionalStatement)stmt.getBody().get(0); ConditionalStatement condStmt = (ConditionalStatement)stmt.getBody().get(i);
if (condStmt.getAlternative() != null) { if (condStmt.getAlternative() != null) {
break; continue;
} }
if (!(condStmt.getConsequent() instanceof BreakStatement)) { if (!(condStmt.getConsequent() instanceof BreakStatement)) {
break; continue;
} }
BreakStatement breakStmt = (BreakStatement)condStmt.getConsequent(); BreakStatement breakStmt = (BreakStatement)condStmt.getConsequent();
if (breakStmt.getTarget() != stmt) { if (breakStmt.getTarget() != stmt) {
break; continue;
}
stmt.getBody().remove(0);
if (condition == null) {
condition = ExprOptimizer.invert(condStmt.getCondition());
} else {
condition = Expr.binary(BinaryOperation.AND, condition,
ExprOptimizer.invert(condStmt.getCondition()));
} }
stmt.getBody().remove(i);
referencedStatements.put(stmt, referencedStatements.get(stmt) - 1); referencedStatements.put(stmt, referencedStatements.get(stmt) - 1);
} ConditionalStatement newCond = new ConditionalStatement();
if (condition == null) { newCond.setCondition(ExprOptimizer.invert(condStmt.getCondition()));
return stmt; List<Statement> remaining = stmt.getBody().subList(i, stmt.getBody().size());
} if (remaining.size() == 1) {
ConditionalStatement newCond = new ConditionalStatement(); newCond.setConsequent(remaining.get(0));
newCond.setCondition(condition);
if (referencedStatements.get(stmt) > 0) {
newCond.setConsequent(stmt);
} else {
if (stmt.getBody().size() == 1) {
newCond.setConsequent(stmt.getBody().get(0));
} else { } else {
SequentialStatement consequent = new SequentialStatement(); SequentialStatement newConsequent = new SequentialStatement();
consequent.getSequence().addAll(stmt.getBody()); newConsequent.getSequence().addAll(remaining);
newCond.setConsequent(consequent); newCond.setConsequent(newConsequent);
}
remaining.clear();
stmt.getBody().add(newCond);
if (referencedStatements.get(stmt) == 0) {
SequentialStatement flat = new SequentialStatement();
flat.getSequence().addAll(stmt.getBody());
return flat;
} else {
--i;
} }
} }
return newCond; return stmt;
} }
public void tryOptimize(WhileStatement stmt) { public void tryOptimize(WhileStatement stmt) {