generics for control flow graph and filters

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1712 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2007-09-02 14:45:41 +00:00
parent cd78f3aa71
commit 182a53ee8f
49 changed files with 684 additions and 672 deletions

View File

@ -33,6 +33,7 @@ import com.ibm.wala.ipa.summaries.SyntheticIR;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
@ -268,7 +269,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
return CodeScanner.iterateCastTypes(statements);
}
public ControlFlowGraph getCFG(CGNode N) {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
return getIR(N).getControlFlowGraph();
}

View File

@ -49,6 +49,7 @@ import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
@ -710,7 +711,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
/*
* @see com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getCFG(com.ibm.wala.ipa.callgraph.CGNode)
*/
public ControlFlowGraph getCFG(CGNode N) {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
return getIR(N).getControlFlowGraph();
}

View File

@ -12,7 +12,6 @@ package com.ibm.wala.analysis.stackMachine;
import java.util.Iterator;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.cfg.ShrikeCFG;
import com.ibm.wala.cfg.ShrikeCFG.BasicBlock;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
@ -120,7 +119,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
protected void init(Meeter meeter, final FlowProvider flow) {
final MeetOperator meet = new MeetOperator(meeter);
ITransferFunctionProvider<IBasicBlock, MachineState> xferFunctions = new ITransferFunctionProvider<IBasicBlock, MachineState>() {
ITransferFunctionProvider<BasicBlock, MachineState> xferFunctions = new ITransferFunctionProvider<BasicBlock, MachineState>() {
public boolean hasNodeTransferFunctions() {
return flow.needsNodeFlow();
}
@ -129,7 +128,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
return flow.needsEdgeFlow();
}
public UnaryOperator<MachineState> getNodeTransferFunction(final IBasicBlock node) {
public UnaryOperator<MachineState> getNodeTransferFunction(final BasicBlock node) {
return new UnaryOperator<MachineState>() {
@Override
public byte evaluate(MachineState lhs, MachineState rhs) {
@ -137,7 +136,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
MachineState exit = lhs;
MachineState entry = rhs;
MachineState newExit = flow.flow(entry, (BasicBlock) node);
MachineState newExit = flow.flow(entry, node);
if (newExit.stateEquals(exit)) {
return NOT_CHANGED;
} else {
@ -163,7 +162,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
};
}
public UnaryOperator<MachineState> getEdgeTransferFunction(final IBasicBlock from, final IBasicBlock to) {
public UnaryOperator<MachineState> getEdgeTransferFunction(final BasicBlock from, final BasicBlock to) {
return new UnaryOperator<MachineState>() {
@Override
public byte evaluate(MachineState lhs, MachineState rhs) {
@ -171,7 +170,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
MachineState exit = lhs;
MachineState entry = rhs;
MachineState newExit = flow.flow(entry, (BasicBlock) from, (BasicBlock) to);
MachineState newExit = flow.flow(entry, from, to);
if (newExit.stateEquals(exit)) {
return NOT_CHANGED;
} else {
@ -202,16 +201,16 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
}
};
IKilldallFramework<IBasicBlock, MachineState> problem = new BasicFramework<IBasicBlock, MachineState>(cfg, xferFunctions);
solver = new DataflowSolver<IBasicBlock, MachineState>(problem) {
IKilldallFramework<BasicBlock, MachineState> problem = new BasicFramework<BasicBlock, MachineState>(cfg, xferFunctions);
solver = new DataflowSolver<BasicBlock, MachineState>(problem) {
private MachineState entry;
@Override
protected MachineState makeNodeVariable(IBasicBlock n, boolean IN) {
protected MachineState makeNodeVariable(BasicBlock n, boolean IN) {
if (Assertions.verifyAssertions) {
Assertions._assert(n != null);
}
MachineState result = new MachineState(71167 * n.hashCode() + (IN ? 0 : 1), (BasicBlock) n);
MachineState result = new MachineState(71167 * n.hashCode() + (IN ? 0 : 1), n);
if (IN && n.equals(cfg.entry())) {
entry = result;
}
@ -219,12 +218,12 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
}
@Override
protected MachineState makeEdgeVariable(IBasicBlock from, IBasicBlock to) {
protected MachineState makeEdgeVariable(BasicBlock from, BasicBlock to) {
if (Assertions.verifyAssertions) {
Assertions._assert(from != null);
Assertions._assert(to != null);
}
MachineState result = new MachineState(71167 * (from.hashCode() + to.hashCode()), (BasicBlock) from);
MachineState result = new MachineState(71167 * (from.hashCode() + to.hashCode()), from);
return result;
}

View File

@ -42,7 +42,7 @@ import com.ibm.wala.util.intset.MutableSparseIntSet;
*
* @author sfink
*/
public abstract class AbstractCFG implements ControlFlowGraph, Constants {
public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowGraph<T>, Constants {
/**
* The method this AbstractCFG represents
@ -52,18 +52,18 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/**
* An object to track nodes in this cfg
*/
final private DelegatingNumberedNodeManager<IBasicBlock> nodeManager = new DelegatingNumberedNodeManager<IBasicBlock>();
final private DelegatingNumberedNodeManager<T> nodeManager = new DelegatingNumberedNodeManager<T>();
/**
* An object to track most normal edges in this cfg
*/
final private SparseNumberedEdgeManager<IBasicBlock> normalEdgeManager = new SparseNumberedEdgeManager<IBasicBlock>(nodeManager, 2,
final private SparseNumberedEdgeManager<T> normalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager, 2,
BasicNaturalRelation.SIMPLE);
/**
* An object to track not-to-exit exceptional edges in this cfg
*/
final private SparseNumberedEdgeManager<IBasicBlock> exceptionalEdgeManager = new SparseNumberedEdgeManager<IBasicBlock>(nodeManager,
final private SparseNumberedEdgeManager<T> exceptionalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager,
0, BasicNaturalRelation.SIMPLE);
/**
@ -89,7 +89,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/**
* Cache here for efficiency
*/
private IBasicBlock exit;
private T exit;
/**
* @param method
@ -121,7 +121,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
*
* @return the entry basic block for the CFG.
*/
public IBasicBlock entry() {
public T entry() {
return getNode(0);
}
@ -130,11 +130,11 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
*
* @return the exit basic block for the CFG.
*/
public IBasicBlock exit() {
public T exit() {
return exit;
}
public int getPredNodeCount(IBasicBlock N) {
public int getPredNodeCount(T N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -157,7 +157,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
public int getNumberOfNormalIn(IBasicBlock N) {
public int getNumberOfNormalIn(T N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -174,7 +174,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return normalEdgeManager.getPredNodeCount(N) + xtra;
}
public int getNumberOfExceptionalIn(IBasicBlock N) {
public int getNumberOfExceptionalIn(T N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -219,22 +219,22 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return exceptionalEdgeManager.getSuccNodeCount(number) + xtra;
}
public int getNumberOfNormalOut(IBasicBlock N) {
public int getNumberOfNormalOut(T N) {
return getNumberOfNormalOut(getNumber(N));
}
public int getNumberOfExceptionalOut(final IBasicBlock N) {
public int getNumberOfExceptionalOut(final T N) {
return getNumberOfExceptionalOut(getNumber(N));
}
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
public Iterator<T> getPredNodes(T N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
if (N.equals(exit())) {
return new FilterIterator<IBasicBlock>(iterator(), new Filter() {
public boolean accepts(Object o) {
int i = getNumber((IBasicBlock) o);
return new FilterIterator<T>(iterator(), new Filter<T>() {
public boolean accepts(T o) {
int i = getNumber(o);
return normalToExit.get(i) || exceptionalToExit.get(i);
}
});
@ -244,7 +244,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
boolean exceptionalIn = getNumberOfExceptionalIn(N) > 0;
if (normalIn) {
if (exceptionalIn) {
HashSet<IBasicBlock> result = HashSetFactory.make(getNumberOfNormalIn(N) + getNumberOfExceptionalIn(N));
HashSet<T> result = HashSetFactory.make(getNumberOfNormalIn(N) + getNumberOfExceptionalIn(N));
result.addAll(Iterator2Collection.toCollection(normalEdgeManager.getPredNodes(N)));
result.addAll(Iterator2Collection.toCollection(exceptionalEdgeManager.getPredNodes(N)));
if (fallThru.get(number - 1)) {
@ -269,7 +269,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
public int getSuccNodeCount(IBasicBlock N) {
public int getSuccNodeCount(T N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -303,20 +303,20 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
private int slowCountSuccNodes(IBasicBlock N) {
private int slowCountSuccNodes(T N) {
return Iterator2Collection.toCollection(getSuccNodes(N)).size();
}
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
public Iterator<T> getSuccNodes(T N) {
int number = getNumber(N);
if (normalToExit.get(number) && exceptionalToExit.get(number)) {
return new CompoundIterator<IBasicBlock>(iterateNormalSuccessorsWithoutExit(number), iterateExceptionalSuccessors(number));
return new CompoundIterator<T>(iterateNormalSuccessorsWithoutExit(number), iterateExceptionalSuccessors(number));
} else {
return new CompoundIterator<IBasicBlock>(iterateNormalSuccessors(number), iterateExceptionalSuccessors(number));
return new CompoundIterator<T>(iterateNormalSuccessors(number), iterateExceptionalSuccessors(number));
}
}
private Iterator<IBasicBlock> iterateExceptionalSuccessors(int number) {
private Iterator<T> iterateExceptionalSuccessors(int number) {
if (exceptionalEdgeManager.hasAnySuccessor(number)) {
if (exceptionalToExit.get(number)) {
return IteratorPlusOne.make(exceptionalEdgeManager.getSuccNodes(number), exit());
@ -325,18 +325,18 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
} else {
if (exceptionalToExit.get(number)) {
return new NonNullSingletonIterator<IBasicBlock>(exit());
return new NonNullSingletonIterator<T>(exit());
} else {
return EmptyIterator.instance();
}
}
}
Iterator<IBasicBlock> iterateExceptionalPredecessors(IBasicBlock N) {
Iterator<T> iterateExceptionalPredecessors(T N) {
if (N.equals(exit())) {
return new FilterIterator<IBasicBlock>(iterator(), new Filter() {
public boolean accepts(Object o) {
int i = getNumber((IBasicBlock) o);
return new FilterIterator<T>(iterator(), new Filter<T>() {
public boolean accepts(T o) {
int i = getNumber(o);
return exceptionalToExit.get(i);
}
});
@ -345,11 +345,11 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
Iterator<IBasicBlock> iterateNormalPredecessors(IBasicBlock N) {
Iterator<T> iterateNormalPredecessors(T N) {
if (N.equals(exit())) {
return new FilterIterator<IBasicBlock>(iterator(), new Filter() {
public boolean accepts(Object o) {
int i = getNumber((IBasicBlock) o);
return new FilterIterator<T>(iterator(), new Filter<T>() {
public boolean accepts(T o) {
int i = getNumber(o);
return normalToExit.get(i);
}
});
@ -363,10 +363,10 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
private Iterator<IBasicBlock> iterateNormalSuccessors(int number) {
private Iterator<T> iterateNormalSuccessors(int number) {
if (fallThru.get(number)) {
if (normalToExit.get(number)) {
return new IteratorPlusTwo<IBasicBlock>(normalEdgeManager.getSuccNodes(number), getNode(number + 1), exit());
return new IteratorPlusTwo<T>(normalEdgeManager.getSuccNodes(number), getNode(number + 1), exit());
} else {
return IteratorPlusOne.make(normalEdgeManager.getSuccNodes(number), getNode(number + 1));
}
@ -379,7 +379,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
}
private Iterator<IBasicBlock> iterateNormalSuccessorsWithoutExit(int number) {
private Iterator<T> iterateNormalSuccessorsWithoutExit(int number) {
if (fallThru.get(number)) {
return IteratorPlusOne.make(normalEdgeManager.getSuccNodes(number), getNode(number + 1));
} else {
@ -390,7 +390,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/**
* @param n
*/
public void addNode(IBasicBlock n) {
public void addNode(T n) {
nodeManager.addNode(n);
}
@ -398,11 +398,11 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return nodeManager.getMaxNumber();
}
public IBasicBlock getNode(int number) {
public T getNode(int number) {
return nodeManager.getNode(number);
}
public int getNumber(IBasicBlock N) {
public int getNumber(T N) {
return nodeManager.getNumber(N);
}
@ -410,19 +410,19 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return nodeManager.getNumberOfNodes();
}
public Iterator<IBasicBlock> iterator() {
public Iterator<T> iterator() {
return nodeManager.iterator();
}
public void addEdge(IBasicBlock src, IBasicBlock dst) throws UnimplementedError {
public void addEdge(T src, T dst) throws UnimplementedError {
Assertions.UNREACHABLE("Don't call me .. use addNormalEdge or addExceptionalEdge");
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void removeEdge(T src, T dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasEdge(T src, T dst) {
if (dst == null) {
throw new IllegalArgumentException("dst is null");
}
@ -435,7 +435,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return normalEdgeManager.hasEdge(src, dst) || exceptionalEdgeManager.hasEdge(src, dst);
}
public boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasExceptionalEdge(T src, T dst) {
if (dst == null) {
throw new IllegalArgumentException("dst is null");
}
@ -446,7 +446,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
return exceptionalEdgeManager.hasEdge(src, dst);
}
public boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasNormalEdge(T src, T dst) {
if (dst == null) {
throw new IllegalArgumentException("dst is null");
}
@ -465,7 +465,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
* @throws IllegalArgumentException
* if dst is null
*/
public void addNormalEdge(IBasicBlock src, IBasicBlock dst) {
public void addNormalEdge(T src, T dst) {
if (dst == null) {
throw new IllegalArgumentException("dst is null");
}
@ -484,7 +484,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
* @throws IllegalArgumentException
* if dst is null
*/
public void addExceptionalEdge(IBasicBlock src, IBasicBlock dst) {
public void addExceptionalEdge(T src, T dst) {
if (dst == null) {
throw new IllegalArgumentException("dst is null");
}
@ -498,21 +498,21 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/*
* @see com.ibm.wala.util.graph.Graph#removeNode(com.ibm.wala.util.graph.Node)
*/
public void removeNodeAndEdges(IBasicBlock N) throws UnimplementedError {
public void removeNodeAndEdges(T N) throws UnimplementedError {
Assertions.UNREACHABLE();
}
/*
* @see com.ibm.wala.util.graph.NodeManager#remove(com.ibm.wala.util.graph.Node)
*/
public void removeNode(IBasicBlock n) throws UnimplementedError {
public void removeNode(T n) throws UnimplementedError {
Assertions.UNREACHABLE();
}
/*
* @see com.ibm.wala.util.graph.NodeManager#containsNode(com.ibm.wala.util.graph.Node)
*/
public boolean containsNode(IBasicBlock N) {
public boolean containsNode(T N) {
return nodeManager.containsNode(N);
}
@ -522,11 +522,11 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
@Override
public String toString() {
StringBuffer s = new StringBuffer("");
for (Iterator it = iterator(); it.hasNext();) {
IBasicBlock bb = (IBasicBlock) it.next();
for (Iterator<T> it = iterator(); it.hasNext();) {
T bb = it.next();
s.append("BB").append(getNumber(bb)).append("\n");
Iterator<IBasicBlock> succNodes = getSuccNodes(bb);
Iterator<T> succNodes = getSuccNodes(bb);
while (succNodes.hasNext()) {
s.append(" -> BB").append(getNumber(succNodes.next())).append("\n");
}
@ -567,14 +567,14 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/*
* @see com.ibm.wala.util.graph.EdgeManager#removeEdges(java.lang.Object)
*/
public void removeAllIncidentEdges(IBasicBlock node) throws UnimplementedError {
public void removeAllIncidentEdges(T node) throws UnimplementedError {
Assertions.UNREACHABLE();
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.T)
*/
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
public Collection<T> getExceptionalSuccessors(T b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
@ -582,9 +582,9 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.T)
*/
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
public Collection<T> getNormalSuccessors(T b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
@ -594,15 +594,15 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/*
* @see com.ibm.wala.util.graph.NumberedNodeManager#iterateNodes(com.ibm.wala.util.intset.IntSet)
*/
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
return new NumberedNodeIterator<IBasicBlock>(s, this);
public Iterator<T> iterateNodes(IntSet s) {
return new NumberedNodeIterator<T>(s, this);
}
public void removeIncomingEdges(IBasicBlock node) throws UnimplementedError {
public void removeIncomingEdges(T node) throws UnimplementedError {
Assertions.UNREACHABLE();
}
public void removeOutgoingEdges(IBasicBlock node) throws UnimplementedError {
public void removeOutgoingEdges(T node) throws UnimplementedError {
Assertions.UNREACHABLE();
}
@ -615,9 +615,9 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalPredecessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalPredecessors(com.ibm.wala.cfg.T)
*/
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
public Collection<T> getExceptionalPredecessors(T b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
@ -625,16 +625,16 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalPredecessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalPredecessors(com.ibm.wala.cfg.T)
*/
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
public Collection<T> getNormalPredecessors(T b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
return Iterator2Collection.toCollection(iterateNormalPredecessors(b));
}
public IntSet getPredNodeNumbers(IBasicBlock node) throws UnimplementedError {
public IntSet getPredNodeNumbers(T node) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
@ -642,7 +642,7 @@ public abstract class AbstractCFG implements ControlFlowGraph, Constants {
/*
* TODO: optimize this.
*/
public IntSet getSuccNodeNumbers(IBasicBlock node) {
public IntSet getSuccNodeNumbers(T node) {
int number = getNumber(node);
IntSet s = normalEdgeManager.getSuccNodeNumbers(node);
MutableSparseIntSet result = s == null ? new MutableSparseIntSet() : MutableSparseIntSet.make(s);

View File

@ -17,6 +17,7 @@ import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSACFG;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
@ -39,37 +40,37 @@ public class CFGSanitizer {
/*
*/
public static Graph<IBasicBlock> sanitize(IR ir, IClassHierarchy cha) throws IllegalArgumentException, WalaException {
public static Graph<ISSABasicBlock> sanitize(IR ir, IClassHierarchy cha) throws IllegalArgumentException, WalaException {
if (ir == null) {
throw new IllegalArgumentException("ir cannot be null");
}
ControlFlowGraph cfg = ir.getControlFlowGraph();
Graph<IBasicBlock> G = new SlowSparseNumberedGraph<IBasicBlock>();
ControlFlowGraph<ISSABasicBlock> cfg = ir.getControlFlowGraph();
Graph<ISSABasicBlock> g = new SlowSparseNumberedGraph<ISSABasicBlock>();
// add all nodes to the graph
for (Iterator<? extends IBasicBlock> it = cfg.iterator(); it.hasNext();) {
G.addNode(it.next());
for (Iterator<? extends ISSABasicBlock> it = cfg.iterator(); it.hasNext();) {
g.addNode(it.next());
}
// add all edges to the graph, except those that go to exit
for (Iterator it = cfg.iterator(); it.hasNext();) {
IBasicBlock b = (IBasicBlock) it.next();
ISSABasicBlock b = (ISSABasicBlock) it.next();
for (Iterator it2 = cfg.getSuccNodes(b); it2.hasNext();) {
IBasicBlock b2 = (IBasicBlock) it2.next();
ISSABasicBlock b2 = (ISSABasicBlock) it2.next();
if (!b2.isExitBlock()) {
G.addEdge(b, b2);
g.addEdge(b, b2);
}
}
}
// now add edges to exit, ignoring undeclared exceptions
IBasicBlock exit = cfg.exit();
ISSABasicBlock exit = cfg.exit();
for (Iterator it = cfg.getPredNodes(exit); it.hasNext();) {
// for each predecessor of exit ...
IBasicBlock b = (IBasicBlock) it.next();
ISSABasicBlock b = (ISSABasicBlock) it.next();
SSAInstruction s = ir.getInstructions()[b.getLastInstructionIndex()];
if (s == null) {
@ -78,7 +79,7 @@ public class CFGSanitizer {
}
if (s instanceof SSAReturnInstruction || s instanceof SSAThrowInstruction) {
// return or athrow: add edge to exit
G.addEdge(b, exit);
g.addEdge(b, exit);
} else {
// compute types of exceptions the pei may throw
TypeReference[] exceptions = null;
@ -143,14 +144,14 @@ public class CFGSanitizer {
}
if (isDeclared) {
// found a declared exceptional edge
G.addEdge(b, exit);
g.addEdge(b, exit);
}
}
}
}
}
}
return G;
return g;
}
private static TypeReference[] computeExceptions(IClassHierarchy cha, SSAInstruction s) throws InvalidClassFileException {

View File

@ -23,17 +23,17 @@ import com.ibm.wala.util.intset.BitVector;
* @author cahoon
* @author sfink
*/
public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
public interface ControlFlowGraph<T extends IBasicBlock> extends NumberedGraph<T> {
/**
* Return the entry basic block in the CFG
*/
public IBasicBlock entry();
public T entry();
/**
* @return the synthetic exit block for the cfg
*/
public IBasicBlock exit();
public T exit();
/**
* @return the indices of the catch blocks, as a bit vector
@ -45,7 +45,7 @@ public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
* an instruction index
* @return the basic block which contains this instruction.
*/
public IBasicBlock getBlockForInstruction(int index);
public T getBlockForInstruction(int index);
/**
* @return the instructions of this CFG, as an array.
@ -72,7 +72,7 @@ public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
* @return the basic blocks which may be reached from b via exceptional
* control flow
*/
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b);
public Collection<T> getExceptionalSuccessors(T b);
/**
* The order of blocks returned should be arbitrary but deterministic.
@ -80,7 +80,7 @@ public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
* @return the basic blocks which may be reached from b via normal control
* flow
*/
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b);
public Collection<T> getNormalSuccessors(T b);
/**
* The order of blocks returned should be arbitrary but deterministic.
@ -89,7 +89,7 @@ public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
* @return the basic blocks from which b may be reached via exceptional
* control flow
*/
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b);
public Collection<T> getExceptionalPredecessors(T b);
/**
* The order of blocks returned should be arbitrary but deterministic.
@ -98,5 +98,5 @@ public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
* @return the basic blocks from which b may be reached via normal
* control flow
*/
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b);
public Collection<T> getNormalPredecessors(T b);
}

View File

@ -45,7 +45,7 @@ import com.ibm.wala.util.graph.impl.NodeWithNumber;
* This is a funny CFG ... we assume that there are always fallthru edges, even
* from throws and returns.
*/
public class InducedCFG extends AbstractCFG {
public class InducedCFG extends AbstractCFG<InducedCFG.BasicBlock> {
private static final boolean DEBUG = false;
/**
@ -64,7 +64,6 @@ public class InducedCFG extends AbstractCFG {
* @throws IllegalArgumentException if instructions is null
*/
public InducedCFG(SSAInstruction[] instructions, IMethod method, Context context) {
super(method);
if (instructions == null) {
throw new IllegalArgumentException("instructions is null");
@ -306,7 +305,7 @@ public class InducedCFG extends AbstractCFG {
}
}
public IBasicBlock getBlockForInstruction(int index) {
public BasicBlock getBlockForInstruction(int index) {
if (i2block[index] == null) {
Assertions.productionAssertion(false, "unexpected null for " + index);
}
@ -348,7 +347,7 @@ public class InducedCFG extends AbstractCFG {
if (last.isPEI()) {
// we don't currently model catch blocks here ... instead just link
// to the exit block
addExceptionalEdgeTo((BasicBlock) exit());
addExceptionalEdgeTo(exit());
}
}
@ -386,11 +385,11 @@ public class InducedCFG extends AbstractCFG {
if (DEBUG) {
Trace.println("Add fallthru to " + getNode(getGraphNodeId() + 1));
}
addNormalEdgeTo((BasicBlock) getNode(getGraphNodeId() + 1));
addNormalEdgeTo(getNode(getGraphNodeId() + 1));
}
if (last instanceof SSAReturnInstruction) {
// link each return instrution to the exit block.
BasicBlock exit = (BasicBlock) exit();
BasicBlock exit = exit();
addNormalEdgeTo(exit);
}
}
@ -414,7 +413,7 @@ public class InducedCFG extends AbstractCFG {
// this is the last non-exit block
return getInstructions().length - 1;
} else {
BasicBlock next = (BasicBlock) getNode(getGraphNodeId() + 1);
BasicBlock next = getNode(getGraphNodeId() + 1);
return next.getFirstInstructionIndex() - 1;
}
}
@ -491,7 +490,7 @@ public class InducedCFG extends AbstractCFG {
s.append(" ").append(j).append(" ").append(getInstructions()[j]).append("\n");
}
Iterator<IBasicBlock> succNodes = getSuccNodes(bb);
Iterator<BasicBlock> succNodes = getSuccNodes(bb);
while (succNodes.hasNext()) {
s.append(" -> BB").append(getNumber(succNodes.next())).append("\n");
}

View File

@ -37,13 +37,12 @@ import com.ibm.wala.util.warnings.Warning;
import com.ibm.wala.util.warnings.Warnings;
/**
*
* A graph of basic blocks.
*
* @author sfink
* @author roca
*/
public class ShrikeCFG extends AbstractCFG {
public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
private static final boolean DEBUG = false;
@ -208,7 +207,7 @@ public class ShrikeCFG extends AbstractCFG {
* Return an instruction's basic block in the CFG given the index of the
* instruction in the CFG's instruction array.
*/
public IBasicBlock getBlockForInstruction(int index) {
public BasicBlock getBlockForInstruction(int index) {
return getNode(instruction2Block[index]);
}
@ -238,17 +237,17 @@ public class ShrikeCFG extends AbstractCFG {
Instruction last = (Instruction) getInstructions()[getLastInstructionIndex()];
int[] targets = last.getBranchTargets();
for (int i = 0; i < targets.length; i++) {
BasicBlock b = (BasicBlock) getBlockForInstruction(targets[i]);
BasicBlock b = getBlockForInstruction(targets[i]);
addNormalEdgeTo(b);
}
addExceptionalEdges(last);
if (last.isFallThrough()) {
BasicBlock next = (BasicBlock) getNode(getNumber() + 1);
BasicBlock next = getNode(getNumber() + 1);
addNormalEdgeTo(next);
}
if (last instanceof ReturnInstruction) {
// link each return instruction to the exit block.
BasicBlock exit = (BasicBlock) exit();
BasicBlock exit = exit();
addNormalEdgeTo(exit);
}
}
@ -295,7 +294,7 @@ public class ShrikeCFG extends AbstractCFG {
if (DEBUG) {
Trace.println(" handler " + hs[j]);
}
BasicBlock b = (BasicBlock) getBlockForInstruction(hs[j].getHandler());
BasicBlock b = getBlockForInstruction(hs[j].getHandler());
if (DEBUG) {
Trace.println(" target " + b);
}
@ -354,12 +353,12 @@ public class ShrikeCFG extends AbstractCFG {
}
// if needed, add an edge to the exit block.
if (exceptionTypes == null || !exceptionTypes.isEmpty()) {
BasicBlock exit = (BasicBlock) exit();
BasicBlock exit = exit();
addExceptionalEdgeTo(exit);
}
} else {
// found no handler for this PEI ... link to the exit block.
BasicBlock exit = (BasicBlock) exit();
BasicBlock exit = exit();
addExceptionalEdgeTo(exit);
}
}
@ -418,7 +417,7 @@ public class ShrikeCFG extends AbstractCFG {
// this is the last non-exit block
return getInstructions().length - 1;
} else {
BasicBlock next = (BasicBlock) getNode(getNumber() + 1);
BasicBlock next = getNode(getNumber() + 1);
return next.getFirstInstructionIndex() - 1;
}
}
@ -439,21 +438,21 @@ public class ShrikeCFG extends AbstractCFG {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#isExitBlock()
* @see com.ibm.wala.cfg.BasicBlock#isExitBlock()
*/
public boolean isExitBlock() {
return this == ShrikeCFG.this.exit();
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#isEntryBlock()
* @see com.ibm.wala.cfg.BasicBlock#isEntryBlock()
*/
public boolean isEntryBlock() {
return this == ShrikeCFG.this.entry();
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getMethod()
* @see com.ibm.wala.cfg.BasicBlock#getMethod()
*/
public IMethod getMethod() {
return ShrikeCFG.this.getMethod();
@ -471,7 +470,7 @@ public class ShrikeCFG extends AbstractCFG {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getNumber()
* @see com.ibm.wala.cfg.BasicBlock#getNumber()
*/
public int getNumber() {
return getGraphNodeId();
@ -495,7 +494,7 @@ public class ShrikeCFG extends AbstractCFG {
s.append(" ").append(j).append(" ").append(getInstructions()[j]).append("\n");
}
Iterator<IBasicBlock> succNodes = getSuccNodes(bb);
Iterator<BasicBlock> succNodes = getSuccNodes(bb);
while (succNodes.hasNext()) {
s.append(" -> BB").append(getNumber(succNodes.next())).append("\n");
}

View File

@ -40,7 +40,7 @@ import com.ibm.wala.util.intset.IntSet;
*
* @author sfink
*/
public class TwoExitCFG implements ControlFlowGraph {
public class TwoExitCFG implements ControlFlowGraph<ISSABasicBlock> {
/**
* DEBUG_LEVEL: 0 No output 1 Print some simple stats and warning information
@ -51,12 +51,12 @@ public class TwoExitCFG implements ControlFlowGraph {
/**
* A "normal" cfg with one exit node
*/
private final ControlFlowGraph delegate;
private final ControlFlowGraph<ISSABasicBlock> delegate;
/**
* A distinguished basic block representing the exceptional exit.
*/
private final IBasicBlock exceptionalExit = new ExceptionalExitBlock();
private final ISSABasicBlock exceptionalExit = new ExceptionalExitBlock();
/**
* Numbers of the "normal" predecessors of the delegate's exit() node
@ -83,7 +83,7 @@ public class TwoExitCFG implements ControlFlowGraph {
* A "normal" cfg with one exit node
* @throws IllegalArgumentException if delegate is null
*/
public TwoExitCFG(ControlFlowGraph delegate) {
public TwoExitCFG(ControlFlowGraph<ISSABasicBlock> delegate) {
if (delegate == null) {
throw new IllegalArgumentException("delegate is null");
}
@ -96,7 +96,7 @@ public class TwoExitCFG implements ControlFlowGraph {
private void ensureEdgesReady() {
if (!edgesAreComputed) {
computeEdges(delegate);
computeEdges();
edgesAreComputed = true;
}
}
@ -104,7 +104,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/**
* @param delegate
*/
private void computeEdges(ControlFlowGraph delegate) {
private void computeEdges() {
normalPred = (delegate instanceof AbstractCFG) ? ((AbstractCFG) delegate).getNormalToExit() : new FixedSizeBitVector(delegate
.getMaxNumber() + 1);
exceptionalPred = (delegate instanceof AbstractCFG) ? ((AbstractCFG) delegate).getExceptionalToExit() : new FixedSizeBitVector(
@ -112,7 +112,7 @@ public class TwoExitCFG implements ControlFlowGraph {
if (!(delegate instanceof AbstractCFG)) {
IInstruction[] instructions = delegate.getInstructions();
for (Iterator it = delegate.getPredNodes(delegate.exit()); it.hasNext();) {
IBasicBlock b = (IBasicBlock) it.next();
ISSABasicBlock b = (ISSABasicBlock) it.next();
if (b.getLastInstructionIndex() >= 0) {
IInstruction last = instructions[b.getLastInstructionIndex()];
if (last != null && last.isPEI()) {
@ -133,11 +133,11 @@ public class TwoExitCFG implements ControlFlowGraph {
}
}
public IBasicBlock entry() {
public ISSABasicBlock entry() {
return delegate.entry();
}
public IBasicBlock exit() throws UnsupportedOperationException {
public ISSABasicBlock exit() throws UnsupportedOperationException {
throw new UnsupportedOperationException("don't call this");
}
@ -145,7 +145,7 @@ public class TwoExitCFG implements ControlFlowGraph {
return delegate.getCatchBlocks();
}
public IBasicBlock getBlockForInstruction(int index) {
public ISSABasicBlock getBlockForInstruction(int index) {
return delegate.getBlockForInstruction(index);
}
@ -160,11 +160,11 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#removeNodeAndEdges(java.lang.Object)
*/
public void removeNodeAndEdges(IBasicBlock N) throws UnsupportedOperationException {
public void removeNodeAndEdges(ISSABasicBlock N) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public int getNumber(IBasicBlock N) {
public int getNumber(ISSABasicBlock N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -178,7 +178,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedNodeManager#getNode(int)
*/
public IBasicBlock getNode(int number) {
public ISSABasicBlock getNode(int number) {
return (number == getMaxNumber()) ? exceptionalExit : delegate.getNode(number);
}
@ -192,7 +192,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NodeManager#iterateNodes()
*/
public Iterator<IBasicBlock> iterator() {
public Iterator<ISSABasicBlock> iterator() {
return IteratorPlusOne.make(delegate.iterator(), exceptionalExit);
}
@ -206,28 +206,28 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NodeManager#addNode(java.lang.Object)
*/
public void addNode(IBasicBlock n) throws UnsupportedOperationException {
public void addNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* @see com.ibm.wala.util.graph.NodeManager#removeNode(java.lang.Object)
*/
public void removeNode(IBasicBlock n) throws UnsupportedOperationException {
public void removeNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* @see com.ibm.wala.util.graph.NodeManager#containsNode(java.lang.Object)
*/
public boolean containsNode(IBasicBlock N) {
public boolean containsNode(ISSABasicBlock N) {
return delegate.containsNode(N) || N.equals(exceptionalExit);
}
/*
* @see com.ibm.wala.util.graph.EdgeManager#getPredNodes(java.lang.Object)
*/
public Iterator<? extends IBasicBlock> getPredNodes(IBasicBlock N) {
public Iterator<? extends ISSABasicBlock> getPredNodes(ISSABasicBlock N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -243,7 +243,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.EdgeManager#getPredNodeCount(java.lang.Object)
*/
public int getPredNodeCount(IBasicBlock N) {
public int getPredNodeCount(ISSABasicBlock N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -260,7 +260,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.EdgeManager#getSuccNodes(java.lang.Object)
*/
public Iterator<? extends IBasicBlock> getSuccNodes(IBasicBlock N) {
public Iterator<? extends ISSABasicBlock> getSuccNodes(ISSABasicBlock N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -268,7 +268,7 @@ public class TwoExitCFG implements ControlFlowGraph {
Trace.println("TwoExitCFG: getSuccNodes " + N);
}
ensureEdgesReady();
IBasicBlock bb = N;
ISSABasicBlock bb = N;
if (N.equals(exceptionalExit)) {
return EmptyIterator.instance();
} else if (exceptionalPred.get(bb.getNumber())) {
@ -285,7 +285,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.EdgeManager#getSuccNodeCount(java.lang.Object)
*/
public int getSuccNodeCount(IBasicBlock N) {
public int getSuccNodeCount(ISSABasicBlock N) {
if (N == null) {
throw new IllegalArgumentException("N is null");
}
@ -294,7 +294,7 @@ public class TwoExitCFG implements ControlFlowGraph {
} else {
ensureEdgesReady();
int result = delegate.getSuccNodeCount(N);
IBasicBlock bb = N;
ISSABasicBlock bb = N;
if (exceptionalPred.get(bb.getNumber()) && normalPred.get(bb.getNumber())) {
result++;
}
@ -306,19 +306,19 @@ public class TwoExitCFG implements ControlFlowGraph {
* @see com.ibm.wala.util.graph.EdgeManager#addEdge(java.lang.Object,
* java.lang.Object)
*/
public void addEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void addEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void removeEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public boolean hasEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeAllIncidentEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@ -332,7 +332,7 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getFirstInstructionIndex()
* @see com.ibm.wala.cfg.ISSABasicBlock#getFirstInstructionIndex()
*/
public int getFirstInstructionIndex() {
Assertions.UNREACHABLE();
@ -340,14 +340,14 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getLastInstructionIndex()
* @see com.ibm.wala.cfg.ISSABasicBlock#getLastInstructionIndex()
*/
public int getLastInstructionIndex() {
return -2;
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#isCatchBlock()
* @see com.ibm.wala.cfg.ISSABasicBlock#isCatchBlock()
*/
public boolean isCatchBlock() {
Assertions.UNREACHABLE();
@ -355,21 +355,21 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#isExitBlock()
* @see com.ibm.wala.cfg.ISSABasicBlock#isExitBlock()
*/
public boolean isExitBlock() {
return true;
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#isEntryBlock()
* @see com.ibm.wala.cfg.ISSABasicBlock#isEntryBlock()
*/
public boolean isEntryBlock() {
return false;
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getMethod()
* @see com.ibm.wala.cfg.ISSABasicBlock#getMethod()
*/
public IMethod getMethod() {
return delegate.getMethod();
@ -414,7 +414,7 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.IBasicBlock#getNumber()
* @see com.ibm.wala.cfg.ISSABasicBlock#getNumber()
*/
public int getNumber() {
return getMaxNumber();
@ -449,7 +449,7 @@ public class TwoExitCFG implements ControlFlowGraph {
/**
* An iterator that substitutes exceptionalExit for exit()
*/
private class SubstitutionIterator implements Iterator<IBasicBlock> {
private class SubstitutionIterator implements Iterator<ISSABasicBlock> {
private final Iterator it;
SubstitutionIterator(Iterator it) {
@ -464,8 +464,8 @@ public class TwoExitCFG implements ControlFlowGraph {
return it.hasNext();
}
public IBasicBlock next() {
IBasicBlock n = (IBasicBlock) it.next();
public ISSABasicBlock next() {
ISSABasicBlock n = (ISSABasicBlock) it.next();
if (n.getNumber() == delegateExitNumber) {
return exceptionalExit;
} else {
@ -475,18 +475,18 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.ISSABasicBlock)
*/
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
if (b.equals(exceptionalExit)) {
return Collections.emptySet();
} else {
HashSet<IBasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
for (Iterator<IBasicBlock> it = delegate.getExceptionalSuccessors(b).iterator(); it.hasNext(); ) {
IBasicBlock o = it.next();
HashSet<ISSABasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
for (Iterator<ISSABasicBlock> it = delegate.getExceptionalSuccessors(b).iterator(); it.hasNext(); ) {
ISSABasicBlock o = it.next();
if (o.equals(delegate.exit())) {
c.add(exceptionalExit);
} else {
@ -502,9 +502,9 @@ public class TwoExitCFG implements ControlFlowGraph {
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.IBasicBlock)
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.ISSABasicBlock)
*/
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getNormalSuccessors(ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
@ -518,14 +518,14 @@ public class TwoExitCFG implements ControlFlowGraph {
/**
* @return A distinguished basic block representing the normal exit
*/
public IBasicBlock getNormalExit() {
public ISSABasicBlock getNormalExit() {
return delegate.exit();
}
/**
* @return A distinguished basic block representing the exceptional exit
*/
public IBasicBlock getExceptionalExit() {
public ISSABasicBlock getExceptionalExit() {
return exceptionalExit;
}
@ -539,34 +539,34 @@ public class TwoExitCFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedNodeManager#iterateNodes(com.ibm.wala.util.intset.IntSet)
*/
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
return new NumberedNodeIterator<IBasicBlock>(s, this);
public Iterator<ISSABasicBlock> iterateNodes(IntSet s) {
return new NumberedNodeIterator<ISSABasicBlock>(s, this);
}
public void removeIncomingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeIncomingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeOutgoingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) throws UnimplementedError {
public Collection<ISSABasicBlock> getExceptionalPredecessors(ISSABasicBlock b) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) throws UnimplementedError {
public Collection<ISSABasicBlock> getNormalPredecessors(ISSABasicBlock b) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
public IntSet getSuccNodeNumbers(IBasicBlock node) throws UnimplementedError {
public IntSet getSuccNodeNumbers(ISSABasicBlock node) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
public IntSet getPredNodeNumbers(IBasicBlock node) throws UnimplementedError {
public IntSet getPredNodeNumbers(ISSABasicBlock node) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}

View File

@ -41,7 +41,7 @@ public class Util {
return getLastInstruction(G, b) instanceof SSASwitchInstruction;
}
public static IBasicBlock getFallThruBlock(ControlFlowGraph G, IBasicBlock b) {
public static <T extends IBasicBlock> T getFallThruBlock(ControlFlowGraph<T> G, T b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
@ -52,10 +52,10 @@ public class Util {
}
/**
* Given that b ends with a conditional branch, return the basic block to which control
* transfers if the branch is not taken.
* Given that b ends with a conditional branch, return the basic block to
* which control transfers if the branch is not taken.
*/
public static IBasicBlock getNotTakenSuccessor(ControlFlowGraph G, IBasicBlock b) {
public static <T extends IBasicBlock> T getNotTakenSuccessor(ControlFlowGraph<T> G, T b) {
if (G == null) {
throw new IllegalArgumentException("G is null");
}
@ -66,31 +66,32 @@ public class Util {
}
/**
* Given that b ends with a conditional branch, return the basic block to which control
* transfers if the branch is taken.
* Given that b ends with a conditional branch, return the basic block to
* which control transfers if the branch is taken.
*/
public static IBasicBlock getTakenSuccessor(ControlFlowGraph G, IBasicBlock b) {
public static <T extends IBasicBlock> T getTakenSuccessor(ControlFlowGraph<T> G, T b) {
if (G == null) {
throw new IllegalArgumentException("G is null");
}
if (!endsWithConditionalBranch(G, b)) {
throw new IllegalArgumentException(b.toString() + " does not end with a conditional branch");
}
IBasicBlock fs = getNotTakenSuccessor(G, b);
for (Iterator ss = G.getSuccNodes(b); ss.hasNext();) {
IBasicBlock s = (IBasicBlock) ss.next();
T fs = getNotTakenSuccessor(G, b);
for (Iterator<? extends T> ss = G.getSuccNodes(b); ss.hasNext();) {
T s = ss.next();
if (s != fs)
return s;
}
// under pathological conditions, b may have exactly one successor (in other words, the
// under pathological conditions, b may have exactly one successor (in other
// words, the
// branch is irrelevant
return fs;
}
/**
* When the tested value of the switch statement in b has value c, which
* basic block does control transfer to.
* When the tested value of the switch statement in b has value c, which basic
* block does control transfer to.
*/
public static IBasicBlock resolveSwitch(ControlFlowGraph G, IBasicBlock b, int c) {
Assertions._assert(endsWithSwitch(G, b));
@ -115,8 +116,8 @@ public class Util {
/**
* When a switch statement at the end of block b transfers control to block s,
* which case was taken?
* TODO: Is this correct? Can't we have multiple cases that apply? Check on this.
* which case was taken? TODO: Is this correct? Can't we have multiple cases
* that apply? Check on this.
*/
public static int getSwitchLabel(ControlFlowGraph G, IBasicBlock b, IBasicBlock s) {
Assertions._assert(endsWithSwitch(G, b));
@ -132,7 +133,7 @@ public class Util {
return -1;
}
public static IBasicBlock resolveBranch(ControlFlowGraph G, IBasicBlock bb, int c1, int c2) {
public static <T extends IBasicBlock> T resolveBranch(ControlFlowGraph<T> G, T bb, int c1, int c2) {
SSAConditionalBranchInstruction c = (SSAConditionalBranchInstruction) getLastInstruction(G, bb);
switch ((ConditionalBranchInstruction.Operator) c.getOperator()) {
case EQ:
@ -174,11 +175,11 @@ public class Util {
/**
* Given that a is a predecessor of b in the cfg ..
*
* When we enumerate the predecessors of b in order, which is the first index in this
* order in which a appears? Note that this order corresponds to the order of
* operands in a phi instruction.
* When we enumerate the predecessors of b in order, which is the first index
* in this order in which a appears? Note that this order corresponds to the
* order of operands in a phi instruction.
*/
public static int whichPred(ControlFlowGraph cfg, IBasicBlock a, IBasicBlock b) {
public static <T extends IBasicBlock> int whichPred(ControlFlowGraph<T> cfg, T a, T b) {
if (cfg == null) {
throw new IllegalArgumentException("cfg is null");
}

View File

@ -34,31 +34,31 @@ import com.ibm.wala.util.graph.NodeManager;
* @author Mangala Gowri Nanda
*
*/
public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
public class BVControlDependenceGraph<T extends IBasicBlock> extends AbstractNumberedGraph<T> {
/**
* Governing control flow-graph. The control dependence graph is computed from
* this cfg.
*/
private final ControlFlowGraph cfg;
private final ControlFlowGraph<T> cfg;
/**
* the EdgeManager for the CDG. It implements the edge part of the standard
* Graph abstraction, using the control-dependence egdes of the cdg.
* Graph abstraction, using the control-dependence edges of the cdg.
*/
private final EdgeManager<IBasicBlock> edgeManager;
private final EdgeManager<T> edgeManager;
private final boolean ignoreUnreachableCode;
private final HashMap<IBasicBlock, BasicBlock> bbMap = HashMapFactory.make();
private final HashMap<T, BasicBlock<T>> bbMap = HashMapFactory.make();
final private Vector<BasicBlock> seen = new Vector<BasicBlock>();
final private Vector<BasicBlock<T>> seen = new Vector<BasicBlock<T>>();
private BasicBlock entry;
private BasicBlock<T> entry;
final private Vector<BasicBlock> entryBlocks = new Vector<BasicBlock>();
final private Vector<BasicBlock<T>> entryBlocks = new Vector<BasicBlock<T>>();
private BasicBlock exitnode;
private BasicBlock<T> exitnode;
private int count = 0;
@ -77,17 +77,17 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
/**
* @param cfg
* governing control flow graph wantEdgeLabels is always true
* governing control flow graph wantEdgeLabels is always true
*/
public BVControlDependenceGraph(ControlFlowGraph cfg) {
public BVControlDependenceGraph(ControlFlowGraph<T> cfg) {
this(cfg, false);
}
/**
* @param cfg
* governing control flow graph wantEdgeLabels is always true
* governing control flow graph wantEdgeLabels is always true
*/
public BVControlDependenceGraph(ControlFlowGraph cfg, boolean ignoreUnreachableCode) {
public BVControlDependenceGraph(ControlFlowGraph<T> cfg, boolean ignoreUnreachableCode) {
this.cfg = cfg;
this.ignoreUnreachableCode = ignoreUnreachableCode;
buildParallelGraph();
@ -103,12 +103,12 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
* Return the set of edge labels for the control flow edges that cause the
* given edge in the CDG.
*/
public Set<? extends Object> getEdgeLabels(Object src, Object dst) {
BasicBlock csrc = bbMap.get(src);
public Set<T> getEdgeLabels(Object src, Object dst) {
BasicBlock<T> csrc = bbMap.get(src);
if (csrc == null) {
return Collections.emptySet();
}
BasicBlock cdst = bbMap.get(dst);
BasicBlock<T> cdst = bbMap.get(dst);
if (cdst == null) {
return Collections.emptySet();
}
@ -116,31 +116,31 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
}
@Override
public NodeManager<IBasicBlock> getNodeManager() {
public NodeManager<T> getNodeManager() {
return cfg;
}
@Override
public EdgeManager<IBasicBlock> getEdgeManager() {
public EdgeManager<T> getEdgeManager() {
return edgeManager;
}
private void buildParallelGraph() {
for (Iterator<? extends IBasicBlock> it = cfg.iterator(); it.hasNext();) {
IBasicBlock bb = it.next();
BasicBlock cdgbb = new BasicBlock(bb);
for (Iterator<? extends T> it = cfg.iterator(); it.hasNext();) {
T bb = it.next();
BasicBlock<T> cdgbb = new BasicBlock<T>(bb);
bbMap.put(bb, cdgbb);
cfgCount++;
}
Object entryBB = cfg.entry(); // original entry node
entry = new BasicBlock(null); // parallel entry BasicBlock
entry = new BasicBlock<T>(null); // parallel entry BasicBlock
exitnode = bbMap.get(cfg.exit());
entryBlocks.add(entry);
for (Iterator<? extends IBasicBlock> it = cfg.iterator(); it.hasNext();) {
IBasicBlock bb = it.next();
BasicBlock cdgbb = bbMap.get(bb);
for (Iterator<? extends T> it = cfg.iterator(); it.hasNext();) {
T bb = it.next();
BasicBlock<T> cdgbb = bbMap.get(bb);
// kludge for handling multi-entry CFGs
if (!ignoreUnreachableCode && bb != entryBB) {
@ -152,7 +152,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
// build cfg edges for the parallel graph
for (Iterator succ = cfg.getSuccNodes(bb); succ.hasNext();) {
Object sbb = succ.next();
BasicBlock cdgsbb = bbMap.get(sbb);
BasicBlock<T> cdgsbb = bbMap.get(sbb);
cfgEdge(cdgbb, cdgsbb);
}
}
@ -171,7 +171,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
// count and index the nodes
count(exitnode);
for (int i = 0; i < entryBlocks.size(); i++) {
BasicBlock en = entryBlocks.get(i);
BasicBlock<T> en = entryBlocks.get(i);
count(en);
}
@ -191,7 +191,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
// initialize the rest of the blocks
for (int i = 1; i < count; i++) {
BasicBlock bb = seen.get(i);
BasicBlock<T> bb = seen.get(i);
bb.index = i;
SetVector(i);
}
@ -214,11 +214,11 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
// to find the control dependence
for (int n = count - 1; n >= 0; n--) {
int i, j, k, tx;
BasicBlock bb = seen.get(n);
Vector succ = bb.getSuccessors();
BasicBlock<T> bb = seen.get(n);
Vector<BasicBlock<T>> succ = bb.getSuccessors();
if (succ.size() > 1) {
for (int m = 0; m < succ.size(); m++) {
BasicBlock sb = (BasicBlock) succ.get(m);
BasicBlock<T> sb = succ.get(m);
for (i = 0, k = 0; i < BitvectorSize; i++) {
// postdominates sb but does not postdominate bb
tx = bitvectors[sb.index][i] & ~bitvectors[bb.index][i];
@ -235,7 +235,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
// If bb postdominates one of its successors sb, it is control dependent
// on itself with label sb
for (int m = 0; m < succ.size(); m++) {
BasicBlock sb = (BasicBlock) succ.get(m);
BasicBlock<T> sb = succ.get(m);
if (postdominates(sb.index, bb.index)) {
cdEdge(bb, bb, sb.item);
}
@ -247,25 +247,25 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
/**
* EdgeManager
*/
private EdgeManager<IBasicBlock> constructGraphEdges() {
return new EdgeManager<IBasicBlock>() {
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
BasicBlock cbb = bbMap.get(N);
private EdgeManager<T> constructGraphEdges() {
return new EdgeManager<T>() {
public Iterator<T> getPredNodes(T N) {
BasicBlock<T> cbb = bbMap.get(N);
if (cbb == null) {
return EmptyIterator.instance();
}
return cbb.getPredNodes();
}
public int getPredNodeCount(IBasicBlock N) {
public int getPredNodeCount(T N) {
BasicBlock cbb = bbMap.get(N);
if (cbb == null)
return 0;
return cbb.getPredNodeCount();
}
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
BasicBlock cbb = bbMap.get(N);
public Iterator<T> getSuccNodes(T N) {
BasicBlock<T> cbb = bbMap.get(N);
if (cbb == null) {
return EmptyIterator.instance();
}
@ -314,10 +314,10 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for (Iterator<? extends IBasicBlock> ns = iterator(); ns.hasNext();) {
IBasicBlock n = ns.next();
for (Iterator<T> ns = iterator(); ns.hasNext();) {
T n = ns.next();
sb.append(n.toString()).append("\n");
for (Iterator<? extends IBasicBlock> ss = getSuccNodes(n); ss.hasNext();) {
for (Iterator<? extends T> ss = getSuccNodes(n); ss.hasNext();) {
Object s = ss.next();
sb.append(" --> ").append(s);
for (Iterator labels = getEdgeLabels(n, s).iterator(); labels.hasNext();)
@ -329,26 +329,26 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
return sb.toString();
}
private void count(BasicBlock bb) {
private void count(BasicBlock<T> bb) {
// postorder
if (bb.mark)
return;
bb.mark = true;
Vector succ = bb.getSuccessors();
Vector<BasicBlock<T>> succ = bb.getSuccessors();
for (int i = 0; i < succ.size(); i++) {
BasicBlock bs = (BasicBlock) succ.get(i);
BasicBlock<T> bs = succ.get(i);
count(bs);
}
seen.add(bb);
}
private void cfgEdge(BasicBlock b1, BasicBlock b2) {
private void cfgEdge(BasicBlock<T> b1, BasicBlock<T> b2) {
b2.linkPredecessor(b1);
b1.linkSuccessor(b2);
}
private void cdEdge(BasicBlock b1, BasicBlock b2, IBasicBlock label) {
private void cdEdge(BasicBlock<T> b1, BasicBlock<T> b2, T label) {
if (b1 == entry)
return;
b2.linkCDpredecessor(b1);
@ -414,25 +414,25 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
return 0xffffffff;
}
public static class BasicBlock {
public static class BasicBlock<T extends IBasicBlock> {
protected final IBasicBlock item;
protected final T item;
protected boolean mark = false;
protected int index;
final private Vector<BasicBlock> predecessors = new Vector<BasicBlock>(2);
final private Vector<BasicBlock<T>> predecessors = new Vector<BasicBlock<T>>(2);
final private Vector<BasicBlock> successors = new Vector<BasicBlock>(2);
final private Vector<BasicBlock<T>> successors = new Vector<BasicBlock<T>>(2);
final private Vector<IBasicBlock> cdPred = new Vector<IBasicBlock>(2);
final private Vector<T> cdPred = new Vector<T>(2);
final private Vector<IBasicBlock> cdSucc = new Vector<IBasicBlock>(2);
final private Vector<T> cdSucc = new Vector<T>(2);
final private HashMap<IBasicBlock, Set<IBasicBlock>> labelMap = HashMapFactory.make();
final private HashMap<T, Set<T>> labelMap = HashMapFactory.make();
private BasicBlock(IBasicBlock item) {
private BasicBlock(T item) {
this.item = item;
}
@ -441,7 +441,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
return item.toString();
}
private void linkPredecessor(BasicBlock bb) {
private void linkPredecessor(BasicBlock<T> bb) {
Assertions._assert(bb != null);
if (!predecessors.contains(bb))
@ -457,7 +457,7 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
* private Vector getPredecessors () { return predecessors; }
*/
private void linkSuccessor(BasicBlock bb) {
private void linkSuccessor(BasicBlock<T> bb) {
Assertions._assert(bb != null);
if (!successors.contains(bb))
@ -471,11 +471,11 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
* successors.get(idx); }
*/
private Vector getSuccessors() {
private Vector<BasicBlock<T>> getSuccessors() {
return successors;
}
private void linkCDpredecessor(BasicBlock bb) {
private void linkCDpredecessor(BasicBlock<T> bb) {
Assertions._assert(bb != null);
if (!cdPred.contains(bb.item))
@ -486,17 +486,17 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
return cdPred.size();
}
private Iterator<IBasicBlock> getPredNodes() {
private Iterator<T> getPredNodes() {
return cdPred.iterator();
}
private void linkCDsuccessor(BasicBlock bb, IBasicBlock label) {
private void linkCDsuccessor(BasicBlock<T> bb, T label) {
Assertions._assert(bb != null);
if (!cdSucc.contains(bb.item)) {
cdSucc.add(bb.item);
}
Set<IBasicBlock> labelSet = labelMap.get(bb.item);
Set<T> labelSet = labelMap.get(bb.item);
if (labelSet == null) {
labelSet = HashSetFactory.make(2);
labelMap.put(bb.item, labelSet);
@ -509,12 +509,12 @@ public class BVControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock>
return cdSucc.size();
}
private Iterator<IBasicBlock> getSuccNodes() {
private Iterator<T> getSuccNodes() {
return cdSucc.iterator();
}
private Set<IBasicBlock> getLabels(BasicBlock succ) {
Set<IBasicBlock> ret = labelMap.get(succ.item);
private Set<T> getLabels(BasicBlock<T> succ) {
Set<T> ret = labelMap.get(succ.item);
if (ret == null) {
return Collections.emptySet();
}

View File

@ -33,19 +33,19 @@ import com.ibm.wala.util.graph.impl.GraphInverter;
* @author Julian Dolby
*
*/
public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
public class ControlDependenceGraph<T extends IBasicBlock> extends AbstractNumberedGraph<T> {
/**
* Governing control flow-graph. The control dependence graph is computed from
* this cfg.
*/
private final ControlFlowGraph cfg;
private final ControlFlowGraph<T> cfg;
/**
* the EdgeManager for the CDG. It implements the edge part of the standard
* Graph abstraction, using the control-dependence edges of the cdg.
*/
private final EdgeManager<IBasicBlock> edgeManager;
private final EdgeManager<T> edgeManager;
/**
* If requested, this is a map from parentXchild Pairs representing edges in
@ -62,30 +62,30 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
*
* @return Map: node n -> {x : n is control-dependent on x}
*/
private Map<IBasicBlock, Set<IBasicBlock>> buildControlDependence(boolean wantEdgeLabels) {
Map<IBasicBlock, Set<IBasicBlock>> controlDependence = HashMapFactory.make(cfg.getNumberOfNodes());
private Map<T, Set<T>> buildControlDependence(boolean wantEdgeLabels) {
Map<T, Set<T>> controlDependence = HashMapFactory.make(cfg.getNumberOfNodes());
DominanceFrontiers<IBasicBlock> RDF = new DominanceFrontiers<IBasicBlock>(GraphInverter.invert(cfg), cfg.exit());
DominanceFrontiers<T> RDF = new DominanceFrontiers<T>(GraphInverter.invert(cfg), cfg.exit());
if (wantEdgeLabels) {
edgeLabels = HashMapFactory.make();
}
for (Iterator<? extends IBasicBlock> ns = cfg.iterator(); ns.hasNext();) {
HashSet<IBasicBlock> s = HashSetFactory.make(2);
for (Iterator<? extends T> ns = cfg.iterator(); ns.hasNext();) {
HashSet<T> s = HashSetFactory.make(2);
controlDependence.put(ns.next(), s);
}
for (Iterator<? extends IBasicBlock> ns = cfg.iterator(); ns.hasNext();) {
IBasicBlock y = ns.next();
for (Iterator<IBasicBlock> ns2 = RDF.getDominanceFrontier(y); ns2.hasNext();) {
IBasicBlock x = ns2.next();
for (Iterator<? extends T> ns = cfg.iterator(); ns.hasNext();) {
T y = ns.next();
for (Iterator<T> ns2 = RDF.getDominanceFrontier(y); ns2.hasNext();) {
T x = ns2.next();
controlDependence.get(x).add(y);
if (wantEdgeLabels) {
Set<Object> labels = HashSetFactory.make();
edgeLabels.put(Pair.make(x, y), labels);
for (Iterator<? extends IBasicBlock> ss = cfg.getSuccNodes(x); ss.hasNext();) {
IBasicBlock s = ss.next();
for (Iterator<? extends T> ss = cfg.getSuccNodes(x); ss.hasNext();) {
T s = ss.next();
if (RDF.isDominatedBy(s, y)) {
labels.add(s);
}
@ -102,16 +102,16 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
* control parents to control children), this method creates an EdgeManager
* that provides the edge half of the Graph abstraction.
*/
private EdgeManager<IBasicBlock> constructGraphEdges(final Map<IBasicBlock, Set<IBasicBlock>> forwardEdges) {
return new EdgeManager<IBasicBlock>() {
Map<IBasicBlock, Set<IBasicBlock>> backwardEdges = HashMapFactory.make(forwardEdges.size());
private EdgeManager<T> constructGraphEdges(final Map<T, Set<T>> forwardEdges) {
return new EdgeManager<T>() {
Map<T, Set<T>> backwardEdges = HashMapFactory.make(forwardEdges.size());
{
for (Iterator<? extends IBasicBlock> x = cfg.iterator(); x.hasNext();) {
Set<IBasicBlock> s = HashSetFactory.make();
for (Iterator<? extends T> x = cfg.iterator(); x.hasNext();) {
Set<T> s = HashSetFactory.make();
backwardEdges.put(x.next(), s);
}
for (Iterator<IBasicBlock> ps = forwardEdges.keySet().iterator(); ps.hasNext();) {
IBasicBlock p = ps.next();
for (Iterator<T> ps = forwardEdges.keySet().iterator(); ps.hasNext();) {
T p = ps.next();
for (Iterator ns = ((Set) forwardEdges.get(p)).iterator(); ns.hasNext();) {
Object n = ns.next();
backwardEdges.get(n).add(p);
@ -119,55 +119,55 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
}
}
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
public Iterator<T> getPredNodes(T N) {
if (backwardEdges.containsKey(N))
return backwardEdges.get(N).iterator();
else
return EmptyIterator.instance();
}
public int getPredNodeCount(IBasicBlock N) {
public int getPredNodeCount(T N) {
if (backwardEdges.containsKey(N))
return ((Set) backwardEdges.get(N)).size();
else
return 0;
}
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
public Iterator<T> getSuccNodes(T N) {
if (forwardEdges.containsKey(N))
return forwardEdges.get(N).iterator();
else
return EmptyIterator.instance();
}
public int getSuccNodeCount(IBasicBlock N) {
public int getSuccNodeCount(T N) {
if (forwardEdges.containsKey(N))
return ((Set) forwardEdges.get(N)).size();
else
return 0;
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasEdge(T src, T dst) {
return forwardEdges.containsKey(src) && ((Set) forwardEdges.get(src)).contains(dst);
}
public void addEdge(IBasicBlock src, IBasicBlock dst) {
public void addEdge(T src, T dst) {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) {
public void removeEdge(T src, T dst) {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(IBasicBlock node) {
public void removeAllIncidentEdges(T node) {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(IBasicBlock node) {
public void removeIncomingEdges(T node) {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) {
public void removeOutgoingEdges(T node) {
throw new UnsupportedOperationException();
}
};
@ -176,8 +176,8 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for (Iterator<? extends IBasicBlock> ns = iterator(); ns.hasNext();) {
IBasicBlock n = ns.next();
for (Iterator<? extends T> ns = iterator(); ns.hasNext();) {
T n = ns.next();
sb.append(n.toString()).append("\n");
for (Iterator ss = getSuccNodes(n); ss.hasNext();) {
Object s = ss.next();
@ -194,20 +194,20 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
/**
* @param cfg
* governing control flow graph
* governing control flow graph
* @param wantEdgeLabels
* whether to compute edge labels for CDG edges
* whether to compute edge labels for CDG edges
*/
public ControlDependenceGraph(ControlFlowGraph cfg, boolean wantEdgeLabels) {
public ControlDependenceGraph(ControlFlowGraph<T> cfg, boolean wantEdgeLabels) {
this.cfg = cfg;
this.edgeManager = constructGraphEdges(buildControlDependence(wantEdgeLabels));
}
/**
* @param cfg
* governing control flow graph
* governing control flow graph
*/
public ControlDependenceGraph(ControlFlowGraph cfg) {
public ControlDependenceGraph(ControlFlowGraph<T> cfg) {
this(cfg, false);
}
@ -225,22 +225,22 @@ public class ControlDependenceGraph extends AbstractNumberedGraph<IBasicBlock> {
}
@Override
public NodeManager<IBasicBlock> getNodeManager() {
public NodeManager<T> getNodeManager() {
return cfg;
}
@Override
public EdgeManager<IBasicBlock> getEdgeManager() {
public EdgeManager<T> getEdgeManager() {
return edgeManager;
}
public boolean controlEquivalent(IBasicBlock bb1, IBasicBlock bb2) {
public boolean controlEquivalent(T bb1, T bb2) {
if (getPredNodeCount(bb1) != getPredNodeCount(bb2)) {
return false;
}
for (Iterator pbs1 = getPredNodes(bb1); pbs1.hasNext();) {
if (!hasEdge((IBasicBlock) pbs1.next(), bb2)) {
for (Iterator<? extends T> pbs1 = getPredNodes(bb1); pbs1.hasNext();) {
if (!hasEdge(pbs1.next(), bb2)) {
return false;
}
}

View File

@ -202,7 +202,7 @@ public class ExplodedSupergraphPath<T> {
final Collection<CGNode> exclusions;
SLVPFinder(ExplodedSupergraphWithSummaryEdges<T> esg, Collection<ExplodedSupergraphNode<T>> sources, Collection<ExplodedSupergraphNode<T>> sinks, Collection<CGNode> exclusions) {
super(esg, sources.iterator(), new CollectionFilter(sinks));
super(esg, sources.iterator(), new CollectionFilter<ExplodedSupergraphNode<T>>(sinks));
this.esg = esg;
this.exclusions = exclusions;
// Trace.println("FINDER");
@ -262,6 +262,7 @@ public class ExplodedSupergraphPath<T> {
static class NoReturnBackwardsPathFinder<T> extends BFSPathFinder<ExplodedSupergraphNode<T>> {
final ExplodedSupergraphWithSummaryEdges<T> esg;
@SuppressWarnings("unchecked")
NoReturnBackwardsPathFinder(ExplodedSupergraphWithSummaryEdges<T> esg, ExplodedSupergraphNode<T> sink) {
super(GraphInverter.invert(esg), Collections.singleton(sink).iterator(), zeroFactFilter);
this.esg = esg;

View File

@ -24,6 +24,7 @@ import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cfg.InterproceduralCFG;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.CollectionFilter;
import com.ibm.wala.util.CompoundIterator;
import com.ibm.wala.util.IndiscriminateFilter;
@ -101,6 +102,7 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
* @param noCollapse
* set of nodes in the call graph which cannot be collapsed
*/
@SuppressWarnings("unchecked")
public PartiallyCollapsedSupergraph(CallGraph cg, Collection<CGNode> noCollapse) {
this(cg, noCollapse, IndiscriminateFilter.singleton());
}
@ -114,7 +116,7 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
* set of nodes which are relevant and should be included in the
* supergraph
*/
public PartiallyCollapsedSupergraph(CallGraph cg, Collection<CGNode> noCollapse, Filter relevant) {
public PartiallyCollapsedSupergraph(CallGraph cg, Collection<CGNode> noCollapse, Filter<CGNode> relevant) {
EngineTimings.startVirtual("PartiallyCollapsedSupergraph.<init>");
@ -129,7 +131,7 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
}
}
this.noCollapse = noCollapse;
this.partialIPFG = new InterproceduralCFG(cg, new Filtersection(relevant, new CollectionFilter(noCollapse)), true);
this.partialIPFG = new InterproceduralCFG(cg, new Filtersection<CGNode>(relevant, new CollectionFilter<CGNode>(noCollapse)), true);
if (DEBUG_LEVEL > 0) {
Trace.println("IPFG \n" + partialIPFG.toString());
}
@ -183,10 +185,10 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
public Object[] getExitsForProcedure(CGNode node) {
if (noCollapse.contains(node)) {
ControlFlowGraph cfg = partialIPFG.getCFG(node);
ControlFlowGraph<ISSABasicBlock> cfg = partialIPFG.getCFG(node);
if (cfg instanceof TwoExitCFG) {
IBasicBlock o1 = ((TwoExitCFG) cfg).getNormalExit();
IBasicBlock o2 = ((TwoExitCFG) cfg).getExceptionalExit();
ISSABasicBlock o1 = ((TwoExitCFG) cfg).getNormalExit();
ISSABasicBlock o2 = ((TwoExitCFG) cfg).getExceptionalExit();
return new Object[] { new BasicBlockInContext(node, o1), new BasicBlockInContext(node, o2) };
} else {
return new Object[] { new BasicBlockInContext(node, cfg.exit()) };
@ -331,7 +333,7 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
for (Iterator it2 = cg.getSuccNodes(node); it2.hasNext();) {
CGNode outNode = (CGNode) it2.next();
if (noCollapse.contains(outNode)) {
ControlFlowGraph cfg = partialIPFG.getCFG(outNode);
ControlFlowGraph<ISSABasicBlock> cfg = partialIPFG.getCFG(outNode);
// add an edge to the entry block
BasicBlockInContext entry = new BasicBlockInContext(outNode, cfg.entry());
Set<Object> incoming = MapUtil.findOrCreateSet(incomingTransverseEdges, entry);

View File

@ -646,8 +646,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
*/
protected void addNodeInstructionConstraints(CGNode node, IR ir, DefUse du) {
FlowStatementVisitor v = makeVisitor((ExplicitCallGraph.ExplicitNode) node, ir, du);
ControlFlowGraph cfg = ir.getControlFlowGraph();
for (IBasicBlock b : cfg) {
ControlFlowGraph<ISSABasicBlock> cfg = ir.getControlFlowGraph();
for (ISSABasicBlock b : cfg) {
addBlockInstructionConstraints(node, cfg, b, v);
}
}
@ -655,7 +655,7 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
/**
* Add constraints for a particular basic block.
*/
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph cfg, IBasicBlock b, FlowStatementVisitor v) {
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b, FlowStatementVisitor v) {
v.setBasicBlock(b);
// visit each instruction in the basic block.
@ -669,7 +669,7 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
addPhiConstraints(node, cfg, b);
}
private void addPhiConstraints(CGNode node, ControlFlowGraph cfg, IBasicBlock b) {
private void addPhiConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b) {
// visit each phi instruction in each successor block
for (Iterator<? extends IBasicBlock> iter = cfg.getSuccNodes(b); iter.hasNext();) {
@ -727,9 +727,7 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
}
protected interface FlowStatementVisitor extends SSAInstruction.IVisitor {
void setBasicBlock(IBasicBlock b);
void setBasicBlock(ISSABasicBlock b);
}
public DemandFlowGraph(final CallGraph cg, final HeapModel heapModel, final MemoryAccessMap mam, final ClassHierarchy cha) {

View File

@ -41,7 +41,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.ArrayClass;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
@ -59,6 +58,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSACheckCastInstruction;
@ -143,7 +143,7 @@ public class DemandPointerFlowGraph extends DemandFlowGraph {
/**
* The basic block currently being processed
*/
private IBasicBlock basicBlock;
private ISSABasicBlock basicBlock;
/**
* Governing symbol table
@ -458,14 +458,14 @@ public class DemandPointerFlowGraph extends DemandFlowGraph {
Assertions.UNREACHABLE();
}
public IBasicBlock getBasicBlock() {
public ISSABasicBlock getBasicBlock() {
return basicBlock;
}
/**
* The calling loop must call this in each iteration!
*/
public void setBasicBlock(IBasicBlock block) {
public void setBasicBlock(ISSABasicBlock block) {
basicBlock = block;
}

View File

@ -40,7 +40,6 @@ package com.ibm.wala.demandpa.flowgraph;
import java.util.List;
import java.util.Set;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.ArrayClass;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
@ -58,6 +57,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
@ -139,7 +139,7 @@ public class DemandValueFlowGraph extends DemandFlowGraph {
/**
* The basic block currently being processed
*/
private IBasicBlock basicBlock;
private ISSABasicBlock basicBlock;
/**
* Governing symbol table
@ -485,14 +485,14 @@ public class DemandValueFlowGraph extends DemandFlowGraph {
handleNonHeapInstruction(instruction);
}
public IBasicBlock getBasicBlock() {
public ISSABasicBlock getBasicBlock() {
return basicBlock;
}
/**
* The calling loop must call this in each iteration!
*/
public void setBasicBlock(IBasicBlock block) {
public void setBasicBlock(ISSABasicBlock block) {
basicBlock = block;
}

View File

@ -495,8 +495,8 @@ public class SimpleDemandPointerFlowGraph extends SlowSparseNumberedGraph<Object
*/
protected void addNodeInstructionConstraints(CGNode node, IR ir, DefUse du) {
StatementVisitor v = makeVisitor((ExplicitCallGraph.ExplicitNode) node, ir, du);
ControlFlowGraph cfg = ir.getControlFlowGraph();
for (IBasicBlock b : cfg) {
ControlFlowGraph<ISSABasicBlock> cfg = ir.getControlFlowGraph();
for (ISSABasicBlock b : cfg) {
addBlockInstructionConstraints(node, cfg, b, v);
}
}
@ -504,7 +504,7 @@ public class SimpleDemandPointerFlowGraph extends SlowSparseNumberedGraph<Object
/**
* Add constraints for a particular basic block.
*/
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph cfg, IBasicBlock b, StatementVisitor v) {
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b, StatementVisitor v) {
v.setBasicBlock(b);
// visit each instruction in the basic block.
@ -518,7 +518,7 @@ public class SimpleDemandPointerFlowGraph extends SlowSparseNumberedGraph<Object
addPhiConstraints(node, cfg, b);
}
private void addPhiConstraints(CGNode node, ControlFlowGraph cfg, IBasicBlock b) {
private void addPhiConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b) {
// visit each phi instruction in each successor block
for (Iterator<? extends IBasicBlock> sbs = cfg.getSuccNodes(b); sbs.hasNext();) {
@ -598,7 +598,7 @@ public class SimpleDemandPointerFlowGraph extends SlowSparseNumberedGraph<Object
/**
* The basic block currently being processed
*/
private IBasicBlock basicBlock;
private ISSABasicBlock basicBlock;
/**
* Governing symbol table
@ -1294,14 +1294,14 @@ public class SimpleDemandPointerFlowGraph extends SlowSparseNumberedGraph<Object
// }
}
public IBasicBlock getBasicBlock() {
public ISSABasicBlock getBasicBlock() {
return basicBlock;
}
/**
* The calling loop must call this in each iteration!
*/
public void setBasicBlock(IBasicBlock block) {
public void setBasicBlock(ISSABasicBlock block) {
basicBlock = block;
}

View File

@ -14,9 +14,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSACFG;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
@ -58,7 +58,7 @@ public class LocalLiveRangeAnalysis {
Assertions.UNREACHABLE();
}
}
IBasicBlock queryBlock = findBlock(ir, instructionIndex);
ISSABasicBlock queryBlock = findBlock(ir, instructionIndex);
SSAInstruction def = du.getDef(v);
final SSACFG.BasicBlock defBlock = def == null ? null : findBlock(ir, def);
final Collection<BasicBlock> uses = findBlocks(ir, du.getUses(v));
@ -154,7 +154,7 @@ public class LocalLiveRangeAnalysis {
*
* @return the basic block which contains the ith instruction
*/
private static IBasicBlock findBlock(IR ir, int i) {
private static ISSABasicBlock findBlock(IR ir, int i) {
for (Iterator it = ir.getControlFlowGraph().iterator(); it.hasNext();) {
SSACFG.BasicBlock b = (SSACFG.BasicBlock) it.next();
if (i >= b.getFirstInstructionIndex() && i <= b.getLastInstructionIndex()) {

View File

@ -18,6 +18,7 @@ import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.graph.INodeWithNumber;
/**
@ -95,7 +96,7 @@ public interface CGNode extends INodeWithNumber, ContextItem {
/**
* @return a CFG that represents the node, or null if it's an unmodelled native method
*/
public ControlFlowGraph getCFG();
public ControlFlowGraph<ISSABasicBlock> getCFG();
/**
* @return an Iterator of the types that may be allocated by a given

View File

@ -27,6 +27,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeBT.BytecodeConstants;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.IntFunction;
import com.ibm.wala.util.IntMapIterator;
import com.ibm.wala.util.collections.EmptyIterator;
@ -321,7 +322,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
return getCallGraph().getInterpreter(this).iterateNewSites(this);
}
public ControlFlowGraph getCFG() {
public ControlFlowGraph<ISSABasicBlock> getCFG() {
return getCallGraph().getInterpreter(this).getCFG(this);
}
}

View File

@ -36,8 +36,8 @@ public class PartialCallGraph extends DelegatingGraph<CGNode> implements CallGra
}
public static PartialCallGraph make(final CallGraph CG, final Set<CGNode> partialRoots, final Collection<CGNode> nodes) {
Graph<CGNode> partialGraph = GraphSlicer.prune(CG, new Filter() {
public boolean accepts(Object o) {
Graph<CGNode> partialGraph = GraphSlicer.prune(CG, new Filter<CGNode>() {
public boolean accepts(CGNode o) {
return nodes.contains(o);
}
});
@ -47,8 +47,8 @@ public class PartialCallGraph extends DelegatingGraph<CGNode> implements CallGra
public static PartialCallGraph make(CallGraph CG, Set<CGNode> partialRoots) {
final Set<CGNode> nodes = DFS.getReachableNodes(CG, partialRoots);
Graph<CGNode> partialGraph = GraphSlicer.prune(CG, new Filter() {
public boolean accepts(Object o) {
Graph<CGNode> partialGraph = GraphSlicer.prune(CG, new Filter<CGNode>() {
public boolean accepts(CGNode o) {
return nodes.contains(o);
}
});

View File

@ -14,12 +14,12 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.ProgramCounter;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
@ -254,7 +254,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
private final IR ir;
private final IBasicBlock bb;
private final ISSABasicBlock bb;
private final PointerAnalysis pa;

View File

@ -15,6 +15,7 @@ import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
*
@ -43,6 +44,6 @@ public interface SSAContextInterpreter extends RTAContextInterpreter {
*/
public int getNumberOfStatements(CGNode node);
public ControlFlowGraph getCFG(CGNode n);
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode n);
}

View File

@ -44,6 +44,7 @@ import com.ibm.wala.shrikeBT.IInstruction;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAAbstractThrowInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
@ -275,8 +276,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
ConstraintVisitor v = makeVisitor((ExplicitCallGraph.ExplicitNode) node);
IR ir = getCFAContextInterpreter().getIR(node);
ControlFlowGraph cfg = ir.getControlFlowGraph();
for (Iterator<IBasicBlock> x = cfg.iterator(); x.hasNext();) {
ControlFlowGraph<ISSABasicBlock> cfg = ir.getControlFlowGraph();
for (Iterator<ISSABasicBlock> x = cfg.iterator(); x.hasNext();) {
BasicBlock b = (BasicBlock) x.next();
addBlockInstructionConstraints(node, cfg, b, v);
if (wasChanged(node)) {
@ -288,7 +289,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
/**
* Add constraints for a particular basic block.
*/
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph cfg, BasicBlock b, ConstraintVisitor v) {
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, BasicBlock b, ConstraintVisitor v) {
v.setBasicBlock(b);
// visit each instruction in the basic block.
@ -305,7 +306,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
addPhiConstraints(node, cfg, b, v);
}
private void addPhiConstraints(CGNode node, ControlFlowGraph cfg, BasicBlock b, ConstraintVisitor v) {
private void addPhiConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, BasicBlock b, ConstraintVisitor v) {
// visit each phi instruction in each successor block
for (Iterator sbs = cfg.getSuccNodes(b); sbs.hasNext();) {
BasicBlock sb = (BasicBlock) sbs.next();
@ -446,13 +447,11 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
}
/**
* @param call
* @param ir
* @return true iff there's a unique catch block which catches all exceptions
* thrown by a certain call site.
*/
protected static boolean hasUniqueCatchBlock(SSAAbstractInvokeInstruction call, IR ir) {
IBasicBlock[] bb = ir.getBasicBlocksForCall(call.getCallSite());
ISSABasicBlock[] bb = ir.getBasicBlocksForCall(call.getCallSite());
if (bb.length == 1) {
Iterator it = ir.getControlFlowGraph().getExceptionalSuccessors(bb[0]).iterator();
// check that there's exactly one element in the iterator
@ -479,7 +478,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
if (ir == null) {
throw new IllegalArgumentException("ir == null");
}
IBasicBlock[] bb = ir.getBasicBlocksForCall(call.getCallSite());
ISSABasicBlock[] bb = ir.getBasicBlocksForCall(call.getCallSite());
if (Assertions.verifyAssertions) {
Assertions._assert(bb.length == 1);
}
@ -499,16 +498,16 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
* @throws IllegalArgumentException
* if ir is null
*/
public static List<ProgramCounter> getIncomingPEIs(IR ir, IBasicBlock bb) {
public static List<ProgramCounter> getIncomingPEIs(IR ir, ISSABasicBlock bb) {
if (ir == null) {
throw new IllegalArgumentException("ir is null");
}
if (DEBUG) {
Trace.println("getIncomingPEIs " + bb);
}
ControlFlowGraph G = ir.getControlFlowGraph();
List<ProgramCounter> result = new ArrayList<ProgramCounter>(G.getPredNodeCount(bb));
for (Iterator it = G.getPredNodes(bb); it.hasNext();) {
ControlFlowGraph<ISSABasicBlock> g = ir.getControlFlowGraph();
List<ProgramCounter> result = new ArrayList<ProgramCounter>(g.getPredNodeCount(bb));
for (Iterator it = g.getPredNodes(bb); it.hasNext();) {
BasicBlock pred = (BasicBlock) it.next();
if (DEBUG) {
Trace.println("pred: " + pred);
@ -521,9 +520,9 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
// TODO: consider pruning CFG for unreachable blocks.
if (pei != null && pei.isPEI()) {
if (DEBUG) {
Trace.println("PEI: " + pei + " index " + index + " PC " + G.getProgramCounter(index));
Trace.println("PEI: " + pei + " index " + index + " PC " + g.getProgramCounter(index));
}
result.add(new ProgramCounter(G.getProgramCounter(index)));
result.add(new ProgramCounter(g.getProgramCounter(index)));
}
}
return result;
@ -563,7 +562,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
/**
* The basic block currently being processed
*/
private IBasicBlock basicBlock;
private ISSABasicBlock basicBlock;
/**
* Governing symbol table
@ -1272,17 +1271,17 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
@Override
public void visitPi(SSAPiInstruction instruction) {
int dir;
ControlFlowGraph CFG = ir.getControlFlowGraph();
ControlFlowGraph<ISSABasicBlock> cfg = ir.getControlFlowGraph();
PointerKey src = getPointerKeyForLocal(instruction.getVal());
if (hasNoInterestingUses(instruction.getDef())) {
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
system.recordImplicitPointsToSet(dst);
} else {
if (com.ibm.wala.cfg.Util.endsWithConditionalBranch(CFG, getBasicBlock()) && CFG.getSuccNodeCount(getBasicBlock()) == 2) {
SSAConditionalBranchInstruction cond = (SSAConditionalBranchInstruction) com.ibm.wala.cfg.Util.getLastInstruction(CFG,
if (com.ibm.wala.cfg.Util.endsWithConditionalBranch(cfg, getBasicBlock()) && cfg.getSuccNodeCount(getBasicBlock()) == 2) {
SSAConditionalBranchInstruction cond = (SSAConditionalBranchInstruction) com.ibm.wala.cfg.Util.getLastInstruction(cfg,
getBasicBlock());
SSAInstruction cause = instruction.getCause();
BasicBlock target = (BasicBlock) CFG.getNode(instruction.getSuccessor());
BasicBlock target = (BasicBlock) cfg.getNode(instruction.getSuccessor());
if ((cause instanceof SSAInstanceofInstruction) && ((dir = booleanConstantTest(cond, cause.getDef())) != 0)) {
TypeReference type = ((SSAInstanceofInstruction) cause).getCheckedType();
IClass cls = getClassHierarchy().lookupClass(type);
@ -1292,8 +1291,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
system.newConstraint(dst, assignOperator, src);
} else {
PointerKey dst = getFilteredPointerKeyForLocal(instruction.getDef(), new FilteredPointerKey.SingleClassFilter(cls));
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(CFG, getBasicBlock()) && dir == 1)
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(CFG, getBasicBlock()) && dir == -1)) {
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && dir == 1)
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && dir == -1)) {
system.newConstraint(dst, getBuilder().filterOperator, src);
// System.err.println("PI " + dst + " " + src);
} else {
@ -1301,8 +1300,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
}
}
} else if ((dir = nullConstantTest(cond, instruction.getVal())) != 0) {
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(CFG, getBasicBlock()) && dir == -1)
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(CFG, getBasicBlock()) && dir == 1)) {
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && dir == -1)
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && dir == 1)) {
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
system.newConstraint(dst, assignOperator, src);
}
@ -1317,14 +1316,14 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
}
}
public IBasicBlock getBasicBlock() {
public ISSABasicBlock getBasicBlock() {
return basicBlock;
}
/**
* The calling loop must call this in each iteration!
*/
public void setBasicBlock(IBasicBlock block) {
public void setBasicBlock(ISSABasicBlock block) {
basicBlock = block;
}

View File

@ -20,6 +20,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.rta.ContextInsensitiveRTAInterpreter;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
*
@ -56,7 +57,7 @@ public class ContextInsensitiveSSAInterpreter extends ContextInsensitiveRTAInter
return false;
}
public ControlFlowGraph getCFG(CGNode N) {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
IR ir = getIR(N);
if (ir == null) {
return null;

View File

@ -24,6 +24,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.rta.DefaultRTAInterpreter;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
*
@ -76,7 +77,7 @@ public class DefaultSSAInterpreter extends DefaultRTAInterpreter implements SSAC
return false;
}
public ControlFlowGraph getCFG(CGNode N) {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
return getCFAInterpreter(N).getCFG(N);
}

View File

@ -17,6 +17,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.rta.DelegatingRTAContextInterpreter;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.debug.Assertions;
/**
@ -81,7 +82,9 @@ public class DelegatingSSAContextInterpreter extends DelegatingRTAContextInterpr
result |= B.recordFactoryType(node, klass);
return result;
}
public ControlFlowGraph getCFG(CGNode node) {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode node) {
if (A != null) {
if (A.understands(node)) {
return A.getCFG(node);

View File

@ -16,7 +16,7 @@ import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.shrikeBT.IInstruction;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.graph.impl.NodeWithNumber;
/**
@ -26,14 +26,11 @@ import com.ibm.wala.util.graph.impl.NodeWithNumber;
* @author sfink
*/
public final class BasicBlockInContext extends NodeWithNumber implements IBasicBlock {
private final IBasicBlock delegate;
private final ISSABasicBlock delegate;
private final CGNode node;
public BasicBlockInContext(CGNode node, IBasicBlock bb) {
if (Assertions.verifyAssertions) {
Assertions._assert(!(bb instanceof BasicBlockInContext));
}
public BasicBlockInContext(CGNode node, ISSABasicBlock bb) {
this.delegate = bb;
this.node = node;
}
@ -109,7 +106,7 @@ public final class BasicBlockInContext extends NodeWithNumber implements IBasicB
return delegate.hashCode() + 229 * node.hashCode();
}
public IBasicBlock getDelegate() {
public ISSABasicBlock getDelegate() {
return delegate;
}

View File

@ -12,10 +12,10 @@ package com.ibm.wala.ipa.cfg;
import com.ibm.wala.cfg.IBasicBlock;
public interface EdgeFilter {
public interface EdgeFilter<T extends IBasicBlock> {
boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst);
boolean hasNormalEdge(T src, T dst);
boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst);
boolean hasExceptionalEdge(T src, T dst);
}

View File

@ -18,17 +18,17 @@ import com.ibm.wala.cfg.IBasicBlock;
*/
public class ExceptionPrunedCFG {
private static final EdgeFilter exceptionEdgePruner = new EdgeFilter() {
public boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst) {
private static class ExceptionEdgePruner<T extends IBasicBlock> implements EdgeFilter<T>{
public boolean hasNormalEdge(T src, T dst) {
return true;
}
public boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasExceptionalEdge(T src, T dst) {
return false;
}
};
public static PrunedCFG make(ControlFlowGraph cfg) {
return PrunedCFG.make(cfg, exceptionEdgePruner);
public static <T extends IBasicBlock> PrunedCFG<T> make(ControlFlowGraph<T> cfg) {
return PrunedCFG.make(cfg, new ExceptionEdgePruner<T>());
}
}

View File

@ -23,6 +23,7 @@ import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.shrikeBT.IInstruction;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.shrikeBT.InvokeInstruction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.Function;
@ -80,7 +81,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
/**
* Filter that determines relevant call graph nodes
*/
private final Filter relevant;
private final Filter<CGNode> relevant;
/**
* a cache: for each node (Basic Block), does that block end in a call?
@ -95,6 +96,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param CG
* the call graph
*/
@SuppressWarnings("unchecked")
public InterproceduralCFG(CallGraph CG) {
this(CG, IndiscriminateFilter.singleton(), false);
}
@ -108,7 +110,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* a filter which accepts those call graph nodes which should be
* included in the I-CFG. Other nodes are ignored.
*/
public InterproceduralCFG(CallGraph CG, Filter relevant, boolean partitionExits) {
public InterproceduralCFG(CallGraph CG, Filter<CGNode> relevant, boolean partitionExits) {
EngineTimings.startVirtual("InterproceduralCFG.<init>");
this.cg = CG;
@ -141,7 +143,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
CGNode n = (CGNode) ns.next();
if (relevant.accepts(n)) {
// retrieve a cfg for node n.
ControlFlowGraph cfg = n.getCFG();
ControlFlowGraph<ISSABasicBlock> cfg = n.getCFG();
if (cfg == null) {
// n is an unmodelled native method
continue;
@ -152,7 +154,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
IInstruction[] instrs = cfg.getInstructions();
// create edges for node n.
for (Iterator bbs = cfg.iterator(); bbs.hasNext();) {
IBasicBlock bb = (IBasicBlock) bbs.next();
ISSABasicBlock bb = (ISSABasicBlock) bbs.next();
// entry node gets edges from callers
if (bb == cfg.entry()) {
addEdgesToEntryBlock(n, bb);
@ -179,7 +181,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
}
// retrieve a cfg for node n.
ControlFlowGraph cfg = getCFG(n);
ControlFlowGraph<ISSABasicBlock> cfg = getCFG(n);
if (cfg != null) {
// create a node for each basic block.
addNodeForEachBasicBlock(cfg, n);
@ -189,16 +191,15 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
}
/**
* @param n
* @return the cfg for n, or null if none found
* @throws IllegalArgumentException
* if n == null
*/
public ControlFlowGraph getCFG(CGNode n) throws IllegalArgumentException {
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode n) throws IllegalArgumentException {
if (n == null) {
throw new IllegalArgumentException("n == null");
}
ControlFlowGraph cfg = n.getCFG();
ControlFlowGraph<ISSABasicBlock> cfg = n.getCFG();
if (cfg == null) {
return null;
}
@ -245,7 +246,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param bb
* a basic block in the CFG
*/
private void addEdgesToNonEntryBlock(CGNode n, ControlFlowGraph cfg, IInstruction[] instrs, IBasicBlock bb) {
private void addEdgesToNonEntryBlock(CGNode n, ControlFlowGraph<ISSABasicBlock> cfg, IInstruction[] instrs, ISSABasicBlock bb) {
if (DEBUG_LEVEL > 0) {
Trace.println("addEdgesForNonEntryBlock: " + bb);
@ -254,7 +255,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
}
for (Iterator ps = cfg.getPredNodes(bb); ps.hasNext();) {
IBasicBlock pb = (IBasicBlock) ps.next();
ISSABasicBlock pb = (ISSABasicBlock) ps.next();
if (DEBUG_LEVEL > 0) {
Trace.println("Consider previous block: " + pb);
}
@ -297,7 +298,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
Trace.println("Relevant target: " + tn);
}
// add an edge from tn exit to this node
ControlFlowGraph tcfg = tn.getCFG();
ControlFlowGraph<ISSABasicBlock> tcfg = tn.getCFG();
// tcfg might be null if tn is an unmodelled native method
if (tcfg != null) {
if (partitionExits) {
@ -373,8 +374,8 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param targetCFG
* the called method
*/
private void addEdgesFromExceptionalExitToReturn(CGNode caller, IBasicBlock returnBlock, CGNode target, TwoExitCFG targetCFG) {
IBasicBlock texit = targetCFG.getExceptionalExit();
private void addEdgesFromExceptionalExitToReturn(CGNode caller, ISSABasicBlock returnBlock, CGNode target, TwoExitCFG targetCFG) {
ISSABasicBlock texit = targetCFG.getExceptionalExit();
BasicBlockInContext exit = new BasicBlockInContext(target, texit);
BasicBlockInContext ret = new BasicBlockInContext(caller, returnBlock);
if (Assertions.verifyAssertions) {
@ -395,7 +396,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* a basic block that ends in a call
* @return true iff bb is reached from pb by exceptional control flow
*/
private boolean representsExceptionalReturn(ControlFlowGraph cfg, IBasicBlock ret, IBasicBlock call) {
private boolean representsExceptionalReturn(ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock ret, ISSABasicBlock call) {
for (Iterator it = cfg.getExceptionalSuccessors(call).iterator(); it.hasNext();) {
if (ret.equals(it.next())) {
return true;
@ -413,8 +414,8 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param targetCFG
* the called method
*/
private void addEdgesFromNormalExitToReturn(CGNode caller, IBasicBlock returnBlock, CGNode target, TwoExitCFG targetCFG) {
IBasicBlock texit = targetCFG.getNormalExit();
private void addEdgesFromNormalExitToReturn(CGNode caller, ISSABasicBlock returnBlock, CGNode target, TwoExitCFG targetCFG) {
ISSABasicBlock texit = targetCFG.getNormalExit();
BasicBlockInContext exit = new BasicBlockInContext(target, texit);
BasicBlockInContext ret = new BasicBlockInContext(caller, returnBlock);
if (Assertions.verifyAssertions) {
@ -431,7 +432,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* the governing cfg
* @return true iff bb is reached from pb by a normal return flow
*/
private boolean representsNormalReturn(ControlFlowGraph cfg, IBasicBlock ret, IBasicBlock call) {
private boolean representsNormalReturn(ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock ret, ISSABasicBlock call) {
for (Iterator it = cfg.getNormalSuccessors(call).iterator(); it.hasNext();) {
if (ret.equals(it.next())) {
return true;
@ -449,8 +450,8 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param targetCFG
* the called method
*/
private void addEdgesFromExitToReturn(CGNode caller, IBasicBlock returnBlock, CGNode target, ControlFlowGraph targetCFG) {
IBasicBlock texit = targetCFG.exit();
private void addEdgesFromExitToReturn(CGNode caller, ISSABasicBlock returnBlock, CGNode target, ControlFlowGraph<ISSABasicBlock> targetCFG) {
ISSABasicBlock texit = targetCFG.exit();
BasicBlockInContext exit = new BasicBlockInContext(target, texit);
BasicBlockInContext ret = new BasicBlockInContext(caller, returnBlock);
if (Assertions.verifyAssertions) {
@ -470,7 +471,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param bb
* the entry() block for n
*/
private void addEdgesToEntryBlock(CGNode n, IBasicBlock bb) {
private void addEdgesToEntryBlock(CGNode n, ISSABasicBlock bb) {
if (DEBUG_LEVEL > 0) {
Trace.println("addEdgesToEntryBlock " + bb);
@ -485,7 +486,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
if (DEBUG_LEVEL > 0) {
Trace.println("caller " + caller + "is relevant");
}
ControlFlowGraph ccfg = caller.getCFG();
ControlFlowGraph<ISSABasicBlock> ccfg = caller.getCFG();
IInstruction[] cinsts = ccfg.getInstructions();
if (DEBUG_LEVEL > 0) {
@ -503,7 +504,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
if (DEBUG_LEVEL > 0) {
Trace.println("Adding edge " + ccfg.getBlockForInstruction(i) + " to " + bb);
}
IBasicBlock callerBB = ccfg.getBlockForInstruction(i);
ISSABasicBlock callerBB = ccfg.getBlockForInstruction(i);
BasicBlockInContext b1 = new BasicBlockInContext(caller, callerBB);
BasicBlockInContext b2 = new BasicBlockInContext(n, bb);
G.addEdge(b1, b2);
@ -521,9 +522,9 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @param cfg
* a control-flow graph
*/
private void addNodeForEachBasicBlock(ControlFlowGraph cfg, CGNode N) {
for (Iterator bbs = cfg.iterator(); bbs.hasNext();) {
IBasicBlock bb = (IBasicBlock) bbs.next();
private void addNodeForEachBasicBlock(ControlFlowGraph<ISSABasicBlock> cfg, CGNode N) {
for (Iterator<ISSABasicBlock> bbs = cfg.iterator(); bbs.hasNext();) {
ISSABasicBlock bb = bbs.next();
if (DEBUG_LEVEL > 0) {
Trace.println("IPCFG Add basic block " + bb);
}
@ -539,7 +540,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
* @return the original CFG from whence B came
* @throws IllegalArgumentException if B == null
*/
public ControlFlowGraph getCFG(BasicBlockInContext B) throws IllegalArgumentException {
public ControlFlowGraph<ISSABasicBlock> getCFG(BasicBlockInContext B) throws IllegalArgumentException {
if (B == null) {
throw new IllegalArgumentException("B == null");
}
@ -758,8 +759,8 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
}
public Object getEntry(CGNode n) {
ControlFlowGraph cfg = getCFG(n);
IBasicBlock entry = cfg.entry();
ControlFlowGraph<ISSABasicBlock> cfg = getCFG(n);
ISSABasicBlock entry = cfg.entry();
return new BasicBlockInContext(n, entry);
}
@ -794,16 +795,16 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
if (bb == null) {
throw new IllegalArgumentException("bb is null");
}
ControlFlowGraph cfg = getCFG(bb);
Iterator<? extends IBasicBlock> it = cfg.getPredNodes(bb.getDelegate());
ControlFlowGraph<ISSABasicBlock> cfg = getCFG(bb);
Iterator<? extends ISSABasicBlock> it = cfg.getPredNodes(bb.getDelegate());
final CGNode node = bb.getNode();
Function<IBasicBlock, BasicBlockInContext> toContext = new Function<IBasicBlock, BasicBlockInContext>() {
public BasicBlockInContext apply(IBasicBlock object) {
IBasicBlock b = object;
Function<ISSABasicBlock, BasicBlockInContext> toContext = new Function<ISSABasicBlock, BasicBlockInContext>() {
public BasicBlockInContext apply(ISSABasicBlock object) {
ISSABasicBlock b = object;
return new BasicBlockInContext(node, b);
}
};
MapIterator<IBasicBlock, BasicBlockInContext> m = new MapIterator<IBasicBlock, BasicBlockInContext>(it, toContext);
MapIterator<ISSABasicBlock, BasicBlockInContext> m = new MapIterator<ISSABasicBlock, BasicBlockInContext>(it, toContext);
return new FilterIterator<BasicBlockInContext>(m, isCall);
}
@ -817,9 +818,9 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
if (bb == null) {
throw new IllegalArgumentException("bb == null");
}
ControlFlowGraph cfg = getCFG(bb);
for (Iterator it = cfg.getPredNodes(bb.getDelegate()); it.hasNext();) {
IBasicBlock b = (IBasicBlock) it.next();
ControlFlowGraph<ISSABasicBlock> cfg = getCFG(bb);
for (Iterator<? extends ISSABasicBlock> it = cfg.getPredNodes(bb.getDelegate()); it.hasNext();) {
ISSABasicBlock b = it.next();
if (hasCall(new BasicBlockInContext(bb.getNode(), b))) {
return true;
}

View File

@ -38,107 +38,110 @@ import com.ibm.wala.util.intset.IntSetUtil;
import com.ibm.wala.util.intset.MutableIntSet;
/**
* A pruned view of a {@link ControlFlowGraph}. Use this class along with
* an {@link EdgeFilter} to produce a custom view of a CFG.
* A pruned view of a {@link ControlFlowGraph}. Use this class along with an
* {@link EdgeFilter} to produce a custom view of a CFG.
*
* For example, you can use this class to produce a CFG view that ignores certain
* types of exceptional edges.
* For example, you can use this class to produce a CFG view that ignores
* certain types of exceptional edges.
*/
public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements ControlFlowGraph {
public class PrunedCFG<T extends IBasicBlock> extends AbstractNumberedGraph<T> implements ControlFlowGraph<T> {
/**
* @param cfg the original CFG that you want a view of
* @param filter an object that selectively filters edges in the original CFG
* @param cfg
* the original CFG that you want a view of
* @param filter
* an object that selectively filters edges in the original CFG
* @return a view of cfg that includes only edges accepted by the filter.
* @throws IllegalArgumentException if cfg is null
* @throws IllegalArgumentException
* if cfg is null
*/
public static PrunedCFG make(final ControlFlowGraph cfg, final EdgeFilter filter) {
public static <T extends IBasicBlock> PrunedCFG<T> make(final ControlFlowGraph<T> cfg, final EdgeFilter<T> filter) {
if (cfg == null) {
throw new IllegalArgumentException("cfg is null");
}
return new PrunedCFG(cfg, filter);
return new PrunedCFG<T>(cfg, filter);
}
private static class FilteredCFGEdges implements NumberedEdgeManager<IBasicBlock> {
private final ControlFlowGraph cfg;
private static class FilteredCFGEdges<T extends IBasicBlock> implements NumberedEdgeManager<T> {
private final ControlFlowGraph<T> cfg;
private final NumberedNodeManager<IBasicBlock> currentCFGNodes;
private final NumberedNodeManager<T> currentCFGNodes;
private final EdgeFilter filter;
private final EdgeFilter<T> filter;
FilteredCFGEdges(ControlFlowGraph cfg, NumberedNodeManager<IBasicBlock> currentCFGNodes, EdgeFilter filter) {
FilteredCFGEdges(ControlFlowGraph<T> cfg, NumberedNodeManager<T> currentCFGNodes, EdgeFilter<T> 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(N, (IBasicBlock) o);
public Iterator<T> getExceptionalSuccessors(final T N) {
return new FilterIterator<T>(cfg.getExceptionalSuccessors(N).iterator(), new Filter<T>() {
public boolean accepts(T o) {
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge(N, 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(N, (IBasicBlock) o);
public Iterator<T> getNormalSuccessors(final T N) {
return new FilterIterator<T>(cfg.getNormalSuccessors(N).iterator(), new Filter<T>() {
public boolean accepts(T o) {
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge(N, 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, N);
public Iterator<T> getExceptionalPredecessors(final T N) {
return new FilterIterator<T>(cfg.getExceptionalPredecessors(N).iterator(), new Filter<T>() {
public boolean accepts(T o) {
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge(o, 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, N);
public Iterator<T> getNormalPredecessors(final T N) {
return new FilterIterator<T>(cfg.getNormalPredecessors(N).iterator(), new Filter<T>() {
public boolean accepts(T o) {
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge(o, N);
}
});
}
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalSuccessors(N), getExceptionalSuccessors(N));
public Iterator<T> getSuccNodes(T N) {
return new CompoundIterator<T>(getNormalSuccessors(N), getExceptionalSuccessors(N));
}
public int getSuccNodeCount(IBasicBlock N) {
public int getSuccNodeCount(T N) {
return Iterator2Collection.toCollection(getSuccNodes(N)).size();
}
public IntSet getSuccNodeNumbers(IBasicBlock N) {
public IntSet getSuccNodeNumbers(T N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getSuccNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
for (Iterator<T> EE = getSuccNodes(N); EE.hasNext();) {
bits.add(EE.next().getNumber());
}
return bits;
}
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalPredecessors(N), getExceptionalPredecessors(N));
public Iterator<T> getPredNodes(T N) {
return new CompoundIterator<T>(getNormalPredecessors(N), getExceptionalPredecessors(N));
}
public int getPredNodeCount(IBasicBlock N) {
public int getPredNodeCount(T N) {
return Iterator2Collection.toCollection(getPredNodes(N)).size();
}
public IntSet getPredNodeNumbers(IBasicBlock N) {
public IntSet getPredNodeNumbers(T N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getPredNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
for (Iterator<T> EE = getPredNodes(N); EE.hasNext();) {
bits.add(EE.next().getNumber());
}
return bits;
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
public boolean hasEdge(T src, T dst) {
for (Iterator EE = getSuccNodes(src); EE.hasNext();) {
if (EE.next().equals(dst)) {
return true;
@ -148,46 +151,46 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return false;
}
public void addEdge(IBasicBlock src, IBasicBlock dst) {
public void addEdge(T src, T dst) {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) {
public void removeEdge(T src, T dst) {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(IBasicBlock node) {
public void removeAllIncidentEdges(T node) {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(IBasicBlock node) {
public void removeIncomingEdges(T node) {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) {
public void removeOutgoingEdges(T node) {
throw new UnsupportedOperationException();
}
}
private static class FilteredNodes implements NumberedNodeManager<IBasicBlock> {
private final NumberedNodeManager<IBasicBlock> nodes;
private static class FilteredNodes<T extends IBasicBlock> implements NumberedNodeManager<T> {
private final NumberedNodeManager<T> nodes;
private final Set subset;
FilteredNodes(NumberedNodeManager<IBasicBlock> nodes, Set subset) {
FilteredNodes(NumberedNodeManager<T> nodes, Set subset) {
this.nodes = nodes;
this.subset = subset;
}
public int getNumber(IBasicBlock N) {
public int getNumber(T N) {
if (subset.contains(N))
return nodes.getNumber(N);
else
return -1;
}
public IBasicBlock getNode(int number) {
IBasicBlock N = nodes.getNode(number);
public T getNode(int number) {
T N = nodes.getNode(number);
if (subset.contains(N))
return N;
else
@ -196,8 +199,8 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
public int getMaxNumber() {
int max = -1;
for (Iterator<? extends IBasicBlock> NS = nodes.iterator(); NS.hasNext();) {
IBasicBlock N = NS.next();
for (Iterator<? extends T> NS = nodes.iterator(); NS.hasNext();) {
T N = NS.next();
if (subset.contains(N) && getNumber(N) > max) {
max = getNumber(N);
}
@ -206,19 +209,19 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return max;
}
private Iterator<IBasicBlock> filterNodes(Iterator nodeIterator) {
return new FilterIterator<IBasicBlock>(nodeIterator, new Filter() {
private Iterator<T> filterNodes(Iterator nodeIterator) {
return new FilterIterator<T>(nodeIterator, new Filter() {
public boolean accepts(Object o) {
return subset.contains(o);
}
});
}
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
public Iterator<T> iterateNodes(IntSet s) {
return filterNodes(nodes.iterateNodes(s));
}
public Iterator<IBasicBlock> iterator() {
public Iterator<T> iterator() {
return filterNodes(nodes.iterator());
}
@ -226,84 +229,84 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return subset.size();
}
public void addNode(IBasicBlock n) {
public void addNode(T n) {
throw new UnsupportedOperationException();
}
public void removeNode(IBasicBlock n) {
public void removeNode(T n) {
throw new UnsupportedOperationException();
}
public boolean containsNode(IBasicBlock N) {
public boolean containsNode(T N) {
return subset.contains(N);
}
}
private final ControlFlowGraph cfg;
private final ControlFlowGraph<T> cfg;
private final FilteredNodes nodes;
private final FilteredNodes<T> nodes;
private final FilteredCFGEdges edges;
private final FilteredCFGEdges<T> edges;
private PrunedCFG(final ControlFlowGraph cfg, final EdgeFilter filter) {
private PrunedCFG(final ControlFlowGraph<T> cfg, final EdgeFilter<T> filter) {
this.cfg = cfg;
Graph<IBasicBlock> temp = new AbstractNumberedGraph<IBasicBlock>() {
private final EdgeManager<IBasicBlock> edges = new FilteredCFGEdges(cfg, cfg, filter);
Graph<T> temp = new AbstractNumberedGraph<T>() {
private final EdgeManager<T> edges = new FilteredCFGEdges<T>(cfg, cfg, filter);
@Override
protected NodeManager<IBasicBlock> getNodeManager() {
protected NodeManager<T> getNodeManager() {
return cfg;
}
@Override
protected EdgeManager<IBasicBlock> getEdgeManager() {
protected EdgeManager<T> 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()));
Set<T> reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
Set<T> 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);
this.nodes = new FilteredNodes<T>(cfg, reachable);
this.edges = new FilteredCFGEdges<T>(cfg, nodes, filter);
}
@Override
protected NodeManager<IBasicBlock> getNodeManager() {
protected NodeManager<T> getNodeManager() {
return nodes;
}
@Override
protected EdgeManager<IBasicBlock> getEdgeManager() {
protected EdgeManager<T> getEdgeManager() {
return edges;
}
public Collection<IBasicBlock> getExceptionalSuccessors(final IBasicBlock N) {
public Collection<T> getExceptionalSuccessors(final T N) {
return Iterator2Collection.toCollection(edges.getExceptionalSuccessors(N));
}
public Collection<IBasicBlock> getNormalSuccessors(final IBasicBlock N) {
public Collection<T> getNormalSuccessors(final T N) {
return Iterator2Collection.toCollection(edges.getNormalSuccessors(N));
}
public Collection<IBasicBlock> getExceptionalPredecessors(final IBasicBlock N) {
public Collection<T> getExceptionalPredecessors(final T N) {
return Iterator2Collection.toCollection(edges.getExceptionalPredecessors(N));
}
public Collection<IBasicBlock> getNormalPredecessors(final IBasicBlock N) {
public Collection<T> getNormalPredecessors(final T N) {
return Iterator2Collection.toCollection(edges.getNormalPredecessors(N));
}
public IBasicBlock entry() {
public T entry() {
return cfg.entry();
}
public IBasicBlock exit() {
public T exit() {
return cfg.exit();
}
public IBasicBlock getBlockForInstruction(int index) {
public T getBlockForInstruction(int index) {
return cfg.getBlockForInstruction(index);
}

View File

@ -15,7 +15,6 @@ import java.util.Collections;
import java.util.Map;
import java.util.Set;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
import com.ibm.wala.dataflow.graph.BitVectorFramework;
import com.ibm.wala.dataflow.graph.BitVectorIdentity;
@ -37,7 +36,10 @@ import com.ibm.wala.ipa.modref.ExtendedHeapModel;
import com.ibm.wala.ipa.modref.ModRef;
import com.ibm.wala.ipa.slicer.HeapStatement.ReturnCaller;
import com.ibm.wala.ipa.slicer.Statement.Kind;
import com.ibm.wala.ssa.*;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.analysis.ExplodedControlFlowGraph;
import com.ibm.wala.ssa.analysis.ExplodedControlFlowGraph.ExplodedBasicBlock;
import com.ibm.wala.util.collections.Filter;
@ -122,12 +124,12 @@ public class HeapReachingDefs {
Map<Integer, NormalStatement> ssaInstructionIndex2Statement = mapInstructionsToStatements(domain);
// solve reaching definitions as a dataflow problem
BitVectorFramework<IBasicBlock, Statement> rd = new BitVectorFramework<IBasicBlock, Statement>(cfg, new RD(node, cfg, pa,
BitVectorFramework<ISSABasicBlock, Statement> rd = new BitVectorFramework<ISSABasicBlock, Statement>(cfg, new RD(node, cfg, pa,
domain, ssaInstructionIndex2Statement, exclusions), domain);
if (VERBOSE) {
System.err.println("Solve ");
}
BitVectorSolver<IBasicBlock> solver = new BitVectorSolver<IBasicBlock>(rd);
BitVectorSolver<ISSABasicBlock> solver = new BitVectorSolver<ISSABasicBlock>(rd);
solver.solve();
if (VERBOSE) {
System.err.println("Solved. ");
@ -143,7 +145,7 @@ public class HeapReachingDefs {
private final CallGraph cg;
RDMap(BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
RDMap(BitVectorSolver<ISSABasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
if (VERBOSE) {
@ -161,7 +163,7 @@ public class HeapReachingDefs {
}
}
private void eagerPopulate(Map<PointerKey, MutableIntSet> pointerKeyMod, BitVectorSolver<IBasicBlock> solver,
private void eagerPopulate(Map<PointerKey, MutableIntSet> pointerKeyMod, BitVectorSolver<ISSABasicBlock> solver,
OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa,
Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
Map<Integer, NormalStatement> ssaInstruction2Statement) {
@ -287,7 +289,7 @@ public class HeapReachingDefs {
* value read by s.
*/
OrdinalSet<Statement> computeResult(Statement s, Map<PointerKey, MutableIntSet> pointerKeyMod,
BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
BitVectorSolver<ISSABasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
Map<Integer, NormalStatement> ssaInstructionIndex2Statement) {
switch (s.getKind()) {
@ -295,7 +297,7 @@ public class HeapReachingDefs {
NormalStatement n = (NormalStatement) s;
Collection<PointerKey> ref = modRef.getRef(node, h, pa, n.getInstruction(), exclusions);
if (!ref.isEmpty()) {
IBasicBlock bb = cfg.getBlockForInstruction(n.getInstructionIndex());
ISSABasicBlock bb = cfg.getBlockForInstruction(n.getInstructionIndex());
BitVectorVariable v = solver.getIn(bb);
MutableSparseIntSet defs = new MutableSparseIntSet();
for (PointerKey p : ref) {
@ -318,7 +320,7 @@ public class HeapReachingDefs {
}
case HEAP_RET_CALLER: {
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) s;
IBasicBlock bb = cfg.getBlockForInstruction(r.getCallIndex());
ISSABasicBlock bb = cfg.getBlockForInstruction(r.getCallIndex());
BitVectorVariable v = solver.getIn(bb);
if (allCalleesMod(cg, r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) {
// do nothing ... force flow into and out of the callees
@ -332,7 +334,7 @@ public class HeapReachingDefs {
case HEAP_PARAM_CALLER: {
HeapStatement.ParamCaller r = (HeapStatement.ParamCaller) s;
NormalStatement call = ssaInstructionIndex2Statement.get(r.getCallIndex());
IBasicBlock callBlock = cfg.getBlockForInstruction(call.getInstructionIndex());
ISSABasicBlock callBlock = cfg.getBlockForInstruction(call.getInstructionIndex());
BitVectorVariable v = solver.getIn(callBlock);
if (pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) {
// do nothing ... force flow into and out of the callees
@ -368,7 +370,7 @@ public class HeapReachingDefs {
* For each statement s, compute the set of statements that may def the heap
* value read by s.
*/
private Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<IBasicBlock> solver,
private Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<ISSABasicBlock> solver,
OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa,
Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
@ -446,7 +448,7 @@ public class HeapReachingDefs {
/**
* Reaching def flow functions
*/
private class RD implements ITransferFunctionProvider<IBasicBlock, BitVectorVariable> {
private class RD implements ITransferFunctionProvider<ISSABasicBlock, BitVectorVariable> {
private final CGNode node;
@ -493,7 +495,7 @@ public class HeapReachingDefs {
}
}
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(IBasicBlock src, IBasicBlock dst) {
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(ISSABasicBlock src, ISSABasicBlock dst) {
ExplodedBasicBlock s = (ExplodedBasicBlock) src;
if (s.getInstruction() != null && !(s.getInstruction() instanceof SSAAbstractInvokeInstruction)
&& !cfg.getNormalSuccessors(src).contains(dst)) {
@ -524,7 +526,7 @@ public class HeapReachingDefs {
return BitVectorUnion.instance();
}
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(IBasicBlock node) {
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(ISSABasicBlock node) {
Assertions.UNREACHABLE();
return null;
}

View File

@ -37,6 +37,7 @@ import com.ibm.wala.ipa.slicer.Statement.Kind;
import com.ibm.wala.shrikeBT.IInstruction;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayReferenceInstruction;
@ -167,7 +168,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
if (ir == null) {
return;
}
ControlFlowGraph controlFlowGraph = ir.getControlFlowGraph();
ControlFlowGraph<ISSABasicBlock> controlFlowGraph = ir.getControlFlowGraph();
if (cOptions.equals(ControlDependenceOptions.NO_EXCEPTIONAL_EDGES)) {
controlFlowGraph = ExceptionPrunedCFG.make(controlFlowGraph);
// In case the CFG has no nodes left because the only control dependencies
@ -181,8 +182,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
Assertions.productionAssertion(cOptions.equals(ControlDependenceOptions.FULL));
}
ControlDependenceGraph cdg = new ControlDependenceGraph(controlFlowGraph);
for (IBasicBlock bb : cdg) {
ControlDependenceGraph<ISSABasicBlock> cdg = new ControlDependenceGraph<ISSABasicBlock>(controlFlowGraph);
for (ISSABasicBlock bb : cdg) {
if (bb.isExitBlock()) {
// nothing should be control-dependent on the exit block.
continue;
@ -234,8 +235,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
// the CDG does not represent control dependences from the entry node.
// add these manually
Statement methodEntry = new MethodEntryStatement(node);
for (Iterator<? extends IBasicBlock> it = cdg.iterator(); it.hasNext();) {
IBasicBlock bb = it.next();
for (Iterator<? extends ISSABasicBlock> it = cdg.iterator(); it.hasNext();) {
ISSABasicBlock bb = it.next();
if (cdg.getPredNodeCount(bb) == 0) {
// this is control dependent on the method entry.
for (IInstruction s : bb) {

View File

@ -32,13 +32,13 @@ public class SDGView implements ISDG {
private final ISDG delegate;
private final Filter notExcluded;
private final Filter<Statement> notExcluded;
public SDGView(final ISDG sdg, final Collection<Statement> exclusions) {
super();
this.delegate = sdg;
this.notExcluded = new Filter() {
public boolean accepts(Object o) {
this.notExcluded = new Filter<Statement>() {
public boolean accepts(Statement o) {
return !exclusions.contains(o);
}
};

View File

@ -13,7 +13,6 @@ package com.ibm.wala.ssa;
import java.util.Iterator;
import java.util.Map;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.NewSiteReference;
@ -81,7 +80,7 @@ public abstract class IR {
/**
* Mapping from SSAInstruction to Basic Block, computed lazily
*/
private Map<SSAInstruction, IBasicBlock> instruction2Block;
private Map<SSAInstruction, ISSABasicBlock> instruction2Block;
/**
* subclasses must provide a source name mapping, if they want one
@ -152,7 +151,7 @@ public abstract class IR {
result.append(cfg.toString());
result.append("Instructions:\n");
for (int i = 0; i <= cfg.getMaxNumber(); i++) {
BasicBlock bb = (BasicBlock) cfg.getNode(i);
BasicBlock bb = cfg.getNode(i);
int start = bb.getFirstInstructionIndex();
int end = bb.getLastInstructionIndex();
result.append("BB").append(bb.getNumber());
@ -257,7 +256,7 @@ public abstract class IR {
@SuppressWarnings("unchecked")
DerivedNodeIterator() {
currentBlockIndex = 0;
currentBlockIterator = ((BasicBlock) cfg.getNode(0)).iteratePhis();
currentBlockIterator = cfg.getNode(0).iteratePhis();
if (!currentBlockIterator.hasNext()) {
advanceBlock();
}
@ -281,7 +280,7 @@ public abstract class IR {
private void advanceBlock() {
for (int i = currentBlockIndex + 1; i <= cfg.getMaxNumber(); i++) {
Iterator<? extends SSAInstruction> it = getBlockIterator((BasicBlock) cfg.getNode(i));
Iterator<? extends SSAInstruction> it = getBlockIterator(cfg.getNode(i));
if (it.hasNext()) {
currentBlockIndex = i;
currentBlockIterator = it;
@ -566,12 +565,12 @@ public abstract class IR {
* @return the basic block corresponding to this instruction
* @throws IllegalArgumentException if site is null
*/
public IBasicBlock[] getBasicBlocksForCall(final CallSiteReference site) {
public ISSABasicBlock[] getBasicBlocksForCall(final CallSiteReference site) {
if (site == null) {
throw new IllegalArgumentException("site is null");
}
final IntSet s = callSiteMapping.getRelated(site.getProgramCounter());
final IBasicBlock[] result = new IBasicBlock[s.size()];
final ISSABasicBlock[] result = new ISSABasicBlock[s.size()];
int index = 0;
for (final IntIterator it = s.intIterator(); it.hasNext();) {
final int i = it.next();
@ -586,7 +585,7 @@ public abstract class IR {
* Be very careful; note the strange identity semantics of SSAInstruction,
* using ==. You can't mix SSAInstructions and IRs freely.
*/
public IBasicBlock getBasicBlockForInstruction(SSAInstruction s) {
public ISSABasicBlock getBasicBlockForInstruction(SSAInstruction s) {
if (instruction2Block == null) {
mapInstructions2Blocks();
}
@ -595,7 +594,7 @@ public abstract class IR {
private void mapInstructions2Blocks() {
instruction2Block = HashMapFactory.make();
for (IBasicBlock b : cfg) {
for (ISSABasicBlock b : cfg) {
for (IInstruction s : b) {
instruction2Block.put((SSAInstruction)s, b);
}
@ -656,7 +655,7 @@ public abstract class IR {
}
public IBasicBlock getBasicBlockForCatch(SSAGetCaughtExceptionInstruction instruction) {
public ISSABasicBlock getBasicBlockForCatch(SSAGetCaughtExceptionInstruction instruction) {
if (instruction == null) {
throw new IllegalArgumentException("instruction is null");
}

View File

@ -130,7 +130,7 @@ public class SSABuilder extends AbstractIntStackMachine {
// didn't find anything but TOP
return TOP;
} else {
SSACFG.BasicBlock newBB = (com.ibm.wala.ssa.SSACFG.BasicBlock) cfg.getNode(shrikeCFG.getNumber(bb));
SSACFG.BasicBlock newBB = cfg.getNode(shrikeCFG.getNumber(bb));
// if we already have a phi for this stack location
SSAPhiInstruction phi = newBB.getPhiForStackSlot(slot);
int result;
@ -164,7 +164,7 @@ public class SSABuilder extends AbstractIntStackMachine {
// didn't find anything but TOP
return TOP;
} else {
SSACFG.BasicBlock newBB = (com.ibm.wala.ssa.SSACFG.BasicBlock) cfg.getNode(shrikeCFG.getNumber(bb));
SSACFG.BasicBlock newBB = cfg.getNode(shrikeCFG.getNumber(bb));
if (bb.isExitBlock()) {
// no phis in exit block please
return TOP;

View File

@ -50,7 +50,7 @@ import com.ibm.wala.util.warnings.Warnings;
* @author sfink
*/
public class SSACFG implements ControlFlowGraph {
public class SSACFG implements ControlFlowGraph<ISSABasicBlock> {
private static final boolean DEBUG = false;
@ -60,7 +60,7 @@ public class SSACFG implements ControlFlowGraph {
final protected IMethod method;
final protected AbstractCFG cfg;
final protected AbstractCFG<IBasicBlock> cfg;
/**
* cache a ref to the exit block for efficient access
@ -78,6 +78,7 @@ public class SSACFG implements ControlFlowGraph {
* @throws IllegalArgumentException
* if method is null
*/
@SuppressWarnings("unchecked")
public SSACFG(IMethod method, AbstractCFG cfg, SSAInstruction[] instructions) {
if (method == null) {
@ -686,7 +687,7 @@ public class SSACFG implements ControlFlowGraph {
public String toString() {
StringBuffer s = new StringBuffer("");
for (int i = 0; i <= getNumber(exit()); i++) {
BasicBlock bb = (BasicBlock) getNode(i);
BasicBlock bb = getNode(i);
s.append("BB").append(i).append("[").append(bb.getFirstInstructionIndex()).append("..").append(bb.getLastInstructionIndex())
.append("]\n");
@ -728,7 +729,7 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedGraph#getNumber(com.ibm.wala.util.graph.Node)
*/
public int getNumber(IBasicBlock N) throws IllegalArgumentException {
public int getNumber(ISSABasicBlock N) throws IllegalArgumentException {
if (N == null) {
throw new IllegalArgumentException("N == null");
}
@ -739,7 +740,7 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedGraph#getNode(int)
*/
public IBasicBlock getNode(int number) {
public BasicBlock getNode(int number) {
return basicBlocks[number];
}
@ -753,9 +754,9 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#iterateNodes()
*/
public Iterator<IBasicBlock> iterator() {
ArrayList<IBasicBlock> list = new ArrayList<IBasicBlock>();
for (IBasicBlock b : basicBlocks) {
public Iterator<ISSABasicBlock> iterator() {
ArrayList<ISSABasicBlock> list = new ArrayList<ISSABasicBlock>();
for (BasicBlock b : basicBlocks) {
list.add(b);
}
return list.iterator();
@ -771,18 +772,18 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#getPredNodes(com.ibm.wala.util.graph.Node)
*/
public Iterator<IBasicBlock> getPredNodes(IBasicBlock b) throws IllegalArgumentException {
public Iterator<ISSABasicBlock> getPredNodes(ISSABasicBlock b) throws IllegalArgumentException {
if (b == null) {
throw new IllegalArgumentException("b == null");
}
IBasicBlock n = cfg.getNode(b.getNumber());
final Iterator i = cfg.getPredNodes(n);
return new Iterator<IBasicBlock>() {
return new Iterator<ISSABasicBlock>() {
public boolean hasNext() {
return i.hasNext();
}
public IBasicBlock next() {
public BasicBlock next() {
IBasicBlock n = (IBasicBlock) i.next();
int number = n.getNumber();
return basicBlocks[number];
@ -797,7 +798,7 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#getPredNodeCount(com.ibm.wala.util.graph.Node)
*/
public int getPredNodeCount(IBasicBlock b) throws IllegalArgumentException {
public int getPredNodeCount(ISSABasicBlock b) throws IllegalArgumentException {
if (b == null) {
throw new IllegalArgumentException("b == null");
}
@ -808,18 +809,18 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#getSuccNodes(com.ibm.wala.util.graph.Node)
*/
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock b) throws IllegalArgumentException {
public Iterator<ISSABasicBlock> getSuccNodes(ISSABasicBlock b) throws IllegalArgumentException {
if (b == null) {
throw new IllegalArgumentException("b == null");
}
IBasicBlock n = cfg.getNode(b.getNumber());
final Iterator i = cfg.getSuccNodes(n);
return new Iterator<IBasicBlock>() {
return new Iterator<ISSABasicBlock>() {
public boolean hasNext() {
return i.hasNext();
}
public IBasicBlock next() {
public ISSABasicBlock next() {
IBasicBlock n = (IBasicBlock) i.next();
int number = n.getNumber();
return basicBlocks[number];
@ -834,7 +835,7 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#getSuccNodeCount(com.ibm.wala.util.graph.Node)
*/
public int getSuccNodeCount(IBasicBlock b) throws IllegalArgumentException {
public int getSuccNodeCount(ISSABasicBlock b) throws IllegalArgumentException {
if (b == null) {
throw new IllegalArgumentException("b == null");
}
@ -845,36 +846,36 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedGraph#addNode(com.ibm.wala.util.graph.Node)
*/
public void addNode(IBasicBlock n) throws UnsupportedOperationException {
public void addNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void addEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void addEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void removeEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* @see com.ibm.wala.util.graph.EdgeManager#removeEdges(com.ibm.wala.util.graph.Node)
*/
public void removeAllIncidentEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeAllIncidentEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* @see com.ibm.wala.util.graph.Graph#removeNode(com.ibm.wala.util.graph.Node)
*/
public void removeNodeAndEdges(IBasicBlock N) throws UnsupportedOperationException {
public void removeNodeAndEdges(ISSABasicBlock N) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/*
* @see com.ibm.wala.util.graph.NodeManager#remove(com.ibm.wala.util.graph.Node)
*/
public void removeNode(IBasicBlock n) throws UnsupportedOperationException {
public void removeNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@ -889,7 +890,7 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.Graph#containsNode(com.ibm.wala.util.graph.Node)
*/
public boolean containsNode(IBasicBlock N) {
public boolean containsNode(ISSABasicBlock N) {
if (N instanceof BasicBlock) {
return basicBlocks[getNumber(N)] == N;
} else {
@ -907,13 +908,13 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
*/
public Collection<IBasicBlock> getExceptionalSuccessors(final IBasicBlock b) {
public Collection<ISSABasicBlock> getExceptionalSuccessors(final ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
final IBasicBlock n = cfg.getNode(b.getNumber());
final Iterator i = cfg.getExceptionalSuccessors(n).iterator();
final Collection<IBasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
final Collection<ISSABasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
for (; i.hasNext();) {
final IBasicBlock s = (IBasicBlock) i.next();
c.add(basicBlocks[cfg.getNumber(s)]);
@ -924,17 +925,17 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
*/
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getExceptionalPredecessors(ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
IBasicBlock n = cfg.getNode(b.getNumber());
Function<IBasicBlock, IBasicBlock> f = new Function<IBasicBlock, IBasicBlock>() {
public IBasicBlock apply(IBasicBlock object) {
Function<IBasicBlock, ISSABasicBlock> f = new Function<IBasicBlock, ISSABasicBlock>() {
public ISSABasicBlock apply(IBasicBlock object) {
return basicBlocks[cfg.getNumber(object)];
}
};
return Iterator2Collection.toCollection(new MapIterator<IBasicBlock, IBasicBlock>(cfg.getExceptionalPredecessors(n).iterator(),
return Iterator2Collection.toCollection(new MapIterator<IBasicBlock, ISSABasicBlock>(cfg.getExceptionalPredecessors(n).iterator(),
f));
}
@ -944,7 +945,7 @@ public class SSACFG implements ControlFlowGraph {
* @throws IllegalArgumentException
* if dest is null
*/
public boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dest) {
public boolean hasExceptionalEdge(BasicBlock src, BasicBlock dest) {
if (dest == null) {
throw new IllegalArgumentException("dest is null");
}
@ -952,6 +953,7 @@ public class SSACFG implements ControlFlowGraph {
int srcNum = getNumber(src);
return cfg.getExceptionalToExit().get(srcNum);
}
// this is horrible and fragile
return cfg.hasExceptionalEdge(src, dest);
}
@ -961,7 +963,7 @@ public class SSACFG implements ControlFlowGraph {
* @throws IllegalArgumentException
* if dest is null
*/
public boolean hasNormalEdge(IBasicBlock src, IBasicBlock dest) {
public boolean hasNormalEdge(BasicBlock src, BasicBlock dest) {
if (dest == null) {
throw new IllegalArgumentException("dest is null");
}
@ -969,19 +971,20 @@ public class SSACFG implements ControlFlowGraph {
int srcNum = getNumber(src);
return cfg.getNormalToExit().get(srcNum);
}
// this is horrible and fragile.
return cfg.hasNormalEdge(src, dest);
}
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.IBasicBlock)
*/
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getNormalSuccessors(ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
IBasicBlock n = cfg.getNode(b.getNumber());
final Iterator i = cfg.getNormalSuccessors(n).iterator();
Collection<IBasicBlock> c = new ArrayList<IBasicBlock>(getSuccNodeCount(b));
Collection<ISSABasicBlock> c = new ArrayList<ISSABasicBlock>(getSuccNodeCount(b));
for (; i.hasNext();) {
IBasicBlock s = (IBasicBlock) i.next();
c.add(basicBlocks[cfg.getNumber(s)]);
@ -992,13 +995,13 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.IBasicBlock)
*/
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getNormalPredecessors(ISSABasicBlock b) {
if (b == null) {
throw new IllegalArgumentException("b is null");
}
IBasicBlock n = cfg.getNode(b.getNumber());
final Iterator i = cfg.getNormalPredecessors(n).iterator();
Collection<IBasicBlock> c = new ArrayList<IBasicBlock>(getPredNodeCount(b));
Collection<ISSABasicBlock> c = new ArrayList<ISSABasicBlock>(getPredNodeCount(b));
for (; i.hasNext();) {
IBasicBlock s = (IBasicBlock) i.next();
c.add(basicBlocks[cfg.getNumber(s)]);
@ -1009,23 +1012,23 @@ public class SSACFG implements ControlFlowGraph {
/*
* @see com.ibm.wala.util.graph.NumberedNodeManager#iterateNodes(com.ibm.wala.util.intset.IntSet)
*/
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
return new NumberedNodeIterator<IBasicBlock>(s, this);
public Iterator<ISSABasicBlock> iterateNodes(IntSet s) {
return new NumberedNodeIterator<ISSABasicBlock>(s, this);
}
public void removeIncomingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeIncomingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeOutgoingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) throws UnimplementedError {
public boolean hasEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnimplementedError {
return getSuccNodeNumbers(src).contains(getNumber(dst));
}
public IntSet getSuccNodeNumbers(IBasicBlock node) throws IllegalArgumentException {
public IntSet getSuccNodeNumbers(ISSABasicBlock node) throws IllegalArgumentException {
if (node == null) {
throw new IllegalArgumentException("node == null");
}
@ -1034,7 +1037,7 @@ public class SSACFG implements ControlFlowGraph {
return cfg.getSuccNodeNumbers(n);
}
public IntSet getPredNodeNumbers(IBasicBlock node) throws UnimplementedError {
public IntSet getPredNodeNumbers(ISSABasicBlock node) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}

View File

@ -18,7 +18,6 @@ import java.util.Iterator;
import java.util.List;
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.ssa.IR;
@ -44,7 +43,7 @@ import com.ibm.wala.util.intset.SimpleVector;
*
* Prototype: Not terribly efficient.
*/
public class ExplodedControlFlowGraph implements ControlFlowGraph {
public class ExplodedControlFlowGraph implements ControlFlowGraph<ISSABasicBlock> {
private final IR ir;
@ -52,9 +51,9 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
* The ith element of this vector is the basic block holding instruction i.
* this basic block has number i+1.
*/
private final SimpleVector<IBasicBlock> normalNodes = new SimpleVector<IBasicBlock>();
private final SimpleVector<ISSABasicBlock> normalNodes = new SimpleVector<ISSABasicBlock>();
private final Collection<IBasicBlock> allNodes = HashSetFactory.make();
private final Collection<ISSABasicBlock> allNodes = HashSetFactory.make();
private final ExplodedBasicBlock entry;
@ -70,9 +69,9 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
private void createNodes() {
allNodes.add(entry);
allNodes.add(exit);
for (IBasicBlock b : ir.getControlFlowGraph()) {
for (ISSABasicBlock b : ir.getControlFlowGraph()) {
for (int i = b.getFirstInstructionIndex(); i <= b.getLastInstructionIndex(); i++) {
ExplodedBasicBlock bb = new ExplodedBasicBlock(i, (ISSABasicBlock) b);
ExplodedBasicBlock bb = new ExplodedBasicBlock(i, b);
normalNodes.set(i, bb);
allNodes.add(bb);
}
@ -83,15 +82,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return new ExplodedControlFlowGraph(ir);
}
public IBasicBlock entry() {
public ISSABasicBlock entry() {
return entry;
}
public IBasicBlock exit() {
public ISSABasicBlock exit() {
return exit;
}
public IBasicBlock getBlockForInstruction(int index) {
public ISSABasicBlock getBlockForInstruction(int index) {
return normalNodes.get(index);
}
@ -109,15 +108,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return result;
}
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getExceptionalPredecessors(ISSABasicBlock b) {
assert b != null;
if (b.equals(entry)) {
return Collections.emptySet();
}
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
if (eb.isExitBlock() || eb.instructionIndex == eb.original.getFirstInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (IBasicBlock s : ir.getControlFlowGraph().getExceptionalPredecessors(eb.original)) {
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (ISSABasicBlock s : ir.getControlFlowGraph().getExceptionalPredecessors(eb.original)) {
assert normalNodes.get(s.getLastInstructionIndex()) != null;
result.add(normalNodes.get(s.getLastInstructionIndex()));
}
@ -127,15 +126,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
assert b != null;
if (b.equals(exit)) {
return Collections.emptySet();
}
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (IBasicBlock s : ir.getControlFlowGraph().getExceptionalSuccessors(eb.original)) {
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (ISSABasicBlock s : ir.getControlFlowGraph().getExceptionalSuccessors(eb.original)) {
if (s.equals(ir.getControlFlowGraph().exit())) {
result.add(exit());
} else {
@ -158,15 +157,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return null;
}
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getNormalPredecessors(ISSABasicBlock b) {
assert b != null;
if (b.equals(entry)) {
return Collections.emptySet();
}
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
if (eb.isExitBlock() || eb.instructionIndex == eb.original.getFirstInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (IBasicBlock s : ir.getControlFlowGraph().getNormalPredecessors(eb.original)) {
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (ISSABasicBlock s : ir.getControlFlowGraph().getNormalPredecessors(eb.original)) {
if (s.equals(ir.getControlFlowGraph().entry())) {
result.add(entry());
} else {
@ -181,15 +180,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
public Collection<ISSABasicBlock> getNormalSuccessors(ISSABasicBlock b) {
assert b != null;
if (b.equals(exit)) {
return Collections.emptySet();
}
ExplodedBasicBlock eb = (ExplodedBasicBlock) b;
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (IBasicBlock s : ir.getControlFlowGraph().getNormalSuccessors(eb.original)) {
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (ISSABasicBlock s : ir.getControlFlowGraph().getNormalSuccessors(eb.original)) {
if (s.equals(ir.getControlFlowGraph().exit())) {
result.add(exit());
} else {
@ -209,15 +208,15 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return 0;
}
public void removeNodeAndEdges(IBasicBlock N) throws UnsupportedOperationException {
public void removeNodeAndEdges(ISSABasicBlock N) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void addNode(IBasicBlock n) throws UnsupportedOperationException {
public void addNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public boolean containsNode(IBasicBlock N) {
public boolean containsNode(ISSABasicBlock N) {
return allNodes.contains(N);
}
@ -225,19 +224,19 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return allNodes.size();
}
public Iterator<IBasicBlock> iterator() {
public Iterator<ISSABasicBlock> iterator() {
return allNodes.iterator();
}
public void removeNode(IBasicBlock n) throws UnsupportedOperationException {
public void removeNode(ISSABasicBlock n) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void addEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void addEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public int getPredNodeCount(IBasicBlock N) throws IllegalArgumentException {
public int getPredNodeCount(ISSABasicBlock N) throws IllegalArgumentException {
if (N == null) {
throw new IllegalArgumentException("N == null");
}
@ -252,7 +251,7 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public Iterator<? extends IBasicBlock> getPredNodes(IBasicBlock N) throws IllegalArgumentException {
public Iterator<? extends ISSABasicBlock> getPredNodes(ISSABasicBlock N) throws IllegalArgumentException {
if (N == null) {
throw new IllegalArgumentException("N == null");
}
@ -261,9 +260,9 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return EmptyIterator.instance();
}
if (b.equals(exit) || b.instructionIndex == b.original.getFirstInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (Iterator<IBasicBlock> it = ir.getControlFlowGraph().getPredNodes(b.original); it.hasNext();) {
IBasicBlock s = it.next();
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (Iterator<ISSABasicBlock> it = ir.getControlFlowGraph().getPredNodes(b.original); it.hasNext();) {
ISSABasicBlock s = it.next();
if (s.isEntryBlock()) {
result.add(entry);
} else {
@ -278,21 +277,21 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public int getSuccNodeCount(IBasicBlock N) throws UnimplementedError {
public int getSuccNodeCount(ISSABasicBlock N) throws UnimplementedError {
Assertions.UNREACHABLE();
return 0;
}
public Iterator<? extends IBasicBlock> getSuccNodes(IBasicBlock N) {
public Iterator<? extends ISSABasicBlock> getSuccNodes(ISSABasicBlock N) {
assert N != null;
if (N.equals(exit)) {
return EmptyIterator.instance();
}
ExplodedBasicBlock b = (ExplodedBasicBlock) N;
if (b.isEntryBlock() || b.instructionIndex == b.original.getLastInstructionIndex()) {
List<IBasicBlock> result = new ArrayList<IBasicBlock>();
for (Iterator<IBasicBlock> it = ir.getControlFlowGraph().getSuccNodes(b.original); it.hasNext();) {
IBasicBlock s = it.next();
List<ISSABasicBlock> result = new ArrayList<ISSABasicBlock>();
for (Iterator<ISSABasicBlock> it = ir.getControlFlowGraph().getSuccNodes(b.original); it.hasNext();) {
ISSABasicBlock s = it.next();
if (s.equals(ir.getControlFlowGraph().exit())) {
result.add(exit());
} else {
@ -307,25 +306,25 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) throws UnimplementedError {
public boolean hasEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnimplementedError {
Assertions.UNREACHABLE();
return false;
}
public void removeAllIncidentEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeAllIncidentEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeEdge(IBasicBlock src, IBasicBlock dst) throws UnsupportedOperationException {
public void removeEdge(ISSABasicBlock src, ISSABasicBlock dst) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeIncomingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(IBasicBlock node) throws UnsupportedOperationException {
public void removeOutgoingEdges(ISSABasicBlock node) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@ -333,7 +332,7 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
return getNumberOfNodes() - 1;
}
public IBasicBlock getNode(int number) {
public ISSABasicBlock getNode(int number) {
if (number == 0) {
return entry();
} else if (number == getNumberOfNodes() - 1) {
@ -343,27 +342,27 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph {
}
}
public int getNumber(IBasicBlock n) throws IllegalArgumentException {
public int getNumber(ISSABasicBlock n) throws IllegalArgumentException {
if (n == null) {
throw new IllegalArgumentException("n == null");
}
return n.getNumber();
}
public Iterator<IBasicBlock> iterateNodes(IntSet s) throws UnimplementedError {
public Iterator<ISSABasicBlock> iterateNodes(IntSet s) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
public IntSet getPredNodeNumbers(IBasicBlock node) {
public IntSet getPredNodeNumbers(ISSABasicBlock node) {
MutableSparseIntSet result = new MutableSparseIntSet();
for (Iterator<? extends IBasicBlock> it = getPredNodes(node); it.hasNext();) {
for (Iterator<? extends ISSABasicBlock> it = getPredNodes(node); it.hasNext();) {
result.add(getNumber(it.next()));
}
return result;
}
public IntSet getSuccNodeNumbers(IBasicBlock node) throws UnimplementedError {
public IntSet getSuccNodeNumbers(ISSABasicBlock node) throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}

View File

@ -22,19 +22,19 @@ import com.ibm.wala.util.collections.Filter;
*
* @author sfink
*/
public class CollectionFilter implements Filter {
public class CollectionFilter<T> implements Filter<T> {
@NonNull
private final Collection<? extends Object> S;
private final Collection<? extends T> S;
public CollectionFilter(Collection<? extends Object> S) {
public CollectionFilter(Collection<? extends T> S) {
this.S = S;
}
/*
* @see com.ibm.wala.util.Filter#accepts(java.lang.Object)
*/
public boolean accepts(Object o) {
public boolean accepts(T o) {
return S.contains(o);
}

View File

@ -19,12 +19,10 @@ import com.ibm.wala.util.collections.Filter;
*
* @author sfink
*/
public class IndiscriminateFilter implements Filter {
public class IndiscriminateFilter<T> implements Filter<T> {
private final static IndiscriminateFilter INSTANCE = new IndiscriminateFilter();
public static IndiscriminateFilter singleton() {
return INSTANCE;
public static <T> IndiscriminateFilter singleton() {
return new IndiscriminateFilter<T>();
}
/*

View File

@ -16,10 +16,10 @@ package com.ibm.wala.util.collections;
*
* @author sfink
*/
public interface Filter {
public interface Filter<T> {
/**
* @param o
* @return true iff o is in the set defined by this filter
*/
public boolean accepts(Object o);
public boolean accepts(T o);
}

View File

@ -18,18 +18,18 @@ import com.ibm.wala.annotations.NonNull;
*
* @author sfink
*/
public class Filtersection implements Filter {
public class Filtersection<T> implements Filter<T> {
@NonNull
final private Filter a;
final private Filter b;
final private Filter<T> a;
final private Filter<T> b;
public Filtersection(Filter a, Filter b) {
public Filtersection(Filter<T> a, Filter<T> b) {
this.a = a;
this.b = b;
}
public boolean accepts(Object o) {
public boolean accepts(T o) {
return a.accepts(o) && b.accepts(o);
}

View File

@ -28,7 +28,7 @@ import com.ibm.wala.util.warnings.WalaException;
*/
public class GraphSlicer {
public static <T> Collection<T> slice(Graph<T> g, Filter f) throws WalaException {
public static <T> Collection<T> slice(Graph<T> g, Filter<T> f) throws WalaException {
if (g == null) {
throw new IllegalArgumentException("g is null");
@ -47,7 +47,7 @@ public class GraphSlicer {
}
public static <T> Graph<T> prune(final Graph<T> g, final Filter f) {
public static <T> Graph<T> prune(final Graph<T> g, final Filter<T> f) {
final NodeManager<T> n = new NodeManager<T>() {

View File

@ -49,7 +49,7 @@ public class BFSPathFinder<T> {
/**
* The Filter which defines the target set of nodes to find
*/
final private Filter filter;
final private Filter<T> filter;
/**
* an enumeration of all nodes to search from
@ -63,7 +63,7 @@ public class BFSPathFinder<T> {
* @param G
* the graph whose nodes to enumerate
*/
public BFSPathFinder(Graph<T> G, T N, Filter f) {
public BFSPathFinder(Graph<T> G, T N, Filter<T> f) {
this.G = G;
this.roots = new NonNullSingletonIterator<T>(N);
this.filter = f;
@ -86,8 +86,8 @@ public class BFSPathFinder<T> {
if (!G.containsNode(src)) {
throw new IllegalArgumentException("src is not in graph " + src);
}
this.filter = new Filter() {
public boolean accepts(Object o) {
this.filter = new Filter<T>() {
public boolean accepts(T o) {
return target.equals(o);
}
};
@ -109,8 +109,8 @@ public class BFSPathFinder<T> {
this.G = G;
this.roots = new NonNullSingletonIterator<T>(src);
this.filter = new Filter() {
public boolean accepts(Object o) {
this.filter = new Filter<T>() {
public boolean accepts(T o) {
return ts.contains(o);
}
};
@ -126,8 +126,8 @@ public class BFSPathFinder<T> {
public BFSPathFinder(Graph<T> G, Iterator<T> sources, final T target) {
this.G = G;
this.roots = sources;
this.filter = new Filter() {
public boolean accepts(Object o) {
this.filter = new Filter<T>() {
public boolean accepts(T o) {
return target.equals(o);
}
};
@ -140,7 +140,7 @@ public class BFSPathFinder<T> {
* @param nodes
* the set of nodes from which to start searching
*/
public BFSPathFinder(Graph<T> G, Iterator<T> nodes, Filter f) {
public BFSPathFinder(Graph<T> G, Iterator<T> nodes, Filter<T> f) {
this.G = G;
this.roots = nodes;
this.filter = f;

View File

@ -45,7 +45,7 @@ public class DFSPathFinder<T> extends Stack<T> {
/**
* The Filter which defines the target set of nodes to find
*/
final private Filter filter;
final private Filter<T> filter;
/**
* an enumeration of all nodes to search from
@ -64,7 +64,7 @@ public class DFSPathFinder<T> extends Stack<T> {
* @param G the graph whose nodes to enumerate
* @throws IllegalArgumentException if G is null
*/
public DFSPathFinder(Graph<T> G, T N, Filter f) throws IllegalArgumentException {
public DFSPathFinder(Graph<T> G, T N, Filter<T> f) throws IllegalArgumentException {
if (G == null) {
throw new IllegalArgumentException("G is null");
}
@ -83,7 +83,7 @@ public class DFSPathFinder<T> extends Stack<T> {
*
* @param nodes the set of nodes from which to start searching
*/
public DFSPathFinder(Graph<T> G, Iterator<T> nodes, Filter f) {
public DFSPathFinder(Graph<T> G, Iterator<T> nodes, Filter<T> f) {
this.G = G;
this.roots = nodes;
this.filter = f;
@ -102,7 +102,7 @@ public class DFSPathFinder<T> extends Stack<T> {
setPendingChildren(n, getConnected(n));
}
while (hasNext()) {
Object n = peek();
T n = peek();
if (filter.accepts(n)) {
return currentPath();
}

View File

@ -14,9 +14,9 @@ import java.util.HashMap;
import java.util.Iterator;
import com.ibm.wala.cfg.CFGSanitizer;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSACFG;
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
import com.ibm.wala.ssa.SSAInstruction;
@ -60,7 +60,7 @@ public class GhostviewUtil {
if (ir == null) {
throw new IllegalArgumentException("ir is null");
}
Graph<IBasicBlock> g = ir.getControlFlowGraph();
Graph<? extends ISSABasicBlock> g = ir.getControlFlowGraph();
NodeDecorator labels = makeIRDecorator(ir);
if (annotations != null) {

View File

@ -14,12 +14,12 @@ import java.io.File;
import java.util.Collection;
import java.util.Properties;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.dataflow.IFDS.TabulationResult;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.properties.WalaProperties;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.Trace;
import com.ibm.wala.util.graph.InferGraphRoots;
@ -91,7 +91,7 @@ public class IFDSExplorer {
}
@SuppressWarnings("unchecked")
public String getLabel(Object o) throws WalaException {
IBasicBlock bb = (IBasicBlock)o;
ISSABasicBlock bb = (ISSABasicBlock)o;
Object b = new BasicBlockInContext(getCurrentNode(),bb);
IntSet result = r.getResult(b);
String label = result == null ? "no result" : result.toString();