package dk.brics.jspointers.flowgraph.analysis;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import dk.brics.tajs.flowgraph.Node;
import dk.brics.tajs.flowgraph.nodes.AssignmentNode;
import dk.brics.tajs.flowgraph.nodes.CatchNode;
import dk.brics.tajs.flowgraph.nodes.ReadVariableNode;
import dk.brics.tajs.flowgraph.nodes.WriteVariableNode;
import dk.brics.tajs.optimizer2.Decorator;
import dk.brics.tajs.optimizer2.analysis.FlowAnalysis;
public class LiveVarsAnalysis extends FlowAnalysis<Set<LocalVariable>> {
private Decorator decorator;
private ReadVarsInterface readvars;
private Set<String> privateVariables;
public LiveVarsAnalysis(Decorator decorator, ReadVarsInterface readvars, Set<String> privateVariables) {
super(new SetLattice<LocalVariable>());
this.decorator = decorator;
this.readvars = readvars;
this.privateVariables = privateVariables;
}
@Override
public Set<Node> getJoinSet(Node node) {
return decorator.getAllSuccessorNodes(node);
}
@Override
public Set<Node> getDependencySet(Node node) {
return decorator.getAllPredecessorNodes(node);
}
@Override
public Set<LocalVariable> defaultLatticePoint(Node n, Set<LocalVariable> after) {
Set<LocalVariable> s = new HashSet<LocalVariable>(after);
boolean ignorable = false;
// decide if the statement can be ignored due to irrelevant result node
if (n instanceof AssignmentNode) {
AssignmentNode asn = (AssignmentNode)n;
LocalTemporaryVariable var = new LocalTemporaryVariable(asn.getResultVar());
if (new IsPureAssignmentVisitor().isPure(asn) && !after.contains(var)) {
ignorable = true;
}
} else if (n instanceof WriteVariableNode) {
WriteVariableNode write = (WriteVariableNode)n;
if (privateVariables.contains(write.getVarName())) {
// important: writes to non-private variables can NOT be ignored
if (!after.contains(new LocalProgramVariable(write.getVarName()))) {
ignorable = true;
}
}
}
// nothing to change if ignorable
if (ignorable)
return Collections.unmodifiableSet(s);
// update temporary variables
if (n instanceof AssignmentNode) {
AssignmentNode asn = (AssignmentNode)n;
LocalTemporaryVariable var = new LocalTemporaryVariable(asn.getResultVar());
s.remove(var);
}
else if (n instanceof CatchNode) {
CatchNode ct = (CatchNode)n;
if (ct.getTempVar() != Node.NO_VALUE) {
s.remove(new LocalTemporaryVariable(ct.getTempVar()));
} else {
s.remove(new LocalTemporaryVariable(ct.getScopeObjVar()));
}
}
int[] vars = readvars.getReadVars(n);
for (int var : vars) {
s.add(new LocalTemporaryVariable(var));
}
// update (private) program variables
if (n instanceof ReadVariableNode) {
ReadVariableNode read = (ReadVariableNode)n;
if (privateVariables.contains(read.getVarName())) {
s.add(new LocalProgramVariable(read.getVarName()));
}
}
else if (n instanceof WriteVariableNode) {
WriteVariableNode write = (WriteVariableNode)n;
if (privateVariables.contains(write.getVarName())) {
s.remove(new LocalProgramVariable(write.getVarName()));
}
}
return Collections.unmodifiableSet(s);
}
}