package dk.brics.xact.analysis.transformations;
import java.util.HashSet;
import java.util.LinkedList;
import dk.brics.xact.analysis.Debug;
import dk.brics.xact.analysis.flowgraph.Edge;
import dk.brics.xact.analysis.flowgraph.FlowGraph;
import dk.brics.xact.analysis.flowgraph.Statement;
import dk.brics.xact.analysis.flowgraph.VariableFilter;
/**
* Removes all nodes that are not reachable from an entry node.
*/
public class UnreachableTransformer {
/**
* Constructs a new <code>UnreachableTransformer</code>.
*/
public UnreachableTransformer() {}
/**
* Transforms the given flow graph.
*/
public void run(FlowGraph graph) {
// find reachable nodes
HashSet<Statement> reachable = new HashSet<Statement>();
LinkedList<Statement> queue = new LinkedList<Statement>();
queue.addAll(graph.getEntries());
while (!queue.isEmpty()) {
Statement s = queue.removeFirst();
if (!reachable.contains(s)) {
reachable.add(s);
for (Edge<Statement,VariableFilter> edge : graph.getOutEdges(s))
if (edge.getData().getKind() != VariableFilter.Kind.RETURN)
queue.addLast(edge.getTo());
}
}
// remove unreachable nodes
int before = graph.getNodes().size();
for (Statement s : new HashSet<Statement>(graph.getNodes()))
if (!reachable.contains(s))
graph.removeNode(s);
Debug.println(5, true, "Removed " + (before - graph.getNodes().size()) + " nodes");
}
}