tabulation API generalization
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2532 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
84e00a667a
commit
c38525d185
|
@ -12,8 +12,6 @@ package com.ibm.wala.dataflow.IFDS;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import com.ibm.wala.util.collections.Pair;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Representation of a Dyck-language graph reachability problem for the
|
* Representation of a Dyck-language graph reachability problem for the
|
||||||
|
@ -41,10 +39,9 @@ public interface TabulationProblem<T,P> {
|
||||||
public IFlowFunctionMap<T> getFunctionMap();
|
public IFlowFunctionMap<T> getFunctionMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the set of facts that are live on entry to the analysis. Each fact represents a dataflow
|
* Define the set of path edges to start propagation with.
|
||||||
* factoid number (Integer) at a particular supergraph node (T).
|
|
||||||
*/
|
*/
|
||||||
public Collection<Pair<T,Integer>> initialSeeds();
|
public Collection<PathEdge<T>> initialSeeds();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special case: if supportsMerge(), then the problem is not really IFDS
|
* Special case: if supportsMerge(), then the problem is not really IFDS
|
||||||
|
|
|
@ -29,7 +29,6 @@ import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
import com.ibm.wala.util.collections.Heap;
|
import com.ibm.wala.util.collections.Heap;
|
||||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
|
||||||
import com.ibm.wala.util.collections.ToStringComparator;
|
import com.ibm.wala.util.collections.ToStringComparator;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
import com.ibm.wala.util.heapTrace.HeapTracer;
|
import com.ibm.wala.util.heapTrace.HeapTracer;
|
||||||
|
@ -188,8 +187,8 @@ public class TabulationSolver<T, P> {
|
||||||
* Start tabulation with the initial seeds.
|
* Start tabulation with the initial seeds.
|
||||||
*/
|
*/
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
for (Pair<T, Integer> seed : problem.initialSeeds()) {
|
for (PathEdge<T> seed : problem.initialSeeds()) {
|
||||||
propagate(seed.fst, seed.snd, seed.fst, seed.snd);
|
propagate(seed.entry, seed.d1, seed.target, seed.d2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,12 @@ package com.ibm.wala.ipa.slicer;
|
||||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A statement representing method entry, used for managing
|
* A statement representing method entry, used for managing control dependence.
|
||||||
* control dependence
|
*
|
||||||
|
* This is also used as a dummy entry for starting propagation to a seed statement.
|
||||||
*
|
*
|
||||||
* @author sjfink
|
* @author sjfink
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MethodEntryStatement extends Statement {
|
public class MethodEntryStatement extends Statement {
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public class MethodEntryStatement extends Statement {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getClass().equals(obj.getClass())) {
|
if (getClass().equals(obj.getClass())) {
|
||||||
MethodEntryStatement other = (MethodEntryStatement)obj;
|
MethodEntryStatement other = (MethodEntryStatement) obj;
|
||||||
return getNode().equals(other.getNode());
|
return getNode().equals(other.getNode());
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -40,12 +41,12 @@ public class MethodEntryStatement extends Statement {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.METHOD_ENTRY;
|
return Kind.METHOD_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return getKind().hashCode() + 9901*getNode().hashCode();
|
return getKind().hashCode() + 9901 * getNode().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -119,14 +119,11 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
private boolean isPopulated = false;
|
private boolean isPopulated = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mod
|
* @param mod the set of heap locations which may be written (transitively) by this node. These are logically return
|
||||||
* the set of heap locations which may be written (transitively) by this node. These are logically return
|
* values in the SDG.
|
||||||
* values in the SDG.
|
* @param ref the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
||||||
* @param ref
|
* in the SDG.
|
||||||
* the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
* @throws IllegalArgumentException if node is null
|
||||||
* in the SDG.
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if node is null
|
|
||||||
*/
|
*/
|
||||||
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
|
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
|
||||||
|
@ -135,14 +132,11 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mod
|
* @param mod the set of heap locations which may be written (transitively) by this node. These are logically return
|
||||||
* the set of heap locations which may be written (transitively) by this node. These are logically return
|
* values in the SDG.
|
||||||
* values in the SDG.
|
* @param ref the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
||||||
* @param ref
|
* in the SDG.
|
||||||
* the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
* @throws IllegalArgumentException if node is null
|
||||||
* in the SDG.
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if node is null
|
|
||||||
*/
|
*/
|
||||||
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
|
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
|
||||||
|
@ -448,7 +442,7 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
Assertions.UNREACHABLE();
|
Assertions.UNREACHABLE();
|
||||||
}
|
}
|
||||||
// TODO: this is overly conservative. deal with catch blocks?
|
// TODO: this is overly conservative. deal with catch blocks?
|
||||||
for (IntIterator ii = getPEIs(ir).intIterator(); ii.hasNext(); ) {
|
for (IntIterator ii = getPEIs(ir).intIterator(); ii.hasNext();) {
|
||||||
int index = ii.next();
|
int index = ii.next();
|
||||||
SSAInstruction pei = ir.getInstructions()[index];
|
SSAInstruction pei = ir.getInstructions()[index];
|
||||||
if (dOptions.isTerminateAtCast() && (pei instanceof SSACheckCastInstruction)) {
|
if (dOptions.isTerminateAtCast() && (pei instanceof SSACheckCastInstruction)) {
|
||||||
|
@ -720,7 +714,8 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
return ssaInstruction2Statement(node, s, instructionIndices);
|
return ssaInstruction2Statement(node, s, instructionIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized Statement ssaInstruction2Statement(CGNode node, SSAInstruction s, Map<SSAInstruction, Integer> instructionIndices) {
|
public static synchronized Statement ssaInstruction2Statement(CGNode node, SSAInstruction s,
|
||||||
|
Map<SSAInstruction, Integer> instructionIndices) {
|
||||||
assert s != null;
|
assert s != null;
|
||||||
if (s instanceof SSAPhiInstruction) {
|
if (s instanceof SSAPhiInstruction) {
|
||||||
SSAPhiInstruction phi = (SSAPhiInstruction) s;
|
SSAPhiInstruction phi = (SSAPhiInstruction) s;
|
||||||
|
@ -800,17 +795,14 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
createCalleeParams(ref);
|
createCalleeParams(ref);
|
||||||
createReturnStatements();
|
createReturnStatements();
|
||||||
|
|
||||||
if (!cOptions.equals(ControlDependenceOptions.NONE)) {
|
delegate.addNode(new MethodEntryStatement(node));
|
||||||
delegate.addNode(new MethodEntryStatement(node));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create nodes representing defs of the return values
|
* create nodes representing defs of the return values
|
||||||
*
|
*
|
||||||
* @param mod
|
* @param mod the set of heap locations which may be written (transitively) by this node. These are logically
|
||||||
* the set of heap locations which may be written (transitively) by this node. These are logically
|
* parameters in the SDG.
|
||||||
* parameters in the SDG.
|
|
||||||
* @param dOptions
|
* @param dOptions
|
||||||
*/
|
*/
|
||||||
private void createReturnStatements() {
|
private void createReturnStatements() {
|
||||||
|
@ -839,9 +831,8 @@ public class PDG implements NumberedGraph<Statement> {
|
||||||
/**
|
/**
|
||||||
* create nodes representing defs of formal parameters
|
* create nodes representing defs of formal parameters
|
||||||
*
|
*
|
||||||
* @param ref
|
* @param ref the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
||||||
* the set of heap locations which may be read (transitively) by this node. These are logically parameters
|
* in the SDG.
|
||||||
* in the SDG.
|
|
||||||
*/
|
*/
|
||||||
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||||
ArrayList<Statement> list = new ArrayList<Statement>();
|
ArrayList<Statement> list = new ArrayList<Statement>();
|
||||||
|
|
|
@ -178,7 +178,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
*/
|
*/
|
||||||
public Statement getMainEntry() {
|
public Statement getMainEntry() {
|
||||||
Assertions.productionAssertion(!backward, "todo: support backward");
|
Assertions.productionAssertion(!backward, "todo: support backward");
|
||||||
return srcStatement;
|
return new MethodEntryStatement(srcStatement.getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -188,7 +188,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
// We pretend that sink is the "main exit" .. we don't care about
|
// We pretend that sink is the "main exit" .. we don't care about
|
||||||
// flow past the sink.
|
// flow past the sink.
|
||||||
Assertions.productionAssertion(backward, "todo: support forward");
|
Assertions.productionAssertion(backward, "todo: support forward");
|
||||||
return srcStatement;
|
return new MethodEntryStatement(srcStatement.getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,6 +18,7 @@ import com.ibm.wala.dataflow.IFDS.BackwardsSupergraph;
|
||||||
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
|
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
|
||||||
import com.ibm.wala.dataflow.IFDS.IMergeFunction;
|
import com.ibm.wala.dataflow.IFDS.IMergeFunction;
|
||||||
import com.ibm.wala.dataflow.IFDS.ISupergraph;
|
import com.ibm.wala.dataflow.IFDS.ISupergraph;
|
||||||
|
import com.ibm.wala.dataflow.IFDS.PathEdge;
|
||||||
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
|
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
|
||||||
import com.ibm.wala.dataflow.IFDS.TabulationProblem;
|
import com.ibm.wala.dataflow.IFDS.TabulationProblem;
|
||||||
import com.ibm.wala.dataflow.IFDS.TabulationResult;
|
import com.ibm.wala.dataflow.IFDS.TabulationResult;
|
||||||
|
@ -28,7 +29,6 @@ import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||||
import com.ibm.wala.ipa.modref.ModRef;
|
import com.ibm.wala.ipa.modref.ModRef;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||||
import com.ibm.wala.util.collections.Pair;
|
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -419,8 +419,8 @@ public class Slicer {
|
||||||
return supergraph;
|
return supergraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Pair<Statement, Integer>> initialSeeds() {
|
public Collection<PathEdge<Statement>> initialSeeds() {
|
||||||
Pair<Statement,Integer> seed = Pair.make(src, 0);
|
PathEdge<Statement> seed = PathEdge.createPathEdge(new MethodEntryStatement(src.getNode()), 0, src, 0);
|
||||||
return Collections.singleton(seed);
|
return Collections.singleton(seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue