While eliminator

This commit is contained in:
konsoletyper 2014-01-30 17:36:56 +04:00
parent 692bfdd731
commit 3496907f0e
2 changed files with 137 additions and 0 deletions

View File

@ -0,0 +1,111 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.javascript;
import java.util.List;
import org.teavm.javascript.ast.*;
/**
*
* @author Alexey Andreev
*/
class BreakToContinueReplacer implements StatementVisitor {
private IdentifiedStatement replacedBreak;
private IdentifiedStatement replacement;
private ContinueStatement replaceBy;
public BreakToContinueReplacer(IdentifiedStatement replacedBreak, IdentifiedStatement replacement) {
this.replacedBreak = replacedBreak;
this.replacement = replacement;
}
@Override
public void visit(AssignmentStatement statement) {
}
public void visitSequence(List<Statement> statements) {
for (int i = 0; i < statements.size(); ++i) {
Statement stmt = statements.get(i);
stmt.acceptVisitor(this);
if (replaceBy != null) {
statements.set(i, replaceBy);
replaceBy = null;
}
}
}
@Override
public void visit(SequentialStatement statement) {
visitSequence(statement.getSequence());
}
@Override
public void visit(ConditionalStatement statement) {
visitSequence(statement.getConsequent());
visitSequence(statement.getAlternative());
}
@Override
public void visit(SwitchStatement statement) {
for (SwitchClause clause : statement.getClauses()) {
visitSequence(clause.getBody());
}
visitSequence(statement.getDefaultClause());
}
@Override
public void visit(WhileStatement statement) {
visitSequence(statement.getBody());
}
@Override
public void visit(BlockStatement statement) {
visitSequence(statement.getBody());
}
@Override
public void visit(ForStatement statement) {
}
@Override
public void visit(BreakStatement statement) {
if (statement.getTarget() == replacedBreak) {
replaceBy = new ContinueStatement();
replaceBy.setTarget(replacement);
}
}
@Override
public void visit(ContinueStatement statement) {
}
@Override
public void visit(ReturnStatement statement) {
}
@Override
public void visit(ThrowStatement statement) {
}
@Override
public void visit(IncrementStatement statement) {
}
@Override
public void visit(InitClassStatement statement) {
}
}

View File

@ -447,6 +447,13 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
@Override @Override
public void visit(WhileStatement statement) { public void visit(WhileStatement statement) {
if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) {
WhileStatement innerLoop = (WhileStatement)statement.getBody().get(0);
BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement);
replacer.visitSequence(innerLoop.getBody());
statement.getBody().clear();
statement.getBody().addAll(innerLoop.getBody());
}
List<Statement> statements = processSequence(statement.getBody(), true); List<Statement> statements = processSequence(statement.getBody(), true);
statement.getBody().clear(); statement.getBody().clear();
statement.getBody().addAll(statements); statement.getBody().addAll(statements);
@ -454,6 +461,25 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
statement.getCondition().acceptVisitor(this); statement.getCondition().acceptVisitor(this);
statement.setCondition(resultExpr); statement.setCondition(resultExpr);
} }
while (true) {
if (!statement.getBody().isEmpty() && statement.getBody().get(0) instanceof ConditionalStatement) {
ConditionalStatement cond = (ConditionalStatement)statement.getBody().get(0);
if (cond.getConsequent().size() == 1 && cond.getConsequent().get(0) instanceof BreakStatement) {
BreakStatement breakStmt = (BreakStatement)cond.getConsequent().get(0);
if (breakStmt.getTarget() == statement) {
statement.getBody().remove(0);
if (statement.getCondition() != null) {
statement.setCondition(Expr.binary(BinaryOperation.AND, statement.getCondition(),
ExprOptimizer.invert(cond.getCondition())));
} else {
statement.setCondition(ExprOptimizer.invert(cond.getCondition()));
}
continue;
}
}
}
break;
}
resultStmt = statement; resultStmt = statement;
} }