add factories and objects to allow slicer to be extended to handle multiple languages

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1594 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2007-08-08 12:00:10 +00:00
parent 6814f05939
commit fd91f9a3ba
6 changed files with 78 additions and 44 deletions

View File

@ -57,7 +57,7 @@ public class ModRef {
* @throws IllegalArgumentException if cg is null
*
*/
public static Map<CGNode, OrdinalSet<PointerKey>> computeMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
public Map<CGNode, OrdinalSet<PointerKey>> computeMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
if (cg == null) {
throw new IllegalArgumentException("cg is null");
}
@ -71,7 +71,7 @@ public class ModRef {
* @throws IllegalArgumentException if cg is null
*
*/
public static Map<CGNode, OrdinalSet<PointerKey>> computeRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
public Map<CGNode, OrdinalSet<PointerKey>> computeRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
if (cg == null) {
throw new IllegalArgumentException("cg is null");
}
@ -84,7 +84,7 @@ public class ModRef {
* model) may it write, including its callees transitively
*
*/
public static Map<CGNode, OrdinalSet<PointerKey>> computeMod(CallGraph cg, PointerAnalysis pa) {
public Map<CGNode, OrdinalSet<PointerKey>> computeMod(CallGraph cg, PointerAnalysis pa) {
return computeMod(cg, pa, null);
}
@ -93,11 +93,11 @@ public class ModRef {
* model) may it read, including its callees transitively
*
*/
public static Map<CGNode, OrdinalSet<PointerKey>> computeRef(CallGraph cg, PointerAnalysis pa) {
public Map<CGNode, OrdinalSet<PointerKey>> computeRef(CallGraph cg, PointerAnalysis pa) {
return computeRef(cg, pa, null);
}
private static Map<CGNode, OrdinalSet<PointerKey>> transitiveClosure(CallGraph cg, Map<CGNode, Collection<PointerKey>> scan) {
private Map<CGNode, OrdinalSet<PointerKey>> transitiveClosure(CallGraph cg, Map<CGNode, Collection<PointerKey>> scan) {
GenReach<CGNode, PointerKey> gr = new GenReach<CGNode, PointerKey>(GraphInverter.invert(cg), scan);
BitVectorSolver<CGNode> solver = new BitVectorSolver<CGNode>(gr);
solver.solve();
@ -116,7 +116,7 @@ public class ModRef {
*
* @param heapExclude
*/
private static Map<CGNode, Collection<PointerKey>> scanForMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
private Map<CGNode, Collection<PointerKey>> scanForMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
Map<CGNode, Collection<PointerKey>> result = HashMapFactory.make();
for (Iterator<? extends CGNode> it = cg.iterator(); it.hasNext();) {
CGNode n = it.next();
@ -131,7 +131,7 @@ public class ModRef {
*
* @param heapExclude
*/
private static Map<CGNode, Collection<PointerKey>> scanForRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
private Map<CGNode, Collection<PointerKey>> scanForRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) {
Map<CGNode, Collection<PointerKey>> result = HashMapFactory.make();
for (Iterator<? extends CGNode> it = cg.iterator(); it.hasNext();) {
CGNode n = it.next();
@ -146,10 +146,10 @@ public class ModRef {
*
* @param heapExclude
*/
private static Collection<PointerKey> scanNodeForMod(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
private Collection<PointerKey> scanNodeForMod(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
Collection<PointerKey> result = HashSetFactory.make();
final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel());
SSAInstruction.Visitor v = new ModVisitor(n, result, h, pa);
SSAInstruction.Visitor v = makeModVisitor(n, result, pa, h);
IR ir = n.getIR();
if (ir != null) {
for (Iterator<SSAInstruction> it = ir.iterateNormalInstructions(); it.hasNext();) {
@ -166,10 +166,10 @@ public class ModRef {
* For a call graph node, what heap locations (as determined by a heap model)
* may it read, <bf> NOT </bf> including it's callees transitively
*/
private static Collection<PointerKey> scanNodeForRef(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
private Collection<PointerKey> scanNodeForRef(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
Collection<PointerKey> result = HashSetFactory.make();
final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel());
SSAInstruction.Visitor v = new RefVisitor(n, result, pa, h);
SSAInstruction.Visitor v = makeRefVisitor(n, result, pa, h);
IR ir = n.getIR();
if (ir != null) {
for (Iterator<SSAInstruction> it = ir.iterateNormalInstructions(); it.hasNext();) {
@ -182,7 +182,7 @@ public class ModRef {
return result;
}
private static final class RefVisitor extends SSAInstruction.Visitor {
protected static class RefVisitor extends SSAInstruction.Visitor {
private final CGNode n;
private final Collection<PointerKey> result;
@ -191,7 +191,7 @@ public class ModRef {
private final ExtendedHeapModel h;
private RefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
protected RefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
this.n = n;
this.result = result;
this.pa = pa;
@ -230,7 +230,7 @@ public class ModRef {
}
}
private static final class ModVisitor extends SSAInstruction.Visitor {
protected static class ModVisitor extends SSAInstruction.Visitor {
private final CGNode n;
private final Collection<PointerKey> result;
@ -239,7 +239,8 @@ public class ModRef {
private final PointerAnalysis pa;
private ModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa) {
protected ModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa) {
this.n = n;
this.result = result;
this.h = h;
@ -324,24 +325,32 @@ public class ModRef {
}
}
public static Collection<PointerKey> getMod(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s,
protected ModVisitor makeModVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
return new ModVisitor(n, result, h, pa);
}
public Collection<PointerKey> getMod(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s,
HeapExclusions hexcl) {
if (s == null) {
throw new IllegalArgumentException("s is null");
}
Collection<PointerKey> result = HashSetFactory.make(2);
ModVisitor v = new ModVisitor(n, result, h, pa);
ModVisitor v = makeModVisitor(n, result, pa, h);
s.visit(v);
return hexcl == null ? result : hexcl.filter(result);
}
public static Collection<PointerKey> getRef(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s,
protected RefVisitor makeRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
return new RefVisitor(n, result, pa, h);
}
public Collection<PointerKey> getRef(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s,
HeapExclusions hexcl) {
if (s == null) {
throw new IllegalArgumentException("s is null");
}
Collection<PointerKey> result = HashSetFactory.make(2);
RefVisitor v = new RefVisitor(n, result, pa, h);
RefVisitor v = makeRefVisitor(n, result, pa, h);
s.visit(v);
return hexcl == null ? result : hexcl.filter(result);
}

View File

@ -69,6 +69,12 @@ public class HeapReachingDefs {
private static final boolean VERBOSE = false;
private final ModRef modRef;
public HeapReachingDefs(ModRef modRef) {
this.modRef = modRef;
}
/**
* For each statement s, return the set of statements that may def the heap
* value read by s.
@ -93,7 +99,7 @@ public class HeapReachingDefs {
* @throws IllegalArgumentException
* if statements is null
*/
public static Map<Statement, OrdinalSet<Statement>> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa,
public Map<Statement, OrdinalSet<Statement>> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa,
Map<CGNode, OrdinalSet<PointerKey>> mod, Collection<Statement> statements, HeapExclusions exclusions, CallGraph cg) {
if (statements == null) {
@ -132,7 +138,7 @@ public class HeapReachingDefs {
ssaInstructionIndex2Statement, exclusions, cg);
}
private static class RDMap implements Map<Statement, OrdinalSet<Statement>> {
private class RDMap implements Map<Statement, OrdinalSet<Statement>> {
final Map<Statement, OrdinalSet<Statement>> delegate = HashMapFactory.make();
private final HeapExclusions exclusions;
@ -194,7 +200,7 @@ public class HeapReachingDefs {
return pointerKeyMod;
}
private static MutableIntSet findOrCreateIntSet(Map<PointerKey, MutableIntSet> map, PointerKey key) {
private MutableIntSet findOrCreateIntSet(Map<PointerKey, MutableIntSet> map, PointerKey key) {
MutableIntSet result = map.get(key);
if (result == null) {
result = new MutableSparseIntSet();
@ -277,14 +283,14 @@ public class HeapReachingDefs {
* For a statement s, compute the set of statements that may def the heap
* value read by s.
*/
private OrdinalSet<Statement> computeResult(Statement s, Map<PointerKey, MutableIntSet> pointerKeyMod,
OrdinalSet<Statement> computeResult(Statement s, Map<PointerKey, MutableIntSet> pointerKeyMod,
BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExplodedControlFlowGraph cfg,
Map<Integer, NormalStatement> ssaInstructionIndex2Statement) {
switch (s.getKind()) {
case NORMAL:
NormalStatement n = (NormalStatement) s;
Collection<PointerKey> ref = ModRef.getRef(node, h, pa, n.getInstruction(), exclusions);
Collection<PointerKey> ref = modRef.getRef(node, h, pa, n.getInstruction(), exclusions);
if (!ref.isEmpty()) {
IBasicBlock bb = cfg.getBlockForInstruction(n.getInstructionIndex());
BitVectorVariable v = (BitVectorVariable) solver.getIn(bb);
@ -359,7 +365,7 @@ public class HeapReachingDefs {
* For each statement s, compute the set of statements that may def the heap
* value read by s.
*/
private static Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<IBasicBlock> solver,
private Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<IBasicBlock> 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) {
@ -384,12 +390,12 @@ public class HeapReachingDefs {
return true;
}
private static Collection<PointerKey> getMod(Statement s, CGNode n, ExtendedHeapModel h, PointerAnalysis pa,
private Collection<PointerKey> getMod(Statement s, CGNode n, ExtendedHeapModel h, PointerAnalysis pa,
HeapExclusions exclusions) {
switch (s.getKind()) {
case NORMAL:
NormalStatement ns = (NormalStatement) s;
return ModRef.getMod(n, h, pa, ns.getInstruction(), exclusions);
return modRef.getMod(n, h, pa, ns.getInstruction(), exclusions);
case HEAP_PARAM_CALLEE:
case HEAP_RET_CALLER:
HeapStatement hs = (HeapStatement) s;
@ -437,7 +443,7 @@ public class HeapReachingDefs {
/**
* Reaching def flow functions
*/
private static class RD implements ITransferFunctionProvider<IBasicBlock> {
private class RD implements ITransferFunctionProvider<IBasicBlock> {
private final CGNode node;
@ -552,7 +558,7 @@ public class HeapReachingDefs {
assert (domainIndex != -1);
return heapReturnCaller.getRelated(domainIndex);
} else {
Collection<PointerKey> gen = ModRef.getMod(node, h, pa, s, exclusions);
Collection<PointerKey> gen = modRef.getMod(node, h, pa, s, exclusions);
if (gen.isEmpty()) {
return null;
} else {
@ -587,7 +593,7 @@ public class HeapReachingDefs {
if (s == null) {
return null;
} else {
Collection<PointerKey> mod = ModRef.getMod(node, h, pa, s, exclusions);
Collection<PointerKey> mod = modRef.getMod(node, h, pa, s, exclusions);
if (mod.isEmpty()) {
return null;
} else {

View File

@ -102,6 +102,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
private final CallGraph cg;
private final ModRef modRef;
/**
* @param mod
* the set of heap locations which may be written (transitively) by
@ -114,7 +116,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
*/
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
HeapExclusions exclusions, CallGraph cg) {
HeapExclusions exclusions, CallGraph cg, ModRef modRef) {
super();
if (node == null) {
@ -127,6 +129,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
this.dOptions = dOptions;
this.mod = mod;
this.exclusions = exclusions;
this.modRef = modRef;
instructionIndices = computeInstructionIndices(node.getIR());
createNodes(ref, cOptions);
createScalarEdges(cOptions);
@ -511,7 +514,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
};
Collection<Statement> relevantStatements = Iterator2Collection.toCollection(new FilterIterator<Statement>(iterator(), f));
Map<Statement, OrdinalSet<Statement>> heapReachingDefs = dOptions.isIgnoreHeap() ? null : HeapReachingDefs.computeReachingDefs(
Map<Statement, OrdinalSet<Statement>> heapReachingDefs = dOptions.isIgnoreHeap() ? null : (new HeapReachingDefs(modRef)).computeReachingDefs(
node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))), cg);
for (Statement st : heapReachingDefs.keySet()) {
@ -930,7 +933,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
case NORMAL:
NormalStatement st = (NormalStatement) N;
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
Collection<PointerKey> ref = ModRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions);
Collection<PointerKey> ref = modRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions);
for (PointerKey pk : ref) {
createHeapDataDependenceEdges(pk);
}
@ -950,7 +953,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
case NORMAL:
NormalStatement st = (NormalStatement) N;
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
Collection<PointerKey> ref = ModRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions);
Collection<PointerKey> ref = modRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions);
for (PointerKey pk : ref) {
createHeapDataDependenceEdges(pk);
}

View File

@ -106,20 +106,26 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
*/
private final HeapExclusions heapExclude;
private final ModRef modRef;
public SDG(final CallGraph cg, PointerAnalysis pa, DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
this(cg, pa, dOptions, cOptions, null);
this(cg, pa, new ModRef(), dOptions, cOptions, null);
}
public SDG(CallGraph cg, PointerAnalysis pa, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, HeapExclusions heapExclude) throws IllegalArgumentException {
public SDG(final CallGraph cg, PointerAnalysis pa, ModRef modRef, DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
this(cg, pa, modRef, dOptions, cOptions, null);
}
public SDG(CallGraph cg, PointerAnalysis pa, ModRef modRef, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, HeapExclusions heapExclude) throws IllegalArgumentException {
super();
if (dOptions == null) {
throw new IllegalArgumentException("dOptions must not be null");
}
this.modRef = modRef;
this.cg = cg;
this.pa = pa;
this.mod = dOptions.isIgnoreHeap() ? null : ModRef.computeMod(cg, pa, heapExclude);
this.ref = dOptions.isIgnoreHeap() ? null : ModRef.computeRef(cg, pa, heapExclude);
this.mod = dOptions.isIgnoreHeap() ? null : modRef.computeMod(cg, pa, heapExclude);
this.ref = dOptions.isIgnoreHeap() ? null : modRef.computeRef(cg, pa, heapExclude);
this.dOptions = dOptions;
this.cOptions = cOptions;
this.heapExclude = heapExclude;
@ -618,7 +624,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
public PDG getPDG(CGNode node) {
PDG result = pdgMap.get(node);
if (result == null) {
result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude, cg);
result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude, cg, modRef);
pdgMap.put(node, result);
for (Iterator<? extends Statement> it = result.iterator(); it.hasNext();) {
nodeMgr.addNode(it.next());

View File

@ -25,6 +25,7 @@ import com.ibm.wala.dataflow.IFDS.TabulationResult;
import com.ibm.wala.dataflow.IFDS.TabulationSolver;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.modref.ModRef;
import com.ibm.wala.ipa.slicer.Statement.Kind;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.Iterator2Collection;
@ -190,7 +191,12 @@ public class Slicer {
* @param ss
* a collection of statements of interest
*/
private static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa,
protected static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa,
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) {
return computeSlice(sdg, ss, cg, pa, new ModRef(), dOptions, cOptions, backward);
}
protected static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa, ModRef modRef,
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) {
if (VERBOSE) {
@ -198,7 +204,7 @@ public class Slicer {
}
if (sdg == null) {
sdg = new SDG(cg, pa, dOptions, cOptions);
sdg = new SDG(cg, pa, modRef, dOptions, cOptions);
}
Collection<Statement> rootsConsidered = HashSetFactory.make();

View File

@ -61,7 +61,11 @@ public class ThinSlicer {
private final Graph<Statement> depGraph;
public ThinSlicer(CallGraph cg, PointerAnalysis pa) {
SDG sdg = new SDG(cg, pa, DataDependenceOptions.NO_BASE_NO_HEAP, ControlDependenceOptions.NONE, null);
this(cg, pa, new ModRef());
}
public ThinSlicer(CallGraph cg, PointerAnalysis pa, ModRef modRef) {
SDG sdg = new SDG(cg, pa, modRef, DataDependenceOptions.NO_BASE_NO_HEAP, ControlDependenceOptions.NONE, null);
Map<Statement, Set<PointerKey>> mod = scanForMod(sdg, pa);
Map<Statement, Set<PointerKey>> ref = scanForRef(sdg, pa);
@ -270,7 +274,7 @@ public class ThinSlicer {
Statement st = it.next();
switch (st.getKind()) {
case NORMAL:
Set<PointerKey> c = HashSetFactory.make(ModRef.getMod(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(),
Set<PointerKey> c = HashSetFactory.make((new ModRef()).getMod(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(),
null));
result.put(st, c);
break;
@ -290,7 +294,7 @@ public class ThinSlicer {
Statement st = it.next();
switch (st.getKind()) {
case NORMAL:
Set<PointerKey> c = HashSetFactory.make(ModRef.getRef(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(),
Set<PointerKey> c = HashSetFactory.make((new ModRef()).getRef(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(),
null));
result.put(st, c);
break;