sootup.analysis.intraprocedural.AbstractFlowAnalysis Maven / Gradle / Ivy
package sootup.analysis.intraprocedural;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 1999 Raja Vallee-Rai
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.IdentityHashMap;
import java.util.Map;
import javax.annotation.Nonnull;
import sootup.core.graph.BasicBlock;
import sootup.core.graph.StmtGraph;
import sootup.core.jimple.common.stmt.Stmt;
/**
* An abstract class providing a meta-framework for carrying out dataflow analysis. This class
* provides common methods and fields required by the BranchedFlowAnalysis and FlowAnalysis abstract
* classes.
*
* @param abstraction type for the Facts
*/
public abstract class AbstractFlowAnalysis {
/** The graph being analysed. */
protected final StmtGraph extends BasicBlock>> graph;
/** Maps graph nodes to IN sets. */
protected final Map stmtToBeforeFlow;
/** Constructs a flow analysis on the given StmtGraph
. */
public AbstractFlowAnalysis(StmtGraph extends BasicBlock>> graph) {
this.graph = graph;
this.stmtToBeforeFlow = new IdentityHashMap<>(graph.getNodes().size() * 2 + 1);
}
/** Returns the flow object corresponding to the initial values for each graph node. */
@Nonnull
protected abstract F newInitialFlow();
/** Determines whether entryInitialFlow()
is applied to trap handlers. */
// FIXME: [ms] implement as an option
protected boolean treatTrapHandlersAsEntries() {
return false;
}
/** Returns true if this analysis is forwards. */
protected abstract boolean isForward();
/**
* Compute the merge of the in1
and in2
sets, putting the result into
* out
. The behavior of this function depends on the implementation ( it may be
* necessary to check whether in1
and in2
are equal or aliased ). Used
* by the doAnalysis method.
*/
protected abstract void merge(@Nonnull F in1, @Nonnull F in2, @Nonnull F out);
/**
* Merges in1 and in2 into out, just before node succNode. By default, this method just calls
* merge(A,A,A), ignoring the node.
*/
protected void merge(@Nonnull Stmt succNode, @Nonnull F in1, @Nonnull F in2, @Nonnull F out) {
merge(in1, in2, out);
}
/** Creates a copy of the source
flow object in dest
. */
protected abstract void copy(@Nonnull F source, @Nonnull F dest);
/**
* Carries out the actual flow analysis. Typically called from a concrete FlowAnalysis's
* constructor.
*/
protected abstract void execute();
/** Accessor function returning value of IN set for s. */
@Nonnull
public F getFlowBefore(@Nonnull Stmt s) {
return stmtToBeforeFlow.get(s);
}
/** Merges in into inout, just before node succNode. */
protected void mergeInto(@Nonnull Stmt succNode, @Nonnull F inout, @Nonnull F in) {
F tmp = newInitialFlow();
merge(succNode, inout, in, tmp);
copy(tmp, inout);
}
}