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:
parent
cd78f3aa71
commit
182a53ee8f
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>() {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue