slicer cleanups

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2407 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2008-01-17 10:15:49 +00:00
parent fcc98ee241
commit 16acba0d63
16 changed files with 498 additions and 386 deletions

View File

@ -21,8 +21,8 @@ import com.ibm.wala.eclipse.util.CancelException;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.slicer.NormalReturnCallee;
import com.ibm.wala.ipa.slicer.NormalStatement;
import com.ibm.wala.ipa.slicer.ParamStatement;
import com.ibm.wala.ipa.slicer.Slicer;
import com.ibm.wala.ipa.slicer.Statement;
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
@ -105,7 +105,7 @@ public class ReflectionHandler {
if (n.getMethod() instanceof SyntheticMethod) {
SyntheticMethod m = (SyntheticMethod) n.getMethod();
if (m.isFactoryMethod()) {
result.add(new ParamStatement.NormalReturnCallee(n));
result.add(new NormalReturnCallee(n));
}
}
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
/**
* A {@link Statement} representing the exceptional return value in a callee,
* immediately before returning to the caller.
*
* @author sjfink
*/
public class ExceptionalReturnCallee extends Statement {
public ExceptionalReturnCallee(CGNode node) {
super(node);
}
@Override
public Kind getKind() {
return Kind.EXC_RET_CALLEE;
}
}

View File

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
/**
* A {@link Statement} representing the exceptional return value in a caller,
* immediately after returning to the caller.
*
* @author sjfink
*/
public class ExceptionalReturnCaller extends StatementWithInstructionIndex implements ValueNumberCarrier {
public ExceptionalReturnCaller(CGNode node, int callIndex) {
super(node, callIndex);
}
public int getValueNumber() {
return getInstruction().getException();
}
@Override
public SSAAbstractInvokeInstruction getInstruction() {
return (SSAAbstractInvokeInstruction)super.getInstruction();
}
@Override
public Kind getKind() {
return Kind.EXC_RET_CALLER;
}
}

View File

@ -34,7 +34,7 @@ import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
import com.ibm.wala.ipa.modref.DelegatingExtendedHeapModel;
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.HeapStatement.HeapReturnCaller;
import com.ibm.wala.ipa.slicer.Statement.Kind;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
@ -314,7 +314,7 @@ public class HeapReachingDefs {
return OrdinalSet.empty();
}
case HEAP_RET_CALLEE: {
HeapStatement.ReturnCallee r = (HeapStatement.ReturnCallee) s;
HeapStatement.HeapReturnCallee r = (HeapStatement.HeapReturnCallee) s;
PointerKey p = r.getLocation();
BitVectorVariable v = solver.getIn(cfg.exit());
if (DEBUG) {
@ -326,7 +326,7 @@ public class HeapReachingDefs {
return new OrdinalSet<Statement>(pointerKeyMod.get(p).intersection(v.getValue()), domain);
}
case HEAP_RET_CALLER: {
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) s;
HeapStatement.HeapReturnCaller r = (HeapStatement.HeapReturnCaller) s;
ISSABasicBlock bb = cfg.getBlockForInstruction(r.getCallIndex());
BitVectorVariable v = solver.getIn(bb);
if (allCalleesMod(cg, r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) {
@ -339,11 +339,11 @@ public class HeapReachingDefs {
}
}
case HEAP_PARAM_CALLER: {
HeapStatement.ParamCaller r = (HeapStatement.ParamCaller) s;
HeapStatement.HeapParamCaller r = (HeapStatement.HeapParamCaller) s;
NormalStatement call = ssaInstructionIndex2Statement.get(r.getCallIndex());
ISSABasicBlock callBlock = cfg.getBlockForInstruction(call.getInstructionIndex());
if (callBlock.isEntryBlock()) {
int x = domain.getMappedIndex(new HeapStatement.ParamCallee(node, r.getLocation()));
int x = domain.getMappedIndex(new HeapStatement.HeapParamCallee(node, r.getLocation()));
assert x >= 0;
IntSet xset = SparseIntSet.singleton(x);
return new OrdinalSet<Statement>(xset, domain);
@ -392,7 +392,7 @@ public class HeapReachingDefs {
/**
* Do all callees corresponding to the given call site def the pointer key being tracked by r?
*/
private static boolean allCalleesMod(CallGraph cg, ReturnCaller r, Map<CGNode, OrdinalSet<PointerKey>> mod) {
private static boolean allCalleesMod(CallGraph cg, HeapReturnCaller r, Map<CGNode, OrdinalSet<PointerKey>> mod) {
Collection<CGNode> targets = cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite());
if (targets.isEmpty()) {
return false;
@ -497,7 +497,7 @@ public class HeapReachingDefs {
if (DEBUG) {
System.err.println("initHeapReturnCaller " + s);
}
HeapStatement.ReturnCaller r = (ReturnCaller) s;
HeapStatement.HeapReturnCaller r = (HeapReturnCaller) s;
NormalStatement call = ssaInstructionIndex2Statement.get(r.getCallIndex());
int i = domain.getMappedIndex(call);
int j = domain.getMappedIndex(r);

View File

@ -29,11 +29,11 @@ public abstract class HeapStatement extends Statement {
}
public final static class ParamCaller extends HeapStatement {
public final static class HeapParamCaller extends HeapStatement {
// index into the IR instruction array of the call statements
private final int callIndex;
public ParamCaller(CGNode node,int callIndex, PointerKey loc) {
public HeapParamCaller(CGNode node,int callIndex, PointerKey loc) {
super(node, loc);
this.callIndex = callIndex;
}
@ -64,8 +64,8 @@ public abstract class HeapStatement extends Statement {
@Override
public boolean equals(Object obj) {
// instanceof is OK because this class is final. instanceof is more efficient than getClass
if (obj instanceof ParamCaller) {
ParamCaller other = (ParamCaller) obj;
if (obj instanceof HeapParamCaller) {
HeapParamCaller other = (HeapParamCaller) obj;
return getNode().equals(other.getNode()) && getLocation().equals(other.getLocation()) && callIndex == other.callIndex;
} else {
return false;
@ -73,8 +73,8 @@ public abstract class HeapStatement extends Statement {
}
}
public final static class ParamCallee extends HeapStatement {
public ParamCallee(CGNode node, PointerKey loc) {
public final static class HeapParamCallee extends HeapStatement {
public HeapParamCallee(CGNode node, PointerKey loc) {
super(node, loc);
}
@ -91,8 +91,8 @@ public abstract class HeapStatement extends Statement {
@Override
public boolean equals(Object obj) {
// instanceof is ok because this class is final. instanceof is more efficient than getClass
if (obj instanceof ParamCallee) {
ParamCallee other = (ParamCallee) obj;
if (obj instanceof HeapParamCallee) {
HeapParamCallee other = (HeapParamCallee) obj;
return getNode().equals(other.getNode()) && getLocation().equals(other.getLocation());
} else {
return false;
@ -105,12 +105,12 @@ public abstract class HeapStatement extends Statement {
}
}
public final static class ReturnCaller extends HeapStatement {
public final static class HeapReturnCaller extends HeapStatement {
// index into the instruction array of the relevant call instruction
private final int callIndex;
// private final SSAAbstractInvokeInstruction call;
public ReturnCaller(CGNode node, int callIndex, PointerKey loc) {
public HeapReturnCaller(CGNode node, int callIndex, PointerKey loc) {
super(node, loc);
this.callIndex = callIndex;
}
@ -141,8 +141,8 @@ public abstract class HeapStatement extends Statement {
@Override
public boolean equals(Object obj) {
// instanceof is ok because this class is final. instanceof is more efficient than getClass
if (obj instanceof ReturnCaller) {
ReturnCaller other = (ReturnCaller) obj;
if (obj instanceof HeapReturnCaller) {
HeapReturnCaller other = (HeapReturnCaller) obj;
return getNode().equals(other.getNode()) && getLocation().equals(other.getLocation()) && callIndex == other.callIndex;
} else {
return false;
@ -150,8 +150,8 @@ public abstract class HeapStatement extends Statement {
}
}
public final static class ReturnCallee extends HeapStatement {
public ReturnCallee(CGNode node, PointerKey loc) {
public final static class HeapReturnCallee extends HeapStatement {
public HeapReturnCallee(CGNode node, PointerKey loc) {
super(node, loc);
}
@ -168,8 +168,8 @@ public abstract class HeapStatement extends Statement {
@Override
public boolean equals(Object obj) {
// instanceof is ok because this class is final. instanceof is more efficient than getClass
if (obj instanceof ReturnCallee) {
ReturnCallee other = (ReturnCallee) obj;
if (obj instanceof HeapReturnCallee) {
HeapReturnCallee other = (HeapReturnCallee) obj;
return getNode().equals(other.getNode()) && getLocation().equals(other.getLocation());
} else {
return false;

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
/**
* A {@link Statement} representing the normal return value in a callee,
* immediately before returning to the caller.
*
* @author sjfink
*/
public class NormalReturnCallee extends Statement {
public NormalReturnCallee(CGNode node) {
super(node);
}
@Override
public Kind getKind() {
return Kind.NORMAL_RET_CALLEE;
}
}

View File

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
/**
* A {@link Statement} representing the normal return value in a caller,
* immediately after returning to the caller.
*
* @author sjfink
*/
public class NormalReturnCaller extends StatementWithInstructionIndex implements ValueNumberCarrier {
public NormalReturnCaller(CGNode node, int callIndex) {
super(node, callIndex);
}
public int getValueNumber() {
return getInstruction().getReturnValue(0);
}
@Override
public SSAAbstractInvokeInstruction getInstruction() {
return (SSAAbstractInvokeInstruction)super.getInstruction();
}
@Override
public Kind getKind() {
return Kind.NORMAL_RET_CALLER;
}
}

View File

@ -30,7 +30,6 @@ import com.ibm.wala.ipa.cfg.ExceptionPrunedCFG;
import com.ibm.wala.ipa.modref.DelegatingExtendedHeapModel;
import com.ibm.wala.ipa.modref.ExtendedHeapModel;
import com.ibm.wala.ipa.modref.ModRef;
import com.ibm.wala.ipa.slicer.ParamStatement.ValueNumberCarrier;
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
import com.ibm.wala.ipa.slicer.Statement.Kind;
@ -64,6 +63,7 @@ import com.ibm.wala.util.debug.UnimplementedError;
import com.ibm.wala.util.graph.NumberedGraph;
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
import com.ibm.wala.util.intset.BitVectorIntSet;
import com.ibm.wala.util.intset.IntIterator;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.OrdinalSet;
@ -327,8 +327,7 @@ public class PDG implements NumberedGraph<Statement> {
assert pi != null;
if (pi instanceof SSAAbstractInvokeInstruction) {
SSAAbstractInvokeInstruction i = (SSAAbstractInvokeInstruction) pi;
delegate.addEdge(new ParamStatement.ExceptionalReturnCaller(node, i), c);
delegate.addEdge(new ExceptionalReturnCaller(node, pb.getLastInstructionIndex()), c);
} else if (pi instanceof SSAAbstractThrowInstruction) {
delegate.addEdge(ssaInstruction2Statement(pi), c);
}
@ -432,28 +431,29 @@ public class PDG implements NumberedGraph<Statement> {
Assertions.UNREACHABLE();
}
// TODO: this is overly conservative. deal with catch blocks?
for (NormalStatement pei : getPEIs(ir)) {
if (dOptions.isTerminateAtCast() && (pei.getInstruction() instanceof SSACheckCastInstruction)) {
for (IntIterator ii = getPEIs(ir).intIterator(); ii.hasNext(); ) {
int index = ii.next();
SSAInstruction pei = ir.getInstructions()[index];
if (dOptions.isTerminateAtCast() && (pei instanceof SSACheckCastInstruction)) {
continue;
}
if (pei.getInstruction() instanceof SSAAbstractInvokeInstruction) {
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) pei.getInstruction();
Statement st = new ParamStatement.ExceptionalReturnCaller(node, call);
if (pei instanceof SSAAbstractInvokeInstruction) {
Statement st = new ExceptionalReturnCaller(node, index);
delegate.addEdge(st, s);
} else {
delegate.addEdge(pei, s);
delegate.addEdge(new NormalStatement(node, index), s);
}
}
break;
case PARAM_CALLER: {
ParamStatement.ParamCaller pac = (ParamStatement.ParamCaller) s;
ParamCaller pac = (ParamCaller) s;
int vn = pac.getValueNumber();
// note that if the caller is the fake root method and the parameter
// type is primitive,
// it's possible to have a value number of -1. If so, just ignore it.
if (vn > -1) {
if (ir.getSymbolTable().isParameter(vn)) {
Statement a = new ParamStatement.ParamCallee(node, vn);
Statement a = new ParamCallee(node, vn);
delegate.addEdge(a, pac);
} else {
SSAInstruction d = DU.getDef(vn);
@ -464,10 +464,10 @@ public class PDG implements NumberedGraph<Statement> {
if (d instanceof SSAAbstractInvokeInstruction) {
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) d;
if (vn == call.getException()) {
Statement st = new ParamStatement.ExceptionalReturnCaller(node, call);
Statement st = new ExceptionalReturnCaller(node, instructionIndices.get(d));
delegate.addEdge(st, pac);
} else {
Statement st = new ParamStatement.NormalReturnCaller(node, call);
Statement st = new NormalReturnCaller(node, instructionIndices.get(d));
delegate.addEdge(st, pac);
}
} else {
@ -684,21 +684,16 @@ public class PDG implements NumberedGraph<Statement> {
}
/**
* @return Statements representing each PEI in the ir
* @return {@link IntSet} representing instruction indices of each PEI in the ir
*/
private Collection<NormalStatement> getPEIs(final IR ir) {
Filter filter = new Filter() {
public boolean accepts(Object o) {
if (o instanceof NormalStatement) {
NormalStatement s = (NormalStatement) o;
SSAInstruction st = ir.getInstructions()[s.getInstructionIndex()];
return st.isPEI();
} else {
return false;
}
private IntSet getPEIs(final IR ir) {
BitVectorIntSet result = new BitVectorIntSet();
for (int i = 0; i < ir.getInstructions().length; i++) {
if (ir.getInstructions()[i] != null && ir.getInstructions()[i].isPEI()) {
result.add(i);
}
};
return Iterator2Collection.toCollection(new FilterIterator<NormalStatement>(iterator(), filter));
}
return result;
}
/**
@ -804,18 +799,18 @@ public class PDG implements NumberedGraph<Statement> {
private void createReturnStatements() {
ArrayList<Statement> list = new ArrayList<Statement>();
if (!node.getMethod().getReturnType().equals(TypeReference.Void)) {
ParamStatement.NormalReturnCallee n = new ParamStatement.NormalReturnCallee(node);
NormalReturnCallee n = new NormalReturnCallee(node);
delegate.addNode(n);
list.add(n);
}
if (!dOptions.isIgnoreExceptions()) {
ParamStatement.ExceptionalReturnCallee e = new ParamStatement.ExceptionalReturnCallee(node);
ExceptionalReturnCallee e = new ExceptionalReturnCallee(node);
delegate.addNode(e);
list.add(e);
}
if (!dOptions.isIgnoreHeap()) {
for (PointerKey p : mod.get(node)) {
Statement h = new HeapStatement.ReturnCallee(node, p);
Statement h = new HeapStatement.HeapReturnCallee(node, p);
delegate.addNode(h);
list.add(h);
}
@ -834,13 +829,13 @@ public class PDG implements NumberedGraph<Statement> {
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref) {
ArrayList<Statement> list = new ArrayList<Statement>();
for (int i = 1; i <= node.getMethod().getNumberOfParameters(); i++) {
ParamStatement s = new ParamStatement.ParamCallee(node, i);
ParamCallee s = new ParamCallee(node, i);
delegate.addNode(s);
list.add(s);
}
if (!dOptions.isIgnoreHeap()) {
for (PointerKey p : ref.get(node)) {
Statement h = new HeapStatement.ParamCallee(node, p);
Statement h = new HeapStatement.HeapParamCallee(node, p);
delegate.addNode(h);
list.add(h);
}
@ -909,18 +904,18 @@ public class PDG implements NumberedGraph<Statement> {
Collection<Statement> params = MapUtil.findOrCreateSet(callerParamStatements, call.getCallSite());
Collection<Statement> rets = MapUtil.findOrCreateSet(callerReturnStatements, call.getCallSite());
for (int j = 0; j < call.getNumberOfUses(); j++) {
Statement st = new ParamStatement.ParamCaller(node, call, call.getUse(j));
Statement st = new ParamCaller(node, callIndex, call.getUse(j));
delegate.addNode(st);
params.add(st);
}
if (!call.getDeclaredResultType().equals(TypeReference.Void)) {
Statement st = new ParamStatement.NormalReturnCaller(node, call);
Statement st = new NormalReturnCaller(node, callIndex);
delegate.addNode(st);
rets.add(st);
}
{
if (!dOptions.isIgnoreExceptions()) {
Statement st = new ParamStatement.ExceptionalReturnCaller(node, call);
Statement st = new ExceptionalReturnCaller(node, callIndex);
delegate.addNode(st);
rets.add(st);
}
@ -929,13 +924,13 @@ public class PDG implements NumberedGraph<Statement> {
if (!dOptions.isIgnoreHeap()) {
OrdinalSet<PointerKey> uref = unionHeapLocations(cg, node, call, ref);
for (PointerKey p : uref) {
Statement st = new HeapStatement.ParamCaller(node, callIndex, p);
Statement st = new HeapStatement.HeapParamCaller(node, callIndex, p);
delegate.addNode(st);
params.add(st);
}
OrdinalSet<PointerKey> umod = unionHeapLocations(cg, node, call, mod);
for (PointerKey p : umod) {
Statement st = new HeapStatement.ReturnCaller(node, callIndex, p);
Statement st = new HeapStatement.HeapReturnCaller(node, callIndex, p);
delegate.addNode(st);
rets.add(st);
}

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
/**
* A {@link Statement} representing a formal parameter
*
* @author sjfink
*/
public class ParamCallee extends Statement implements ValueNumberCarrier {
/**
* Value number of the parameter
*/
protected final int valueNumber;
public ParamCallee(CGNode node, int valueNumber) {
super(node);
this.valueNumber = valueNumber;
}
@Override
public Kind getKind() {
return Kind.PARAM_CALLEE;
}
public int getValueNumber() {
return valueNumber;
}
@Override
public String toString() {
return super.toString() + " v" + valueNumber;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + valueNumber;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
final ParamCallee other = (ParamCallee) obj;
if (valueNumber != other.valueNumber)
return false;
return true;
}
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
/**
* A {@link Statement} representing an actual parameter
*
* @author sjfink
*/
public class ParamCaller extends StatementWithInstructionIndex {
/**
* Value number of the actual parameter
*/
protected final int valueNumber;
public ParamCaller(CGNode node, int callIndex, int valueNumber) {
super(node, callIndex);
this.valueNumber = valueNumber;
}
@Override
public Kind getKind() {
return Kind.PARAM_CALLER;
}
@Override
public SSAAbstractInvokeInstruction getInstruction() {
return (SSAAbstractInvokeInstruction)super.getInstruction();
}
@Override
public String toString() {
return super.toString() + " v" + getValueNumber();
}
public int getValueNumber() {
return valueNumber;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + valueNumber;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
final ParamCaller other = (ParamCaller) obj;
if (valueNumber != other.valueNumber)
return false;
return true;
}
}

View File

@ -1,273 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
/**
* Represents parameter-passing statement in the SDG
*
* @author sjfink
*
*/
public abstract class ParamStatement extends Statement {
public ParamStatement(CGNode node) {
super(node);
}
public interface ValueNumberCarrier {
public int getValueNumber();
}
public interface CallStatementCarrier {
public SSAAbstractInvokeInstruction getCall();
}
public static class ParamCaller extends ParamStatement implements ValueNumberCarrier, CallStatementCarrier {
private final SSAAbstractInvokeInstruction call;
protected final int valueNumber;
public ParamCaller(CGNode node, SSAAbstractInvokeInstruction call, int valueNumber) {
super(node);
this.call = call;
this.valueNumber = valueNumber;
}
@Override
public Kind getKind() {
return Kind.PARAM_CALLER;
}
public SSAAbstractInvokeInstruction getCall() {
return call;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode() + " call:" + call + " v" + getValueNumber();
}
public int getValueNumber() {
return valueNumber;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
ParamCaller other = (ParamCaller) obj;
return getNode().equals(other.getNode()) && valueNumber == other.valueNumber && call.getCallSite().equals(other.call.getCallSite());
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() + 17 * valueNumber + 23 * call.hashCode();
}
}
public static class ParamCallee extends ParamStatement implements ValueNumberCarrier {
protected final int valueNumber;
public ParamCallee(CGNode node, int valueNumber) {
super(node);
this.valueNumber = valueNumber;
}
@Override
public Kind getKind() {
return Kind.PARAM_CALLEE;
}
public int getValueNumber() {
return valueNumber;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
ParamCallee other = (ParamCallee) obj;
return getNode().equals(other.getNode()) && valueNumber == other.valueNumber;
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() + 97 * valueNumber;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode() + " v" + valueNumber;
}
}
public static class NormalReturnCaller extends ParamStatement implements ValueNumberCarrier, CallStatementCarrier {
private final SSAAbstractInvokeInstruction call;
protected final int valueNumber;
public NormalReturnCaller(CGNode node, SSAAbstractInvokeInstruction call) {
super(node);
this.call = call;
this.valueNumber = call.getDef();
}
@Override
public Kind getKind() {
return Kind.NORMAL_RET_CALLER;
}
public SSAAbstractInvokeInstruction getCall() {
return call;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode() + " call:" + call;
}
public int getValueNumber() {
return valueNumber;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
NormalReturnCaller other = (NormalReturnCaller) obj;
return getNode().equals(other.getNode()) && valueNumber == other.valueNumber && call.getCallSite().equals(other.call.getCallSite());
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() + 117 * valueNumber + 103 * call.hashCode();
}
}
public static class ExceptionalReturnCaller extends ParamStatement implements ValueNumberCarrier, CallStatementCarrier {
private final SSAAbstractInvokeInstruction call;
protected final int valueNumber;
public ExceptionalReturnCaller(CGNode node, SSAAbstractInvokeInstruction call) {
super(node);
this.call = call;
this.valueNumber = call.getException();
}
@Override
public Kind getKind() {
return Kind.EXC_RET_CALLER;
}
public SSAAbstractInvokeInstruction getCall() {
return call;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode() + " call:" + call;
}
public int getValueNumber() {
return valueNumber;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
ExceptionalReturnCaller other = (ExceptionalReturnCaller) obj;
return getNode().equals(other.getNode()) && valueNumber == other.valueNumber && call.getCallSite().equals(other.call.getCallSite());
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() + 1001 * valueNumber + 2003 * call.hashCode();
}
}
public static class NormalReturnCallee extends ParamStatement {
public NormalReturnCallee(CGNode node) {
super(node);
}
@Override
public Kind getKind() {
return Kind.NORMAL_RET_CALLEE;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
NormalReturnCallee other = (NormalReturnCallee) obj;
return getNode().equals(other.getNode());
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() * 89;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode();
}
}
public static class ExceptionalReturnCallee extends ParamStatement {
public ExceptionalReturnCallee(CGNode node) {
super(node);
}
@Override
public Kind getKind() {
return Kind.EXC_RET_CALLEE;
}
@Override
public boolean equals(Object obj) {
if (getClass().equals(obj.getClass())) {
ExceptionalReturnCallee other = (ExceptionalReturnCallee) obj;
return getNode().equals(other.getNode());
} else {
return false;
}
}
@Override
public int hashCode() {
return getNode().hashCode() * 89;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode();
}
}
}

View File

@ -283,13 +283,13 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
case CATCH:
return getPDG(N.getNode()).getPredNodes(N);
case EXC_RET_CALLER: {
ParamStatement.ExceptionalReturnCaller nrc = (ParamStatement.ExceptionalReturnCaller) N;
SSAAbstractInvokeInstruction call = nrc.getCall();
ExceptionalReturnCaller nrc = (ExceptionalReturnCaller) N;
SSAAbstractInvokeInstruction call = nrc.getInstruction();
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence predecessors
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
Statement s = new ParamStatement.ExceptionalReturnCallee(t);
Statement s = new ExceptionalReturnCallee(t);
addNode(s);
result.add(s);
}
@ -297,13 +297,13 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case NORMAL_RET_CALLER: {
ParamStatement.NormalReturnCaller nrc = (ParamStatement.NormalReturnCaller) N;
SSAAbstractInvokeInstruction call = nrc.getCall();
NormalReturnCaller nrc = (NormalReturnCaller) N;
SSAAbstractInvokeInstruction call = nrc.getInstruction();
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence predecessors
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
Statement s = new ParamStatement.NormalReturnCallee(t);
Statement s = new NormalReturnCallee(t);
addNode(s);
result.add(s);
}
@ -311,14 +311,14 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case HEAP_RET_CALLER: {
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) N;
HeapStatement.HeapReturnCaller r = (HeapStatement.HeapReturnCaller) N;
SSAAbstractInvokeInstruction call = r.getCall();
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence predecessors
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
if (mod.get(t).contains(r.getLocation())) {
Statement s = new HeapStatement.ReturnCallee(t, r.getLocation());
Statement s = new HeapStatement.HeapReturnCallee(t, r.getLocation());
addNode(s);
result.add(s);
}
@ -327,7 +327,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case PARAM_CALLEE: {
ParamStatement.ParamCallee pac = (ParamStatement.ParamCallee) N;
ParamCallee pac = (ParamCallee) N;
int parameterIndex = pac.getValueNumber() - 1;
Collection<Statement> result = HashSetFactory.make(5);
if (!dOptions.equals(DataDependenceOptions.NONE)) {
@ -348,7 +348,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
int i = ii.next();
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ir.getInstructions()[i];
int p = call.getUse(parameterIndex);
Statement s = new ParamStatement.ParamCaller(caller, call, p);
Statement s = new ParamCaller(caller, i, p);
addNode(s);
result.add(s);
}
@ -363,7 +363,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case HEAP_PARAM_CALLEE: {
HeapStatement.ParamCallee hpc = (HeapStatement.ParamCallee) N;
HeapStatement.HeapParamCallee hpc = (HeapStatement.HeapParamCallee) N;
Collection<Statement> result = HashSetFactory.make(5);
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence predecessors
@ -375,7 +375,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
IntSet indices = ir.getCallInstructionIndices(site);
for (IntIterator ii = indices.intIterator(); ii.hasNext();) {
int i = ii.next();
Statement s = new HeapStatement.ParamCaller(caller, i, hpc.getLocation());
Statement s = new HeapStatement.HeapParamCaller(caller, i, hpc.getLocation());
addNode(s);
result.add(s);
}
@ -461,8 +461,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
IntSet indices = ir.getCallInstructionIndices(site);
for (IntIterator ii = indices.intIterator(); ii.hasNext();) {
int i = ii.next();
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ir.getInstructions()[i];
Statement s = new ParamStatement.ExceptionalReturnCaller(caller, call);
// SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ir.getInstructions()[i];
Statement s = new ExceptionalReturnCaller(caller, i);
addNode(s);
result.add(s);
}
@ -483,8 +483,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
IntSet indices = ir.getCallInstructionIndices(site);
for (IntIterator ii = indices.intIterator(); ii.hasNext();) {
int i = ii.next();
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ir.getInstructions()[i];
Statement s = new ParamStatement.NormalReturnCaller(caller, call);
// SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ir.getInstructions()[i];
Statement s = new NormalReturnCaller(caller, i);
addNode(s);
result.add(s);
}
@ -494,7 +494,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case HEAP_RET_CALLEE: {
HeapStatement.ReturnCallee r = (HeapStatement.ReturnCallee) N;
HeapStatement.HeapReturnCallee r = (HeapStatement.HeapReturnCallee) N;
Collection<Statement> result = HashSetFactory.make(5);
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence predecessors
@ -506,7 +506,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
IntSet indices = ir.getCallInstructionIndices(site);
for (IntIterator ii = indices.intIterator(); ii.hasNext();) {
int i = ii.next();
Statement s = new HeapStatement.ReturnCaller(caller, i, r.getLocation());
Statement s = new HeapStatement.HeapReturnCaller(caller, i, r.getLocation());
addNode(s);
result.add(s);
}
@ -516,8 +516,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case PARAM_CALLER: {
ParamStatement.ParamCaller pac = (ParamStatement.ParamCaller) N;
SSAAbstractInvokeInstruction call = pac.getCall();
ParamCaller pac = (ParamCaller) N;
SSAAbstractInvokeInstruction call = pac.getInstruction();
Collection<Statement> result = HashSetFactory.make(5);
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence successors
@ -528,7 +528,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
continue;
}
if (call.getUse(i) == pac.getValueNumber()) {
Statement s = new ParamStatement.ParamCallee(t, i + 1);
Statement s = new ParamCallee(t, i + 1);
addNode(s);
result.add(s);
}
@ -538,14 +538,14 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return result.iterator();
}
case HEAP_PARAM_CALLER:
HeapStatement.ParamCaller pc = (HeapStatement.ParamCaller) N;
HeapStatement.HeapParamCaller pc = (HeapStatement.HeapParamCaller) N;
SSAAbstractInvokeInstruction call = pc.getCall();
Collection<Statement> result = HashSetFactory.make(5);
if (!dOptions.equals(DataDependenceOptions.NONE)) {
// data dependence successors
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
if (ref.get(t).contains(pc.getLocation())) {
Statement s = new HeapStatement.ParamCallee(t, pc.getLocation());
Statement s = new HeapStatement.HeapParamCallee(t, pc.getLocation());
addNode(s);
result.add(s);
}
@ -591,8 +591,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return false;
}
if (dst.getKind().equals(Kind.EXC_RET_CALLER)) {
ParamStatement.ExceptionalReturnCaller r = (ParamStatement.ExceptionalReturnCaller) dst;
return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
ExceptionalReturnCaller r = (ExceptionalReturnCaller) dst;
return cg.getPossibleTargets(r.getNode(), r.getInstruction().getCallSite()).contains(src.getNode());
} else {
return false;
}
@ -602,8 +602,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return false;
}
if (dst.getKind().equals(Kind.NORMAL_RET_CALLER)) {
ParamStatement.NormalReturnCaller r = (ParamStatement.NormalReturnCaller) dst;
return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
NormalReturnCaller r = (NormalReturnCaller) dst;
return cg.getPossibleTargets(r.getNode(), r.getInstruction().getCallSite()).contains(src.getNode());
} else {
return false;
}
@ -613,7 +613,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return false;
}
if (dst.getKind().equals(Kind.HEAP_RET_CALLER)) {
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) dst;
HeapStatement.HeapReturnCaller r = (HeapStatement.HeapReturnCaller) dst;
HeapStatement h = (HeapStatement) src;
return h.getLocation().equals(r.getLocation())
&& cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
@ -626,11 +626,11 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return false;
}
if (dst.getKind().equals(Kind.PARAM_CALLEE)) {
ParamStatement.ParamCallee callee = (ParamStatement.ParamCallee) dst;
ParamStatement.ParamCaller caller = (ParamStatement.ParamCaller) src;
ParamCallee callee = (ParamCallee) dst;
ParamCaller caller = (ParamCaller) src;
return caller.getValueNumber() == callee.getValueNumber()
&& cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode());
&& cg.getPossibleTargets(caller.getNode(), caller.getInstruction().getCallSite()).contains(callee.getNode());
} else {
return false;
}
@ -640,8 +640,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
return false;
}
if (dst.getKind().equals(Kind.HEAP_PARAM_CALLEE)) {
HeapStatement.ParamCallee callee = (HeapStatement.ParamCallee) dst;
HeapStatement.ParamCaller caller = (HeapStatement.ParamCaller) src;
HeapStatement.HeapParamCallee callee = (HeapStatement.HeapParamCallee) dst;
HeapStatement.HeapParamCaller caller = (HeapStatement.HeapParamCaller) src;
return caller.getLocation().equals(callee.getLocation())
&& cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode());

View File

@ -14,8 +14,6 @@ import java.util.Iterator;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.slicer.ParamStatement.ExceptionalReturnCaller;
import com.ibm.wala.ipa.slicer.ParamStatement.NormalReturnCaller;
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.util.collections.EmptyIterator;
@ -77,19 +75,19 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
public Iterator<? extends Statement> getCallSites(Statement r) {
switch (r.getKind()) {
case EXC_RET_CALLER: {
ParamStatement.ExceptionalReturnCaller n = (ExceptionalReturnCaller) r;
SSAAbstractInvokeInstruction call = n.getCall();
ExceptionalReturnCaller n = (ExceptionalReturnCaller) r;
SSAAbstractInvokeInstruction call = n.getInstruction();
PDG pdg = getProcOf(r);
return pdg.getCallerParamStatements(call).iterator();
}
case NORMAL_RET_CALLER: {
ParamStatement.NormalReturnCaller n = (NormalReturnCaller) r;
SSAAbstractInvokeInstruction call = n.getCall();
NormalReturnCaller n = (NormalReturnCaller) r;
SSAAbstractInvokeInstruction call = n.getInstruction();
PDG pdg = getProcOf(r);
return pdg.getCallerParamStatements(call).iterator();
}
case HEAP_RET_CALLER: {
HeapStatement.ReturnCaller n = (HeapStatement.ReturnCaller) r;
HeapStatement.HeapReturnCaller n = (HeapStatement.HeapReturnCaller) r;
SSAAbstractInvokeInstruction call = n.getCall();
PDG pdg = getProcOf(r);
return pdg.getCallerParamStatements(call).iterator();
@ -231,13 +229,13 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
public Iterator<? extends Statement> getReturnSites(Statement call) {
switch (call.getKind()) {
case PARAM_CALLER: {
ParamStatement.ParamCaller n = (ParamStatement.ParamCaller) call;
SSAAbstractInvokeInstruction st = n.getCall();
ParamCaller n = (ParamCaller) call;
SSAAbstractInvokeInstruction st = n.getInstruction();
PDG pdg = getProcOf(call);
return pdg.getCallerReturnStatements(st).iterator();
}
case HEAP_PARAM_CALLER: {
HeapStatement.ParamCaller n = (HeapStatement.ParamCaller) call;
HeapStatement.HeapParamCaller n = (HeapStatement.HeapParamCaller) call;
SSAAbstractInvokeInstruction st = n.getCall();
PDG pdg = getProcOf(call);
return pdg.getCallerReturnStatements(st).iterator();

View File

@ -33,16 +33,39 @@ public abstract class Statement {
public abstract Kind getKind();
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
@Override
public abstract String toString();
public CGNode getNode() {
return node;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((node == null) ? 0 : node.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Statement other = (Statement) obj;
if (node == null) {
if (other.node != null)
return false;
} else if (!node.equals(other.node))
return false;
return true;
}
@Override
public String toString() {
return getKind().toString() + ":" + getNode();
}
}

View File

@ -0,0 +1,67 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.SSAInstruction;
/**
* A {@link Statement} which carries an instruction index, representing the
* index of an {@link SSAInstruction} in the IR instruction array.
*
* @author sjfink
*
*/
public abstract class StatementWithInstructionIndex extends Statement {
private final int instructionIndex;
protected StatementWithInstructionIndex(CGNode node, int instructionIndex) {
super(node);
this.instructionIndex = instructionIndex;
}
public int getInstructionIndex() {
return instructionIndex;
}
public SSAInstruction getInstruction() {
return getNode().getIR().getInstructions()[instructionIndex];
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + instructionIndex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
final StatementWithInstructionIndex other = (StatementWithInstructionIndex) obj;
if (instructionIndex != other.instructionIndex)
return false;
return true;
}
@Override
public String toString() {
return super.toString() + "[" + getInstructionIndex() + "]" + getInstruction();
}
}

View File

@ -0,0 +1,16 @@
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ipa.slicer;
public interface ValueNumberCarrier {
int getValueNumber();
}