use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class DeadCodeTransformer method transform.
@Override
public void transform(IrMethod method) {
Cfg.createCFG(method);
Cfg.dfsVisit(method, null);
if (method.traps != null) {
for (Iterator<Trap> it = method.traps.iterator(); it.hasNext(); ) {
Trap t = it.next();
boolean allNotThrow = true;
for (Stmt p = t.start; p != t.end; p = p.getNext()) {
if (p.visited && Cfg.isThrow(p)) {
allNotThrow = false;
break;
}
}
if (allNotThrow) {
it.remove();
continue;
}
boolean allNotVisited = true;
boolean allVisited = true;
for (LabelStmt labelStmt : t.handlers) {
if (labelStmt.visited) {
allNotVisited = false;
} else {
allVisited = false;
}
}
if (allNotVisited) {
it.remove();
} else {
// keep start and end
t.start.visited = true;
t.end.visited = true;
if (!allVisited) {
// part visited
List<String> types = new ArrayList<>(t.handlers.length);
List<LabelStmt> labelStmts = new ArrayList<>(t.handlers.length);
for (int i = 0; i < t.handlers.length; i++) {
labelStmts.add(t.handlers[i]);
types.add(t.types[i]);
}
t.handlers = labelStmts.toArray(new LabelStmt[labelStmts.size()]);
t.types = types.toArray(new String[types.size()]);
}
}
}
}
Set<Local> definedLocals = new HashSet<>();
for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {
Stmt p = it.next();
if (!p.visited) {
it.remove();
continue;
}
if (p.st == Stmt.ST.ASSIGN || p.st == Stmt.ST.IDENTITY) {
if (p.getOp1().vt == Value.VT.LOCAL) {
definedLocals.add((Local) p.getOp1());
}
}
}
if (method.phiLabels != null) {
for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
LabelStmt labelStmt = it.next();
if (!labelStmt.visited) {
it.remove();
continue;
}
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
definedLocals.add((Local) phi.getOp1());
}
}
}
}
method.locals.clear();
method.locals.addAll(definedLocals);
Set<Value> tmp = new HashSet<>();
if (method.phiLabels != null) {
for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
LabelStmt labelStmt = it.next();
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
PhiExpr phiExpr = (PhiExpr) phi.getOp2();
boolean needRebuild = false;
for (Value v : phiExpr.getOps()) {
if (!definedLocals.contains(v)) {
needRebuild = true;
break;
}
}
if (needRebuild) {
for (Value v : phiExpr.getOps()) {
if (definedLocals.contains(v)) {
tmp.add(v);
}
}
phiExpr.setOps(tmp.toArray(new Value[tmp.size()]));
tmp.clear();
}
}
}
}
}
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class NewTransformer method replaceX.
void replaceX(IrMethod method) {
final Map<Local, TObject> init = new HashMap<>();
for (Stmt p : method.stmts) {
if (p.st == ASSIGN && p.getOp1().vt == LOCAL && p.getOp2().vt == NEW) {
// the stmt is a new assign stmt
Local local = (Local) p.getOp1();
init.put(local, new TObject(local, (AssignStmt) p));
}
}
if (init.size() > 0) {
final int size = Cfg.reIndexLocal(method);
makeSureUsedBeforeConstructor(method, init, size);
if (init.size() > 0) {
replace0(method, init, size);
}
for (Stmt stmt : method.stmts) {
stmt.frame = null;
}
}
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt 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.stmt.AssignStmt 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.stmt.AssignStmt in project dex2jar by pxb1988.
the class RemoveLocalFromSSA method removeLoopFromPhi.
private boolean removeLoopFromPhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace) {
boolean changed = false;
if (phiLabels != null) {
Set<Local> toDeletePhiAssign = new HashSet<>();
Map<Local, PhiObject> phis;
// detect loop init in phi
phis = collectPhiObjects(phiLabels);
Queue<PhiObject> q = new UniqueQueue<>();
q.addAll(phis.values());
while (!q.isEmpty()) {
PhiObject po = q.poll();
for (PhiObject child : po.children) {
if (child.isInitByPhi) {
if (child.parent.addAll(po.parent)) {
q.add(child);
}
}
}
}
for (PhiObject po : phis.values()) {
if (po.isInitByPhi) {
Local local = null;
for (PhiObject p : po.parent) {
if (!p.isInitByPhi) {
if (local == null) {
// the first non-phi value
local = p.local;
} else {
local = null;
break;
}
}
}
if (local != null) {
toReplace.put(po.local, local);
toDeletePhiAssign.add(po.local);
changed = true;
}
}
}
for (Iterator<LabelStmt> itLabel = phiLabels.iterator(); itLabel.hasNext(); ) {
LabelStmt labelStmt = itLabel.next();
for (Iterator<AssignStmt> it = labelStmt.phis.iterator(); it.hasNext(); ) {
AssignStmt phi = it.next();
if (toDeletePhiAssign.contains(phi.getOp1())) {
it.remove();
}
}
if (labelStmt.phis.size() == 0) {
labelStmt.phis = null;
itLabel.remove();
}
}
}
return changed;
}
Aggregations