From 2a1213789bd0c632218ad68d8119c6ad531c91ff Mon Sep 17 00:00:00 2001 From: sjfink Date: Tue, 13 Nov 2007 16:19:15 +0000 Subject: [PATCH] add CancelException to interact with Eclipse progress monitors and thread it through some APIs git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2006 f5eafffb-2e1d-0410-98e4-8ec43c5233c4 --- .../client/impl/AbstractAnalysisEngine.java | 9 ++- .../wala/dataflow/IFDS/TabulationSolver.java | 43 +++++--------- .../util/CancelException.java} | 23 +++++--- .../ibm/wala/eclipse/util/MonitorUtil.java | 58 +++++++++++++++++++ .../wala/ipa/callgraph/CallGraphBuilder.java | 5 +- .../propagation/AbstractPointsToSolver.java | 4 +- .../propagation/IPointsToSolver.java | 4 +- .../propagation/PreTransitiveSolver.java | 3 +- .../PropagationCallGraphBuilder.java | 3 +- .../propagation/ReflectionHandler.java | 5 +- .../callgraph/propagation/StandardSolver.java | 3 +- .../src/com/ibm/wala/ipa/slicer/Slicer.java | 34 ++++++----- 12 files changed, 134 insertions(+), 60 deletions(-) rename com.ibm.wala.core/src/com/ibm/wala/{dataflow/IFDS/SolverInterruptedException.java => eclipse/util/CancelException.java} (55%) create mode 100644 com.ibm.wala.core/src/com/ibm/wala/eclipse/util/MonitorUtil.java diff --git a/com.ibm.wala.core/src/com/ibm/wala/client/impl/AbstractAnalysisEngine.java b/com.ibm.wala.core/src/com/ibm/wala/client/impl/AbstractAnalysisEngine.java index 1f4dbbea6..b23fd91ae 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/client/impl/AbstractAnalysisEngine.java +++ b/com.ibm.wala.core/src/com/ibm/wala/client/impl/AbstractAnalysisEngine.java @@ -22,6 +22,7 @@ import com.ibm.wala.classLoader.JarFileModule; import com.ibm.wala.classLoader.Module; import com.ibm.wala.client.AnalysisEngine; import com.ibm.wala.client.CallGraphBuilderFactory; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.emf.wrappers.EMFScopeWrapper; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.callgraph.AnalysisOptions; @@ -149,7 +150,7 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine { return getCallGraphBuilderFactory().make(options, cache, cha, getScope(), false); } - protected CallGraphBuilder buildCallGraph(IClassHierarchy cha, AnalysisOptions options, boolean savePointerAnalysis) { + protected CallGraphBuilder buildCallGraph(IClassHierarchy cha, AnalysisOptions options, boolean savePointerAnalysis) throws IllegalArgumentException, CancelException { Assertions.productionAssertion(getCallGraphBuilderFactory() != null, "must initialize callGraphBuilderFactory!"); CallGraphBuilder builder = getCallGraphBuilder(cha, options, cache); @@ -349,8 +350,10 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine { /** * Builds the call graph for the analysis scope in effect, using all of the * given entry points. + * @throws CancelException + * @throws IllegalArgumentException */ - public CallGraphBuilder defaultCallGraphBuilder() { + public CallGraphBuilder defaultCallGraphBuilder() throws IllegalArgumentException, CancelException { buildAnalysisScope(); IClassHierarchy cha = buildClassHierarchy(); setClassHierarchy(cha); @@ -360,7 +363,7 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine { return buildCallGraph(cha, options, true); } - public CallGraph buildDefaultCallGraph() { + public CallGraph buildDefaultCallGraph() throws IllegalArgumentException, CancelException { return defaultCallGraphBuilder().makeCallGraph(options); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/TabulationSolver.java b/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/TabulationSolver.java index 29768cd83..776d41ab5 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/TabulationSolver.java +++ b/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/TabulationSolver.java @@ -20,7 +20,11 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; +import org.eclipse.core.runtime.IProgressMonitor; + import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.eclipse.util.CancelException; +import com.ibm.wala.eclipse.util.MonitorUtil; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.util.ReferenceCleanser; import com.ibm.wala.util.collections.HashMapFactory; @@ -120,16 +124,6 @@ public class TabulationSolver { } }; - /** - * solver allows interruption - */ - static protected final boolean INTERRUPTIBLE = true; - - /** - * how frequently to check for interruption? - */ - static final private int INTERRUPT_LATENCY = 20; - /** * The supergraph which induces this dataflow problem */ @@ -173,6 +167,11 @@ public class TabulationSolver { * The worklist */ final protected Worklist worklist = new Worklist(); + + /** + * A progress monitor. can be null. + */ + private final IProgressMonitor progressMonitor; /** * @param p @@ -180,7 +179,7 @@ public class TabulationSolver { * @throws IllegalArgumentException * if p is null */ - protected TabulationSolver(TabulationProblem p) { + protected TabulationSolver(TabulationProblem p, IProgressMonitor monitor) { if (p == null) { throw new IllegalArgumentException("p is null"); } @@ -191,6 +190,7 @@ public class TabulationSolver { this.flowFunctionMap = IdentityFlowFunctions.singleton(); } this.problem = p; + this.progressMonitor = monitor; } /** @@ -200,16 +200,15 @@ public class TabulationSolver { * if p is null */ public static TabulationSolver make(TabulationProblem p) { - return new TabulationSolver(p); + return new TabulationSolver(p, null); } /** * Solve the dataflow problem. * * @return a representation of the result - * @throws SolverInterruptedException */ - public TabulationResult solve() throws SolverInterruptedException { + public TabulationResult solve() throws CancelException { EngineTimings.startVirtual("TabulationSolver.solve()"); EngineTimings.startVirtual("TabulationSolver.initialize"); @@ -244,27 +243,17 @@ public class TabulationSolver { /** * See POPL 95 paper for this algorithm, Figure 3 * - * @throws SolverInterruptedException + * @throws CancelException */ - private void forwardTabulateSLRPs() throws SolverInterruptedException { - int interrupt = 0; + private void forwardTabulateSLRPs() throws CancelException { while (worklist.size() > 0) { + MonitorUtil.throwExceptionIfCanceled(progressMonitor); if (verbose) { performVerboseAction(); } if (PERIODIC_WIPE_SOFT_CACHES) { tendToSoftCaches(); } - if (INTERRUPTIBLE) { - // checking Thread.interrupted is expensive. Don't do it every time. - interrupt++; - if (interrupt % INTERRUPT_LATENCY == 0) { - interrupt = 0; - if (Thread.interrupted()) { - throw new SolverInterruptedException(); - } - } - } final PathEdge edge = popFromWorkList(); if (DEBUG_LEVEL > 0) { diff --git a/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/SolverInterruptedException.java b/com.ibm.wala.core/src/com/ibm/wala/eclipse/util/CancelException.java similarity index 55% rename from com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/SolverInterruptedException.java rename to com.ibm.wala.core/src/com/ibm/wala/eclipse/util/CancelException.java index dbe0154e3..d45230b28 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/dataflow/IFDS/SolverInterruptedException.java +++ b/com.ibm.wala.core/src/com/ibm/wala/eclipse/util/CancelException.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002 - 2006 IBM Corporation. + * 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 @@ -8,13 +8,22 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package com.ibm.wala.dataflow.IFDS; +package com.ibm.wala.eclipse.util; -public class SolverInterruptedException extends Exception { +/** + * An exception for when work is canceled in eclipse. + * + * @author sjfink + * + */ +public class CancelException extends Exception { - /** - * UID - */ - private static final long serialVersionUID = -32488844370356591L; + private CancelException(String msg) { + super(msg); + } + + public static CancelException make(String msg) { + return new CancelException(msg); + } } diff --git a/com.ibm.wala.core/src/com/ibm/wala/eclipse/util/MonitorUtil.java b/com.ibm.wala.core/src/com/ibm/wala/eclipse/util/MonitorUtil.java new file mode 100644 index 000000000..b43de6958 --- /dev/null +++ b/com.ibm.wala.core/src/com/ibm/wala/eclipse/util/MonitorUtil.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.eclipse.util; + +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Simple utilities for Eclipse progress monitors + * + * @author sjfink + * + */ +public class MonitorUtil { + + public static void beginTask(IProgressMonitor monitor, String task, int totalWork) throws CancelException { + if (monitor != null) { + monitor.beginTask(task, totalWork); + if (monitor.isCanceled()) { + throw CancelException.make("cancelled in " + task); + } + } + } + + public static void done(IProgressMonitor monitor) throws CancelException { + if (monitor != null) { + monitor.done(); + if (monitor.isCanceled()) { + throw CancelException.make("cancelled in " + monitor.toString()); + } + } + } + + public static void worked(IProgressMonitor monitor, int units) throws CancelException { + if (monitor != null) { + monitor.worked(units); + if (monitor.isCanceled()) { + throw CancelException.make("cancelled in " + monitor.toString()); + } + } + } + + public static void throwExceptionIfCanceled(IProgressMonitor progressMonitor) throws CancelException { + if (progressMonitor != null) { + if (progressMonitor.isCanceled()) { + throw CancelException.make("operation cancelled"); + } + } + } +} diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraphBuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraphBuilder.java index d15160faa..0fc4add89 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraphBuilder.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraphBuilder.java @@ -10,6 +10,7 @@ *******************************************************************************/ package com.ibm.wala.ipa.callgraph; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ipa.callgraph.propagation.PointerFlowGraphFactory; @@ -27,8 +28,10 @@ public interface CallGraphBuilder { * @param options an object representing controlling options that the call * graph building algorithm needs to know. * @return the built call graph + * @throws CancelException + * @throws IllegalArgumentException */ - public CallGraph makeCallGraph(AnalysisOptions options); + public CallGraph makeCallGraph(AnalysisOptions options) throws IllegalArgumentException, CancelException; /** * @return the Pointer Analysis information computed as a side-effect of diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/AbstractPointsToSolver.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/AbstractPointsToSolver.java index 057fe15bf..30194ed9a 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/AbstractPointsToSolver.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/AbstractPointsToSolver.java @@ -10,6 +10,8 @@ *******************************************************************************/ package com.ibm.wala.ipa.callgraph.propagation; +import com.ibm.wala.eclipse.util.CancelException; + /** * abstract base class for solver for pointer analysis @@ -35,7 +37,7 @@ public abstract class AbstractPointsToSolver implements IPointsToSolver { /* * @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve() */ - public abstract void solve(); + public abstract void solve() throws IllegalArgumentException, CancelException; protected PropagationCallGraphBuilder getBuilder() { return builder; diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/IPointsToSolver.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/IPointsToSolver.java index fbea25dc3..169896ea4 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/IPointsToSolver.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/IPointsToSolver.java @@ -10,11 +10,13 @@ *******************************************************************************/ package com.ibm.wala.ipa.callgraph.propagation; +import com.ibm.wala.eclipse.util.CancelException; + /** * @author sfink * */ public interface IPointsToSolver { - public void solve(); + public void solve() throws IllegalArgumentException, CancelException; } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PreTransitiveSolver.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PreTransitiveSolver.java index 487044e0c..92639354f 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PreTransitiveSolver.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PreTransitiveSolver.java @@ -15,6 +15,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.Iterator; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.fixedpoint.impl.AbstractFixedPointSolver; import com.ibm.wala.fixedpoint.impl.AbstractStatement; import com.ibm.wala.fixedpoint.impl.UnaryStatement; @@ -61,7 +62,7 @@ public class PreTransitiveSolver extends AbstractPointsToSolver { * @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve() */ @Override - public void solve() { + public void solve() throws IllegalArgumentException, CancelException { EngineTimings.startVirtual("PreTransitiveSolver.solve()"); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java index 503396937..658aa504b 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PropagationCallGraphBuilder.java @@ -23,6 +23,7 @@ import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.classLoader.Language; import com.ibm.wala.classLoader.NewSiteReference; import com.ibm.wala.classLoader.SyntheticClass; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.fixedpoint.impl.UnaryOperator; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.callgraph.AnalysisOptions; @@ -258,7 +259,7 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder { /* * @see com.ibm.wala.ipa.callgraph.CallGraphBuilder#makeCallGraph(com.ibm.wala.ipa.callgraph.AnalysisOptions) */ - public CallGraph makeCallGraph(AnalysisOptions options) { + public CallGraph makeCallGraph(AnalysisOptions options) throws IllegalArgumentException, CancelException { if (options == null) { throw new IllegalArgumentException("options is null"); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/ReflectionHandler.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/ReflectionHandler.java index f592c4d0b..0eaf882cf 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/ReflectionHandler.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/ReflectionHandler.java @@ -17,6 +17,7 @@ import java.util.Set; import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.SyntheticMethod; +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; @@ -60,8 +61,10 @@ public class ReflectionHandler { * results to checkcasts * * @return true if anything has changed + * @throws CancelException + * @throws IllegalArgumentException */ - protected boolean updateForReflection() { + protected boolean updateForReflection() throws IllegalArgumentException, CancelException { EngineTimings.startVirtual("ReflectionHandler.updateForReflection()"); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/StandardSolver.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/StandardSolver.java index 3df7694e5..9302fdbd7 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/StandardSolver.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/StandardSolver.java @@ -10,6 +10,7 @@ *******************************************************************************/ package com.ibm.wala.ipa.callgraph.propagation; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.util.debug.Trace; import com.ibm.wala.util.perf.EngineTimings; @@ -33,7 +34,7 @@ public class StandardSolver extends AbstractPointsToSolver { * @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve() */ @Override - public void solve() { + public void solve() throws IllegalArgumentException, CancelException { EngineTimings.startVirtual("StandardSolver.solve()"); int i = 0; diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java index 0543e7b16..480985981 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java @@ -18,11 +18,11 @@ import com.ibm.wala.dataflow.IFDS.BackwardsSupergraph; import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap; import com.ibm.wala.dataflow.IFDS.IMergeFunction; import com.ibm.wala.dataflow.IFDS.ISupergraph; -import com.ibm.wala.dataflow.IFDS.SolverInterruptedException; import com.ibm.wala.dataflow.IFDS.TabulationDomain; import com.ibm.wala.dataflow.IFDS.TabulationProblem; import com.ibm.wala.dataflow.IFDS.TabulationResult; import com.ibm.wala.dataflow.IFDS.TabulationSolver; +import com.ibm.wala.eclipse.util.CancelException; import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ipa.modref.ModRef; @@ -147,9 +147,10 @@ public class Slicer { * @param s * a statement of interest * @return the backward slice of s. + * @throws CancelException */ public static Collection computeBackwardSlice(Statement s, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException { return computeSlice(null, Collections.singleton(s), cg, pa, dOptions, cOptions, true); } @@ -157,47 +158,52 @@ public class Slicer { * @param s * a statement of interest * @return the forward slice of s. + * @throws CancelException */ public static Collection computeForwardSlice(Statement s, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException { return computeSlice(null, Collections.singleton(s), cg, pa, dOptions, cOptions, false); } /** * Use the passed-in SDG + * @throws CancelException */ public static Collection computeBackwardSlice(SDG sdg, Statement s, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException { return computeSlice(sdg, Collections.singleton(s), cg, pa, dOptions, cOptions, true); } /** * Use the passed-in SDG + * @throws CancelException */ public static Collection computeForwardSlice(SDG sdg, Statement s, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException { return computeSlice(sdg, Collections.singleton(s), cg, pa, dOptions, cOptions, false); } /** * Use the passed-in SDG + * @throws CancelException */ public static Collection computeBackwardSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException { return computeSlice(sdg, ss, cg, pa, dOptions, cOptions, true); } /** * @param ss * a collection of statements of interest + * @throws CancelException */ protected static Collection computeSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) throws CancelException { return computeSlice(sdg, ss, cg, pa, ModRef.make(), dOptions, cOptions, backward); } protected static Collection computeSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, ModRef modRef, - DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) { + DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) throws CancelException { if (VERBOSE) { System.err.println("Build SDG..."); @@ -227,13 +233,8 @@ public class Slicer { } TabulationSolver solver = TabulationSolver.make(p); - TabulationResult tr = null; - try { - tr = solver.solve(); - } catch (SolverInterruptedException e) { - e.printStackTrace(); - Assertions.UNREACHABLE(); - } + TabulationResult tr = solver.solve(); + if (DEBUG) { System.err.println("RESULT"); System.err.println(tr); @@ -361,9 +362,10 @@ public class Slicer { * @param s * a statement of interest * @return the backward slice of s. + * @throws CancelException */ public static Collection computeBackwardSlice(Statement s, CallGraph cg, PointerAnalysis pointerAnalysis) - throws IllegalArgumentException { + throws IllegalArgumentException, CancelException { return computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL, ControlDependenceOptions.FULL); }