Optimize if statement to ternary conditional expression

This commit is contained in:
Alexey Andreev 2017-01-29 23:33:51 +03:00
parent ecd58e3573
commit fa0e884931
3 changed files with 62 additions and 16 deletions

View File

@ -35,14 +35,9 @@ public class Optimizer {
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
stats.analyze(program);
boolean[] preservedVars = new boolean[stats.writes.length];
for (int i = 0; i < preservedVars.length; ++i) {
if (stats.writes[i] != 1) {
preservedVars[i] = true;
}
}
BreakEliminator breakEliminator = new BreakEliminator();
breakEliminator.eliminate(method.getBody());
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads);
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads);
method.getBody().acceptVisitor(optimizer);
method.setBody(optimizer.resultStmt);
int paramCount = method.getReference().parameterCount();
@ -70,17 +65,12 @@ public class Optimizer {
boolean[] preservedVars = new boolean[method.getVariables().size()];
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
stats.analyze(splitter.getProgram(i));
for (int j = 0; j < stats.writes.length; ++j) {
if (stats.writes[j] != 1 && stats.reads[j] > 0) {
preservedVars[j] = true;
}
}
AsyncMethodPart part = method.getBody().get(i);
BreakEliminator breakEliminator = new BreakEliminator();
breakEliminator.eliminate(part.getStatement());
findEscapingLiveVars(liveness, cfg, splitter, i, preservedVars);
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads);
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads);
part.getStatement().acceptVisitor(optimizer);
part.setStatement(optimizer.resultStmt);
}

View File

@ -63,12 +63,14 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
private Expr resultExpr;
Statement resultStmt;
private final boolean[] preservedVars;
private final int[] writeFrequencies;
private final int[] readFrequencies;
private List<Statement> resultSequence;
OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) {
OptimizingVisitor(boolean[] preservedVars, int[] writeFrequencies, int[] readFrequencies) {
this.preservedVars = preservedVars;
this.readFrequencies = readFreqencies;
this.writeFrequencies = writeFrequencies;
this.readFrequencies = readFrequencies;
}
private static boolean isZero(Expr expr) {
@ -196,6 +198,9 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
public void visit(VariableExpr expr) {
int index = expr.getIndex();
resultExpr = expr;
if (writeFrequencies[index] != 1) {
return;
}
if (readFrequencies[index] != 1 || preservedVars[index]) {
return;
}
@ -569,7 +574,58 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
statement.getConsequent().addAll(consequent);
statement.getAlternative().clear();
statement.getAlternative().addAll(alternative);
resultStmt = statement;
Statement asConditional = tryConvertToConditionalExpression(statement);
if (asConditional != null) {
asConditional.acceptVisitor(this);
} else {
resultStmt = statement;
}
}
private Statement tryConvertToConditionalExpression(ConditionalStatement statement) {
if (statement.getConsequent().size() != 1 || statement.getAlternative().size() != 1) {
return null;
}
Statement first = statement.getConsequent().get(0);
Statement second = statement.getAlternative().get(0);
if (!(first instanceof AssignmentStatement) || !(second instanceof AssignmentStatement)) {
return null;
}
AssignmentStatement firstAssignment = (AssignmentStatement) first;
AssignmentStatement secondAssignment = (AssignmentStatement) second;
if (firstAssignment.getLeftValue() == null || secondAssignment.getRightValue() == null) {
return null;
}
if (firstAssignment.isAsync() || secondAssignment.isAsync()) {
return null;
}
if (!(firstAssignment.getLeftValue() instanceof VariableExpr)
|| !(secondAssignment.getLeftValue() instanceof VariableExpr)) {
return null;
}
VariableExpr firstLhs = (VariableExpr) firstAssignment.getLeftValue();
VariableExpr secondLhs = (VariableExpr) secondAssignment.getLeftValue();
if (firstLhs.getIndex() == secondLhs.getIndex()) {
ConditionalExpr conditionalExpr = new ConditionalExpr();
conditionalExpr.setCondition(statement.getCondition());
conditionalExpr.setConsequent(firstAssignment.getRightValue());
conditionalExpr.setAlternative(secondAssignment.getRightValue());
conditionalExpr.setLocation(statement.getCondition().getLocation());
AssignmentStatement assignment = new AssignmentStatement();
assignment.setLocation(conditionalExpr.getLocation());
VariableExpr lhs = new VariableExpr();
lhs.setIndex(firstLhs.getIndex());
assignment.setLeftValue(lhs);
assignment.setRightValue(conditionalExpr);
writeFrequencies[lhs.getIndex()]--;
return assignment;
}
return null;
}
@Override

View File

@ -936,7 +936,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
expr.getAlternative().acceptVisitor(this);
if (outerPrecedence.ordinal() > Precedence.CONDITIONAL.ordinal()) {
writer.append('(');
writer.append(')');
}
if (expr.getLocation() != null) {