-
-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #664 from soot-oss/add/intraprocedural
port intraprocedural analysis and fix the long tail..
- Loading branch information
Showing
209 changed files
with
4,541 additions
and
2,739 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
sootup.analysis/src/main/java/sootup/analysis/intraprocedural/AbstractFlowAnalysis.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
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 | ||
* <http://www.gnu.org/licenses/lgpl-2.1.html>. | ||
* #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 <F> abstraction type for the Facts | ||
*/ | ||
public abstract class AbstractFlowAnalysis<F> { | ||
|
||
/** The graph being analysed. */ | ||
protected final StmtGraph<? extends BasicBlock<?>> graph; | ||
|
||
/** Maps graph nodes to IN sets. */ | ||
protected final Map<Stmt, F> stmtToBeforeFlow; | ||
|
||
/** Constructs a flow analysis on the given <code>StmtGraph</code>. */ | ||
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 <code>entryInitialFlow()</code> 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 <code>in1</code> and <code>in2</code> sets, putting the result into | ||
* <code>out</code>. The behavior of this function depends on the implementation ( it may be | ||
* necessary to check whether <code>in1</code> and <code>in2</code> 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 <code>source</code> flow object in <code>dest</code>. */ | ||
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); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
sootup.analysis/src/main/java/sootup/analysis/intraprocedural/Fact.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package sootup.analysis.intraprocedural; | ||
|
||
import java.util.HashSet; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import javax.annotation.Nonnull; | ||
import sootup.core.jimple.basic.Local; | ||
|
||
/** simple dataflow fact for interprocedural dataflow analysis adaptable with a state enum * */ | ||
public class Fact<S> { | ||
|
||
/** The aliases that point to the same object. */ | ||
@Nonnull private final Set<Local> aliases; | ||
|
||
/** The state of the object. */ | ||
@Nonnull private S state; | ||
|
||
public Fact(@Nonnull S initialState) { | ||
this(new HashSet<>(), initialState); | ||
} | ||
|
||
public Fact(@Nonnull Fact<S> originFact) { | ||
this(new HashSet<>(originFact.aliases), originFact.state); | ||
} | ||
|
||
protected Fact(@Nonnull Set<Local> aliases, @Nonnull S initialState) { | ||
this.aliases = aliases; | ||
this.state = initialState; | ||
} | ||
|
||
public void updateState(@Nonnull S state) { | ||
this.state = state; | ||
} | ||
|
||
public void addAlias(@Nonnull Local alias) { | ||
this.aliases.add(alias); | ||
} | ||
|
||
public boolean containsAlias(@Nonnull Local value) { | ||
return aliases.contains(value); | ||
} | ||
|
||
@Nonnull | ||
public S getState() { | ||
return state; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "(" + aliases + ", " + state + ")"; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(aliases, state); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
|
||
Fact other = (Fact) obj; | ||
if (!aliases.equals(other.aliases)) { | ||
return false; | ||
} | ||
|
||
return state == other.state; | ||
} | ||
} |
Oops, something went wrong.