optimizations

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2879 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
msridhar1 2008-06-10 14:49:38 +00:00
parent 4dd7972a30
commit 3a3c9afaca
3 changed files with 62 additions and 34 deletions

View File

@ -572,10 +572,15 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
protected final PointerKeyAndState queriedPkAndState;
/**
* set of variables whose points-to sets were queried
* map from pointer key to states in which the key's points-to set was queried
*/
private final MultiMap<PointerKey, State> pointsToQueried = HashSetMultiMap.make();
/**
* map from pointer key to states in which a tracked points-to set for the key was computed
*/
private final MultiMap<PointerKey, State> trackedQueried = HashSetMultiMap.make();
/**
* forward worklist: for initially processing points-to queries
*/
@ -808,17 +813,14 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
Assertions._assert(label.isBarred());
}
final State curState = curPkAndState.getState();
// TODO may need to speed this up with another data structure
for (PointerKeyAndState pkAndState : pkToTrackedSet.keySet()) {
if (succPk.equals(pkAndState.getPointerKey())) {
State transState = stateMachine.transition(pkAndState.getState(), label);
if (transState.equals(curState)) {
ret.add(pkAndState);
}
Set<State> succPkStates = trackedQueried.get(succPk);
for (State succState : succPkStates) {
State transState = stateMachine.transition(succState, label);
if (transState.equals(curState)) {
ret.add(new PointerKeyAndState(succPk, succState));
}
}
return ret;
}
void handleBackCopy(PointerKeyAndState curPkAndState, PointerKey predPk, IFlowLabel label) {
@ -879,6 +881,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
if (DEBUG) {
// System.err.println("adding to tracked points-to " + pkAndState);
}
trackedQueried.put(pkAndState.getPointerKey(), pkAndState.getState());
trackedPointsToWorklist.add(pkAndState);
}
@ -2007,12 +2010,23 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
private OrdinalSet<InstanceKeyAndState> getPToSetFromComputer(final PointsToComputer ptoComputer,
PointerKeyAndState pointerKeyAndState) {
// make sure relevant constraints have been added
if (pointerKeyAndState.getPointerKey() instanceof LocalPointerKey) {
LocalPointerKey lpk = (LocalPointerKey) pointerKeyAndState.getPointerKey();
g.addSubgraphForNode(lpk.getNode());
}
// add pointerKeyAndState to init worklist
ptoComputer.addToInitWorklist(pointerKeyAndState);
// run worklist algorithm
ptoComputer.worklistLoop();
// suck out the points-to set
return ptoComputer.makeOrdinalSet(ptoComputer.pkToP2Set.get(pointerKeyAndState));
final MutableIntSet intP2Set = ptoComputer.pkToP2Set.get(pointerKeyAndState);
if (intP2Set == null) {
// null if empty p2set
return OrdinalSet.empty();
} else {
return ptoComputer.makeOrdinalSet(intP2Set);
}
}
private void computeFlowsTo(PointsToComputer ptoComputer, OrdinalSet<InstanceKeyAndState> basePToSet) {
@ -2028,13 +2042,20 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
private Collection<State> getFlowedToStates(PointsToComputer ptoComputer, OrdinalSet<InstanceKeyAndState> basePToSet,
PointerKey putfieldBase) {
Collection<State> result = HashSetFactory.make();
for (PointerKeyAndState pkAndState : ptoComputer.pkToTrackedSet.keySet()) {
if (pkAndState.getPointerKey().equals(putfieldBase)) {
if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
result.add(pkAndState.getState());
}
Set<State> trackedStates = ptoComputer.trackedQueried.get(putfieldBase);
for (State trackedState : trackedStates) {
PointerKeyAndState pkAndState = new PointerKeyAndState(putfieldBase, trackedState);
if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
result.add(trackedState);
}
}
// for (PointerKeyAndState pkAndState : ptoComputer.pkToTrackedSet.keySet()) {
// if (pkAndState.getPointerKey().equals(putfieldBase)) {
// if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
// result.add(pkAndState.getState());
// }
// }
// }
return result;
}
@ -2140,7 +2161,13 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
}
private Collection<Pair<PointerKey, PointerKey>> getBaseAndStored(MemoryAccess fieldWrite, IField field) {
IR ir = fieldWrite.getNode().getIR();
final CGNode node = fieldWrite.getNode();
// an optimization; if node is not represented in our constraint graph, then we could not possibly
// have discovered flow to the base pointer
if (!g.hasSubgraphForNode(node)) {
return null;
}
IR ir = node.getIR();
PointerKey base = null, stored = null;
if (field == ArrayContents.v()) {
final SSAInstruction instruction = ir.getInstructions()[fieldWrite.getInstructionIndex()];

View File

@ -63,7 +63,7 @@ public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
private boolean superOfAnyEncountered(IClass klass) {
for (IClass toRefine : typesToRefine) {
if (cha.isAssignableFrom(klass, toRefine)) {
if (cha.isAssignableFrom(klass, toRefine) || cha.isAssignableFrom(toRefine, klass)) {
return true;
}
}

View File

@ -11,8 +11,8 @@
package com.ibm.wala.demandpa.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@ -29,7 +29,6 @@ import com.ibm.wala.ipa.slicer.Statement;
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
import com.ibm.wala.ipa.slicer.thin.CISlicer;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.collections.MapUtil;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.Trace;
@ -70,19 +69,19 @@ public class PABasedMemoryAccessMap implements MemoryAccessMap {
}
public Collection<MemoryAccess> getArrayReads(PointerKey arrayRef) {
Set<MemoryAccess> memAccesses = HashSetFactory.make();
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
if (DEBUG) {
Trace.println("looking at reads of array ref " + arrayRef);
}
for (InstanceKey ik : pa.getPointsToSet(arrayRef)) {
PointerKey ack = heapModel.getPointerKeyForArrayContents(ik);
memAccesses.addAll(convertStmtsToMemoryAccess(invRef.get(ack)));
convertStmtsToMemoryAccess(invRef.get(ack), memAccesses);
}
return memAccesses;
}
public Collection<MemoryAccess> getArrayWrites(PointerKey arrayRef) {
Set<MemoryAccess> memAccesses = HashSetFactory.make();
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
if (DEBUG) {
Trace.println("looking at writes to array ref " + arrayRef);
}
@ -91,56 +90,58 @@ public class PABasedMemoryAccessMap implements MemoryAccessMap {
Trace.println("instance key " + ik + " class " + ik.getClass());
}
PointerKey ack = heapModel.getPointerKeyForArrayContents(ik);
memAccesses.addAll(convertStmtsToMemoryAccess(invMod.get(ack)));
convertStmtsToMemoryAccess(invMod.get(ack), memAccesses);
}
return memAccesses;
}
public Collection<MemoryAccess> getFieldReads(PointerKey baseRef, IField field) {
Set<MemoryAccess> memAccesses = HashSetFactory.make();
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
for (InstanceKey ik : pa.getPointsToSet(baseRef)) {
PointerKey ifk = heapModel.getPointerKeyForInstanceField(ik, field);
memAccesses.addAll(convertStmtsToMemoryAccess(invRef.get(ifk)));
convertStmtsToMemoryAccess(invRef.get(ifk), memAccesses);
}
return memAccesses;
}
public Collection<MemoryAccess> getFieldWrites(PointerKey baseRef, IField field) {
Set<MemoryAccess> memAccesses = HashSetFactory.make();
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
for (InstanceKey ik : pa.getPointsToSet(baseRef)) {
PointerKey ifk = heapModel.getPointerKeyForInstanceField(ik, field);
memAccesses.addAll(convertStmtsToMemoryAccess(invMod.get(ifk)));
convertStmtsToMemoryAccess(invMod.get(ifk), memAccesses);
}
return memAccesses;
}
public Collection<MemoryAccess> getStaticFieldReads(IField field) {
return convertStmtsToMemoryAccess(invRef.get(heapModel.getPointerKeyForStaticField(field)));
Collection<MemoryAccess> result = new ArrayList<MemoryAccess>();
convertStmtsToMemoryAccess(invRef.get(heapModel.getPointerKeyForStaticField(field)), result);
return result;
}
public Collection<MemoryAccess> getStaticFieldWrites(IField field) {
return convertStmtsToMemoryAccess(invMod.get(heapModel.getPointerKeyForStaticField(field)));
Collection<MemoryAccess> result = new ArrayList<MemoryAccess>();
convertStmtsToMemoryAccess(invMod.get(heapModel.getPointerKeyForStaticField(field)), result);
return result;
}
private Collection<MemoryAccess> convertStmtsToMemoryAccess(Collection<Statement> stmts) {
private void convertStmtsToMemoryAccess(Collection<Statement> stmts, Collection<MemoryAccess> result) {
if (stmts == null) {
return Collections.emptySet();
return;
}
if (DEBUG) {
Trace.println("statements: " + stmts);
}
Collection<MemoryAccess> ret = HashSetFactory.make();
for (Statement s : stmts) {
switch (s.getKind()) {
case NORMAL:
NormalStatement normStmt = (NormalStatement) s;
ret.add(new MemoryAccess(normStmt.getInstructionIndex(), normStmt.getNode()));
result.add(new MemoryAccess(normStmt.getInstructionIndex(), normStmt.getNode()));
break;
default:
Assertions.UNREACHABLE();
}
}
return ret;
}
public HeapModel getHeapModel() {