use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.
the class AggTransformer method simpleMergeLocals.
/**
* if a local is only used in one place, and the value is isLocationInsensitive,
* remove the local and replace it with its value
* <pre>
* a=b+c
* d=a+e
* </pre>
* to
* <pre>
* d=(b+c)+e
* </pre>
*/
private boolean simpleMergeLocals(IrMethod method, boolean changed, Set<Stmt> locationSensitiveStmts) {
if (method.locals.size() == 0) {
return false;
}
final int[] readCounts = Cfg.countLocalReads(method);
Set<Local> useInPhi = collectLocalUsedInPhi(method);
final Map<Local, Value> toReplace = new HashMap<>();
for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {
Stmt p = it.next();
if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) {
Local local = (Local) p.getOp1();
if (useInPhi.contains(local)) {
continue;
}
if (readCounts[local._ls_index] < 2) {
Value op2 = p.getOp2();
if (isLocationInsensitive(op2)) {
method.locals.remove(local);
toReplace.put(local, op2);
it.remove();
changed = true;
} else {
locationSensitiveStmts.add(p);
}
}
}
}
Cfg.TravelCallBack tcb = new Cfg.TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
return v;
}
@Override
public Value onUse(Local v) {
Value v2 = toReplace.get(v);
if (v2 != null) {
return v2;
}
return v;
}
};
modReplace(toReplace, tcb);
Cfg.travelMod(method.stmts, tcb, false);
return changed;
}
use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.
the class Cfg method travel.
public static void travel(Stmt p, TravelCallBack callback, boolean travelPhi) {
switch(p.et) {
case E1:
travel(p.getOp(), callback);
break;
case E2:
Value e2op1 = p.getOp1();
if (e2op1.vt == VT.LOCAL && (p.st == ST.ASSIGN || p.st == ST.IDENTITY)) {
travel(p.getOp2(), callback);
callback.onAssign((Local) e2op1, (AssignStmt) p);
} else {
travel(p.getOp1(), callback);
travel(p.getOp2(), callback);
}
break;
case En:
case E0:
if (travelPhi && p.st == ST.LABEL) {
LabelStmt labelStmt = (LabelStmt) p;
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
travel(phi, callback, false);
}
}
}
break;
}
}
use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.
the class Cfg method travelMod.
public static void travelMod(Stmt p, TravelCallBack callback, boolean travelPhi) {
switch(p.et) {
case E1:
p.setOp(travelMod(p.getOp(), callback));
break;
case E2:
Value e2op1 = p.getOp1();
if (e2op1.vt == VT.LOCAL && (p.st == ST.ASSIGN || p.st == ST.IDENTITY)) {
p.setOp2(travelMod(p.getOp2(), callback));
p.setOp1(callback.onAssign((Local) e2op1, (AssignStmt) p));
} else {
p.setOp1(travelMod(p.getOp1(), callback));
p.setOp2(travelMod(p.getOp2(), callback));
}
break;
case En:
case E0:
if (travelPhi && p.st == ST.LABEL) {
LabelStmt labelStmt = (LabelStmt) p;
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
travelMod(phi, callback, false);
}
}
}
break;
}
}
use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.
the class RemoveLocalFromSSA method replacePhi.
private void replacePhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace, Set<Value> set) {
if (phiLabels != null) {
for (LabelStmt labelStmt : phiLabels) {
for (AssignStmt phi : labelStmt.phis) {
Value[] ops = phi.getOp2().getOps();
for (Value op : ops) {
Value n = toReplace.get(op);
if (n != null) {
set.add(n);
} else {
set.add(op);
}
}
set.remove(phi.getOp1());
phi.getOp2().setOps(set.toArray(new Value[set.size()]));
set.clear();
}
}
}
}
use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.
the class RemoveLocalFromSSA method simpleAssign.
private boolean simpleAssign(List<LabelStmt> phiLabels, List<AssignStmt> assignStmtList, Map<Local, Local> toReplace, StmtList stmts) {
Set<Value> usedInPhi = new HashSet<>();
if (phiLabels != null) {
for (LabelStmt labelStmt : phiLabels) {
for (AssignStmt phi : labelStmt.phis) {
usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));
}
}
}
boolean changed = false;
for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {
AssignStmt as = it.next();
if (!usedInPhi.contains(as.getOp1())) {
it.remove();
stmts.remove(as);
toReplace.put((Local) as.getOp1(), (Local) as.getOp2());
changed = true;
}
}
return changed;
}
Aggregations