use of soot.Unit in project soot by Sable.
the class JimpleLocal method convertToBaf.
@Override
public void convertToBaf(JimpleToBafContext context, List<Unit> out) {
Unit u = Baf.v().newLoadInst(getType(), context.getBafLocalOfJimpleLocal(this));
u.addAllTagsOf(context.getCurrentUnit());
out.add(u);
}
use of soot.Unit in project soot by Sable.
the class ArrayIndexLivenessAnalysis method getGenAndKillSet.
private void getGenAndKillSet(Body body, HashMap<Stmt, HashSet<Value>> absgen, HashMap<Stmt, HashSet<Object>> gen, HashMap<Stmt, HashSet<Value>> kill, HashMap<Stmt, HashSet<Value>> condition) {
for (Unit u : body.getUnits()) {
Stmt stmt = (Stmt) u;
HashSet<Object> genset = new HashSet<Object>();
HashSet<Value> absgenset = new HashSet<Value>();
HashSet<Value> killset = new HashSet<Value>();
HashSet<Value> condset = new HashSet<Value>();
if (stmt instanceof DefinitionStmt) {
getGenAndKillSetForDefnStmt((DefinitionStmt) stmt, absgen, genset, absgenset, killset, condset);
} else if (stmt instanceof IfStmt) {
/* if one of condition is living, than other one is live. */
Value cmpcond = ((IfStmt) stmt).getCondition();
if (cmpcond instanceof ConditionExpr) {
Value op1 = ((ConditionExpr) cmpcond).getOp1();
Value op2 = ((ConditionExpr) cmpcond).getOp2();
if (fullSet.contains(op1) && fullSet.contains(op2)) {
condset.add(op1);
condset.add(op2);
genset.add(op1);
genset.add(op2);
}
}
}
if (genset.size() != 0)
gen.put(stmt, genset);
if (absgenset.size() != 0)
absgen.put(stmt, absgenset);
if (killset.size() != 0)
kill.put(stmt, killset);
if (condset.size() != 0)
condition.put(stmt, condset);
}
}
use of soot.Unit in project soot by Sable.
the class MultiRunStatementsFinder method findMultiCalledMethodsIntra.
private void findMultiCalledMethodsIntra(Set<SootMethod> multiCalledMethods, CallGraph callGraph) {
Iterator<Unit> it = multiRunStatements.iterator();
while (it.hasNext()) {
Stmt stmt = (Stmt) it.next();
if (stmt.containsInvokeExpr()) {
InvokeExpr invokeExpr = stmt.getInvokeExpr();
List<SootMethod> targetList = new ArrayList<SootMethod>();
SootMethod method = invokeExpr.getMethod();
if (invokeExpr instanceof StaticInvokeExpr) {
targetList.add(method);
} else if (invokeExpr instanceof InstanceInvokeExpr) {
if (method.isConcrete() && !method.getDeclaringClass().isLibraryClass()) {
TargetMethodsFinder tmd = new TargetMethodsFinder();
targetList = tmd.find(stmt, callGraph, true, true);
}
}
if (targetList != null) {
Iterator<SootMethod> iterator = targetList.iterator();
while (iterator.hasNext()) {
SootMethod obj = iterator.next();
if (!obj.isNative()) {
multiCalledMethods.add(obj);
}
}
}
}
}
}
use of soot.Unit in project soot by Sable.
the class DeadAssignmentEliminator method internalTransform.
/**
* Eliminates dead code in a linear fashion. Complexity is linear
* with respect to the statements.
*
* Does not work on grimp code because of the check on the right hand
* side for side effects.
*/
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
boolean eliminateOnlyStackLocals = PhaseOptions.getBoolean(options, "only-stack-locals");
final Options soptions = Options.v();
if (soptions.verbose()) {
logger.debug("[" + b.getMethod().getName() + "] Eliminating dead code...");
}
if (soptions.time()) {
Timers.v().deadCodeTimer.start();
}
Chain<Unit> units = b.getUnits();
Deque<Unit> q = new ArrayDeque<Unit>(units.size());
// Make a first pass through the statements, noting
// the statements we must absolutely keep.
boolean isStatic = b.getMethod().isStatic();
boolean allEssential = true;
boolean checkInvoke = false;
Local thisLocal = null;
for (Iterator<Unit> it = units.iterator(); it.hasNext(); ) {
Unit s = it.next();
boolean isEssential = true;
if (s instanceof NopStmt) {
// Hack: do not remove nop if is is used for a Trap
// which is at the very end of the code.
boolean removeNop = it.hasNext();
if (!removeNop) {
removeNop = true;
for (Trap t : b.getTraps()) {
if (t.getEndUnit() == s) {
removeNop = false;
break;
}
}
}
if (removeNop) {
it.remove();
continue;
}
} else if (s instanceof AssignStmt) {
AssignStmt as = (AssignStmt) s;
Value lhs = as.getLeftOp();
Value rhs = as.getRightOp();
// Stmt is of the form a = a which is useless
if (lhs == rhs && lhs instanceof Local) {
it.remove();
continue;
}
if (lhs instanceof Local && (!eliminateOnlyStackLocals || ((Local) lhs).getName().startsWith("$") || lhs.getType() instanceof NullType)) {
isEssential = false;
if (!checkInvoke) {
checkInvoke = as.containsInvokeExpr();
}
if (rhs instanceof CastExpr) {
// CastExpr : can trigger ClassCastException, but null-casts never fail
CastExpr ce = (CastExpr) rhs;
Type t = ce.getCastType();
Value v = ce.getOp();
isEssential = !(v instanceof NullConstant && t instanceof RefType);
} else if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef || rhs instanceof NewExpr || rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
// ArrayRef : can have side effects (like throwing a null pointer exception)
// InvokeExpr : can have side effects (like throwing a null pointer exception)
// NewArrayExpr : can throw exception
// NewMultiArrayExpr : can throw exception
// NewExpr : can trigger class initialization
isEssential = true;
} else if (rhs instanceof FieldRef) {
// Can trigger class initialization
isEssential = true;
if (rhs instanceof InstanceFieldRef) {
InstanceFieldRef ifr = (InstanceFieldRef) rhs;
if (!isStatic && thisLocal == null) {
thisLocal = b.getThisLocal();
}
// Any InstanceFieldRef may have side effects,
// unless the base is reading from 'this'
// in a non-static method
isEssential = (isStatic || thisLocal != ifr.getBase());
}
} else if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
BinopExpr expr = (BinopExpr) rhs;
Type t1 = expr.getOp1().getType();
Type t2 = expr.getOp2().getType();
// Can trigger a division by zero
boolean t2Int = t2 instanceof IntType;
isEssential = t2Int || t1 instanceof IntType || t1 instanceof LongType || t2 instanceof LongType || t1 instanceof UnknownType || t2 instanceof UnknownType;
if (isEssential && t2Int) {
Value v = expr.getOp2();
if (v instanceof IntConstant) {
IntConstant i = (IntConstant) v;
isEssential = (i.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
if (isEssential && t2 instanceof LongType) {
Value v = expr.getOp2();
if (v instanceof LongConstant) {
LongConstant l = (LongConstant) v;
isEssential = (l.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
}
}
}
if (isEssential) {
q.addFirst(s);
}
allEssential &= isEssential;
}
if (checkInvoke || !allEssential) {
// Add all the statements which are used to compute values
// for the essential statements, recursively
final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b);
if (!allEssential) {
Set<Unit> essential = new HashSet<Unit>(b.getUnits().size());
while (!q.isEmpty()) {
Unit s = q.removeFirst();
if (essential.add(s)) {
for (ValueBox box : s.getUseBoxes()) {
Value v = box.getValue();
if (v instanceof Local) {
Local l = (Local) v;
List<Unit> defs = localDefs.getDefsOfAt(l, s);
if (defs != null)
q.addAll(defs);
}
}
}
}
// Remove the dead statements
units.retainAll(essential);
}
if (checkInvoke) {
final LocalUses localUses = LocalUses.Factory.newLocalUses(b, localDefs);
// Eliminate dead assignments from invokes such as x = f(), where
// x is no longer used
List<AssignStmt> postProcess = new ArrayList<AssignStmt>();
for (Unit u : units) {
if (u instanceof AssignStmt) {
AssignStmt s = (AssignStmt) u;
if (s.containsInvokeExpr()) {
// Just find one use of l which is essential
boolean deadAssignment = true;
for (UnitValueBoxPair pair : localUses.getUsesOf(s)) {
if (units.contains(pair.unit)) {
deadAssignment = false;
break;
}
}
if (deadAssignment) {
postProcess.add(s);
}
}
}
}
final Jimple jimple = Jimple.v();
for (AssignStmt s : postProcess) {
// Transform it into a simple invoke.
Stmt newInvoke = jimple.newInvokeStmt(s.getInvokeExpr());
newInvoke.addAllTagsOf(s);
units.swapWith(s, newInvoke);
// If we have a callgraph, we need to fix it
if (Scene.v().hasCallGraph())
Scene.v().getCallGraph().swapEdgesOutOf(s, newInvoke);
}
}
}
if (soptions.time()) {
Timers.v().deadCodeTimer.end();
}
}
use of soot.Unit in project soot by Sable.
the class NullCheckEliminator method internalTransform.
public void internalTransform(Body body, String phaseName, Map<String, String> options) {
// really, the analysis should be able to use its own results to determine
// that some branches are dead, but since it doesn't we just iterate.
boolean changed;
do {
changed = false;
NullnessAnalysis analysis = analysisFactory.newAnalysis(new ExceptionalUnitGraph(body));
Chain<Unit> units = body.getUnits();
Stmt s;
for (s = (Stmt) units.getFirst(); s != null; s = (Stmt) units.getSuccOf(s)) {
if (!(s instanceof IfStmt))
continue;
IfStmt is = (IfStmt) s;
Value c = is.getCondition();
if (!(c instanceof EqExpr || c instanceof NeExpr))
continue;
BinopExpr e = (BinopExpr) c;
Immediate i = null;
if (e.getOp1() instanceof NullConstant)
i = (Immediate) e.getOp2();
if (e.getOp2() instanceof NullConstant)
i = (Immediate) e.getOp1();
if (i == null)
continue;
boolean alwaysNull = analysis.isAlwaysNullBefore(s, i);
boolean alwaysNonNull = analysis.isAlwaysNonNullBefore(s, i);
// -1 => condition is false, 1 => condition is true
int elim = 0;
if (alwaysNonNull)
elim = c instanceof EqExpr ? -1 : 1;
if (alwaysNull)
elim = c instanceof EqExpr ? 1 : -1;
Stmt newstmt = null;
if (elim == -1)
newstmt = Jimple.v().newNopStmt();
if (elim == 1)
newstmt = Jimple.v().newGotoStmt(is.getTarget());
if (newstmt != null) {
units.swapWith(s, newstmt);
s = newstmt;
changed = true;
}
}
} while (changed);
}
Aggregations