soot.jimple.toolkits.scalar.EqualLocalsAnalysis Maven / Gradle / Ivy
package soot.jimple.toolkits.scalar;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
* %%
* 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.ArrayList;
import java.util.Iterator;
import java.util.List;
import soot.EquivalentValue;
import soot.Local;
import soot.Value;
import soot.ValueBox;
import soot.jimple.DefinitionStmt;
import soot.jimple.IdentityStmt;
import soot.jimple.Stmt;
import soot.toolkits.graph.UnitGraph;
import soot.toolkits.scalar.ArraySparseSet;
import soot.toolkits.scalar.FlowSet;
import soot.toolkits.scalar.ForwardFlowAnalysis;
// EqualLocalsAnalysis written by Richard L. Halpert, 2006-12-04
// Finds equal/equavalent/aliasing locals to a given local at a given statement, on demand
// The answer provided is occasionally suboptimal (but correct) in the event where
// a _re_definition of the given local causes it to become equal to existing locals.
public class EqualLocalsAnalysis extends ForwardFlowAnalysis {
Local l;
Stmt s;
public EqualLocalsAnalysis(UnitGraph g) {
super(g);
l = null;
s = null;
// analysis is done on-demand, not now
}
/** Returns a list of EquivalentValue wrapped Locals and Refs that must always be equal to l at s */
public List getCopiesOfAt(Local l, Stmt s) {
this.l = l;
this.s = s;
doAnalysis();
FlowSet fs = (FlowSet) getFlowBefore(s);
List aliasList = new ArrayList(fs.size());
for (Object o : fs) {
aliasList.add(o);
}
if (aliasList.contains(new EquivalentValue(l))) {
return aliasList;
}
return new ArrayList();
}
protected void merge(Object in1, Object in2, Object out) {
FlowSet inSet1 = (FlowSet) in1;
FlowSet inSet2 = (FlowSet) in2;
FlowSet outSet = (FlowSet) out;
inSet1.intersection(inSet2, outSet);
}
protected void flowThrough(Object inValue, Object unit, Object outValue) {
FlowSet in = (FlowSet) inValue;
FlowSet out = (FlowSet) outValue;
Stmt stmt = (Stmt) unit;
in.copy(out);
// get list of definitions at this unit
List newDefs = new ArrayList();
Iterator newDefBoxesIt = stmt.getDefBoxes().iterator();
while (newDefBoxesIt.hasNext()) {
newDefs.add(new EquivalentValue(((ValueBox) newDefBoxesIt.next()).getValue()));
}
// If the local of interest was defined in this statement, then we must
// generate a new list of aliases to it starting here
if (newDefs.contains(new EquivalentValue(l))) {
List