move PrunedCFG to wala.core

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1045 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2007-05-03 17:07:57 +00:00
parent 9086a2aed6
commit 8c2927636c
1 changed files with 0 additions and 319 deletions

View File

@ -1,319 +0,0 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.ir.cfg;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import com.ibm.wala.cfg.ControlFlowGraph;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.shrikeBT.IInstruction;
import com.ibm.wala.util.CompoundIterator;
import com.ibm.wala.util.collections.Filter;
import com.ibm.wala.util.collections.FilterIterator;
import com.ibm.wala.util.collections.Iterator2Collection;
import com.ibm.wala.util.graph.AbstractNumberedGraph;
import com.ibm.wala.util.graph.EdgeManager;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.NodeManager;
import com.ibm.wala.util.graph.NumberedEdgeManager;
import com.ibm.wala.util.graph.NumberedNodeManager;
import com.ibm.wala.util.graph.impl.GraphInverter;
import com.ibm.wala.util.graph.traverse.DFS;
import com.ibm.wala.util.intset.BitVector;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.IntSetUtil;
import com.ibm.wala.util.intset.MutableIntSet;
public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements ControlFlowGraph {
public interface EdgeFilter {
boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst);
boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst);
}
private static class FilteredCFGEdges implements NumberedEdgeManager<IBasicBlock> {
private final ControlFlowGraph cfg;
private final NumberedNodeManager<IBasicBlock> currentCFGNodes;
private final EdgeFilter filter;
FilteredCFGEdges(ControlFlowGraph cfg, NumberedNodeManager<IBasicBlock> currentCFGNodes, EdgeFilter filter) {
this.cfg = cfg;
this.filter = filter;
this.currentCFGNodes = currentCFGNodes;
}
public Iterator<IBasicBlock> getExceptionalSuccessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getExceptionalSuccessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode((IBasicBlock) o) && filter.hasExceptionalEdge((IBasicBlock) N, (IBasicBlock) o);
}
});
}
public Iterator<IBasicBlock> getNormalSuccessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getNormalSuccessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasNormalEdge((IBasicBlock) N, (IBasicBlock) o);
}
});
}
public Iterator<IBasicBlock> getExceptionalPredecessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getExceptionalPredecessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasExceptionalEdge((IBasicBlock) o, (IBasicBlock) N);
}
});
}
public Iterator<IBasicBlock> getNormalPredecessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getNormalPredecessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasNormalEdge((IBasicBlock) o, (IBasicBlock) N);
}
});
}
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalSuccessors((IBasicBlock) N), getExceptionalSuccessors((IBasicBlock) N));
}
public int getSuccNodeCount(IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(getSuccNodes(N)).size();
}
public IntSet getSuccNodeNumbers(IBasicBlock N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getSuccNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
}
return bits;
}
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalPredecessors((IBasicBlock) N), getExceptionalPredecessors((IBasicBlock) N));
}
public int getPredNodeCount(IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(getPredNodes(N)).size();
}
public IntSet getPredNodeNumbers(IBasicBlock N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getPredNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
}
return bits;
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
for (Iterator EE = getSuccNodes(src); EE.hasNext();) {
if (EE.next().equals(dst)) {
return true;
}
}
return false;
}
public void addEdge(IBasicBlock src, IBasicBlock dst) {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
}
private static class FilteredNodes implements NumberedNodeManager<IBasicBlock> {
private final NumberedNodeManager<IBasicBlock> nodes;
private final Set subset;
FilteredNodes(NumberedNodeManager<IBasicBlock> nodes, Set subset) {
this.nodes = nodes;
this.subset = subset;
}
public int getNumber(IBasicBlock N) {
if (subset.contains(N))
return nodes.getNumber(N);
else
return -1;
}
public IBasicBlock getNode(int number) {
IBasicBlock N = nodes.getNode(number);
if (subset.contains(N))
return N;
else
throw new NoSuchElementException();
}
public int getMaxNumber() {
int max = -1;
for (Iterator<? extends IBasicBlock> NS = nodes.iterator(); NS.hasNext();) {
IBasicBlock N = NS.next();
if (subset.contains(N) && getNumber(N) > max) {
max = getNumber(N);
}
}
return max;
}
private Iterator<IBasicBlock> filterNodes(Iterator nodeIterator) {
return new FilterIterator<IBasicBlock>(nodeIterator, new Filter() {
public boolean accepts(Object o) {
return subset.contains(o);
}
});
}
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
return filterNodes(nodes.iterateNodes(s));
}
public Iterator<IBasicBlock> iterator() {
return filterNodes(nodes.iterator());
}
public int getNumberOfNodes() {
return subset.size();
}
public void addNode(IBasicBlock n) {
throw new UnsupportedOperationException();
}
public void removeNode(IBasicBlock n) {
throw new UnsupportedOperationException();
}
public boolean containsNode(IBasicBlock N) {
return subset.contains(N);
}
}
private final ControlFlowGraph cfg;
private final FilteredNodes nodes;
private final FilteredCFGEdges edges;
public PrunedCFG(final ControlFlowGraph cfg, final EdgeFilter filter) {
this.cfg = cfg;
Graph<IBasicBlock> temp = new AbstractNumberedGraph<IBasicBlock>() {
private final EdgeManager<IBasicBlock> edges = new FilteredCFGEdges(cfg, cfg, filter);
protected NodeManager<IBasicBlock> getNodeManager() {
return cfg;
}
protected EdgeManager<IBasicBlock> getEdgeManager() {
return edges;
}
};
Set<IBasicBlock> reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
Set<IBasicBlock> back = DFS.getReachableNodes(GraphInverter.invert(temp), Collections.singleton(cfg.exit()));
reachable.retainAll(back);
this.nodes = new FilteredNodes(cfg, reachable);
this.edges = new FilteredCFGEdges(cfg, nodes, filter);
}
protected NodeManager<IBasicBlock> getNodeManager() {
return nodes;
}
protected EdgeManager<IBasicBlock> getEdgeManager() {
return edges;
}
public Collection<IBasicBlock> getExceptionalSuccessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getExceptionalSuccessors(N));
}
public Collection<IBasicBlock> getNormalSuccessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getNormalSuccessors(N));
}
public Collection<IBasicBlock> getExceptionalPredecessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getExceptionalPredecessors(N));
}
public Collection<IBasicBlock> getNormalPredecessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getNormalPredecessors(N));
}
public IBasicBlock entry() {
return cfg.entry();
}
public IBasicBlock exit() {
return cfg.exit();
}
public IBasicBlock getBlockForInstruction(int index) {
return cfg.getBlockForInstruction(index);
}
public IInstruction[] getInstructions() {
return cfg.getInstructions();
}
public int getProgramCounter(int index) {
return cfg.getProgramCounter(index);
}
public IMethod getMethod() {
return cfg.getMethod();
}
public BitVector getCatchBlocks() {
BitVector result = new BitVector();
BitVector blocks = cfg.getCatchBlocks();
int i = 0;
while ((i = blocks.nextSetBit(i)) != -1) {
if (nodes.containsNode(getNode(i))) {
result.set(i);
}
}
return result;
}
}