package dk.brics.xact.analysis.transformations;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import dk.brics.xact.analysis.dataflow.AnalysisInterface;
import dk.brics.xact.analysis.flowgraph.FlowGraph;
import dk.brics.xact.analysis.flowgraph.Statement;
import dk.brics.xact.analysis.flowgraph.Variable;
import dk.brics.xact.analysis.flowgraph.VariableFilter;
import dk.brics.xact.analysis.flowgraph.statements.Assignment;
/**
* Lattice and transfer functions for reaching definitions analysis.
* Maps each variable to a set of all statements that may assign to that variable.
*/
public class ReachingDefinitionsAnalysis implements AnalysisInterface<Map<Variable,Set<Assignment>>> {
/**
* Constructs a new analysis object.
*/
public ReachingDefinitionsAnalysis() {}
public Map<Variable,Set<Assignment>> newBottomElement() {
return new HashMap<Variable,Set<Assignment>>();
}
private boolean setput(Map<Variable,Set<Assignment>> map, Variable key, Assignment value) {
if (!map.containsKey(key))
map.put(key, new LinkedHashSet<Assignment>());
return map.get(key).add(value);
}
private boolean setput(Map<Variable,Set<Assignment>> map, Variable key, Set<Assignment> value) {
if (!map.containsKey(key))
map.put(key, new LinkedHashSet<Assignment>());
return map.get(key).addAll(value);
}
public boolean merge(Map<Variable,Set<Assignment>> source, VariableFilter filter, Map<Variable,Set<Assignment>> dest) {
boolean changed = false;
for (Map.Entry<Variable,Set<Assignment>> e : source.entrySet()) {
Variable var = e.getKey();
if (filter.containsVariable(var))
changed |= setput(dest, var, e.getValue());
}
return changed;
}
public boolean transfer(Map<Variable,Set<Assignment>> in, Statement s, Map<Variable,Set<Assignment>> out) {
VariableFilter filter = new VariableFilter();
boolean changed = false;
if (s instanceof Assignment) {
Variable var = ((Assignment)s).getDest();
changed |= setput(out, var, (Assignment)s);
filter.removeVariable(var);
}
changed |= merge(in, filter, out);
return changed;
}
public boolean isForward() {
return true;
}
public Set<Statement> getInitial(FlowGraph g) {
return g.getEntries();
}
}