use of com.googlecode.dex2jar.ir.expr.Local 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.Local in project dex2jar by pxb1988.
the class IrMethod method clone.
public IrMethod clone() {
IrMethod n = new IrMethod();
LabelAndLocalMapper mapper = new LabelAndLocalMapper();
n.name = name;
n.args = args;
n.isStatic = isStatic;
n.owner = owner;
n.ret = ret;
n.stmts = stmts.clone(mapper);
for (Trap trap : traps) {
n.traps.add(trap.clone(mapper));
}
for (LocalVar var : vars) {
n.vars.add(var.clone(mapper));
}
if (phiLabels != null) {
List<LabelStmt> nPhiLabels = new ArrayList<>(phiLabels.size());
for (LabelStmt labelStmt : phiLabels) {
nPhiLabels.add(labelStmt.clone(mapper));
}
n.phiLabels = nPhiLabels;
}
for (Local local : locals) {
n.locals.add((Local) local.clone(mapper));
}
return n;
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class LabelAndLocalMapper method map.
public Local map(Local local) {
Local nTarget = locals.get(local);
if (nTarget == null) {
nTarget = (Local) local.clone();
locals.put(local, nTarget);
}
return nTarget;
}
use of com.googlecode.dex2jar.ir.expr.Local 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;
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class SSATransformer method prepare.
private boolean prepare(final IrMethod method) {
int index = Cfg.reIndexLocal(method);
final int[] readCounts = new int[index];
final int[] writeCounts = new int[index];
Cfg.travel(method.stmts, new TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
writeCounts[v._ls_index]++;
return v;
}
@Override
public Value onUse(Local v) {
readCounts[v._ls_index]++;
return v;
}
}, true);
boolean needTravel = false;
boolean needSSAAnalyze = false;
index = 0;
List<Local> oldLocals = method.locals;
List<Local> locals = new ArrayList<>(oldLocals);
oldLocals.clear();
for (Local local : locals) {
int idx = local._ls_index;
int read = readCounts[idx];
int write = writeCounts[idx];
if (read > 0 && write == 0) {
// TODO if we need throw exception ?
// or the code is dead?
}
if (read == 0 && write == 0) {
// ignore the local
} else {
if (write <= 1) {
// no phi require
local._ls_index = -1;
oldLocals.add(local);
} else if (read == 0) {
local._ls_index = -2;
needTravel = true;
// we are going to duplicate each usage of the local and add to method.locals,
// so not add the original local to method.locals
} else {
needSSAAnalyze = true;
local._ls_index = index++;
oldLocals.add(local);
}
}
}
if (needSSAAnalyze || needTravel) {
Cfg.travelMod(method.stmts, new TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
if (v._ls_index == -1) {
return v;
} else if (v._ls_index == -2) {
Local n = (Local) v.clone();
method.locals.add(n);
return n;
}
// others
return v.clone();
}
@Override
public Value onUse(Local v) {
if (v._ls_index == -1) {
return v;
}
return v.clone();
}
}, true);
}
return needSSAAnalyze;
}
Aggregations