58 lines
1.7 KiB
Java
58 lines
1.7 KiB
Java
package cd.transform.optimizers;
|
|
|
|
import cd.ir.Ast;
|
|
import cd.ir.Ast.*;
|
|
import cd.ir.BasicBlock;
|
|
import cd.ir.ControlFlowGraph;
|
|
import cd.ir.ExprVisitor;
|
|
import cd.ir.Symbol.VariableSymbol;
|
|
import cd.transform.analysis.LiveVarAnalysis;
|
|
|
|
import java.util.*;
|
|
|
|
public class WriteOnlyVarRemoval extends OptimizerVisitor<Set<VariableSymbol>> {
|
|
@Override
|
|
public boolean go(ControlFlowGraph cfg) {
|
|
LiveVarAnalysis analysis = new LiveVarAnalysis(cfg);
|
|
for (BasicBlock block : cfg.allBlocks) {
|
|
Set<VariableSymbol> state = new HashSet<>(analysis.outStateOf(block));
|
|
if (block.condition != null)
|
|
new LiveVarAnalysis.Visitor().visit(block.condition, state);
|
|
for (ListIterator<Stmt> iterator = block.stmts.listIterator(block.stmts.size()); iterator.hasPrevious(); ) {
|
|
Stmt stmt = iterator.previous();
|
|
Ast res = visit(stmt, state);
|
|
// TODO: this code should work? even if we iterate through the newly created Stmt nodes
|
|
if (stmt != res) {
|
|
iterator.remove();
|
|
assert res instanceof Seq;
|
|
Seq seq = (Seq) res;
|
|
for (Ast ast : seq.rwChildren) {
|
|
assert ast instanceof Stmt;
|
|
iterator.add((Stmt) ast);
|
|
}
|
|
nodeReplaced(stmt, res);
|
|
}
|
|
}
|
|
}
|
|
return hasChanged();
|
|
}
|
|
|
|
@Override
|
|
public Ast assign(Assign ast, Set<VariableSymbol> arg) {
|
|
if (ast.left() instanceof Var && !arg.contains(((Var) ast.left()).sym)) {
|
|
List<Ast> methodCalls = new ArrayList<>();
|
|
new MethodCallFinder().visit(ast.right(), methodCalls);
|
|
return new Seq(methodCalls);
|
|
} else {
|
|
return ast;
|
|
}
|
|
}
|
|
|
|
private class MethodCallFinder extends ExprVisitor<Void, List<Ast>> {
|
|
@Override
|
|
public Void methodCall(Ast.MethodCallExpr ast, List<Ast> arg) {
|
|
arg.add(new MethodCall(ast));
|
|
return null;
|
|
}
|
|
}
|
|
}
|