use of com.googlecode.dex2jar.ir.expr.PhiExpr 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.expr.PhiExpr in project dex2jar by pxb1988.
the class UnSSATransformer method fixPhi.
/**
* there is somewhere both a and its possible x is both live, insert a=x, will change the meaning for example
*
* <pre>
* L0:
* a = phi(b, ... )
* b = 234;
* if a>0 goto L0: // a, b both live here
* ...
* </pre>
*
* after insert a=b before the if stmt, the programe change to
*
* <pre>
* L0:
* // a = phi(b, ... )
* b = 234;
* a = b
* if a>0 goto L0:
* ...
* </pre>
*
* the solution is by introduce a new local x
*
* <pre>
* L0:
* x = phi(b, ... )
* a = x
* b = 234;
* if a>0 goto L0: // a, b both live here
* ...
* </pre>
*
* insert x = b is ok now
*
* <pre>
* L0:
* // x = phi(b, ... )
* a = x
* b = 234;
* x = b
* if a>0 goto L0: // a, b both live here
* ...
* </pre>
*
* @param phiLabels
*/
private void fixPhi(IrMethod method, Collection<LabelStmt> phiLabels) {
for (LabelStmt labelStmt : phiLabels) {
List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;
for (AssignStmt phi : phis) {
Local a = (Local) phi.getOp1();
PhiExpr b = (PhiExpr) phi.getOp2();
boolean introduceNewLocal = false;
RegAssign aReg = (RegAssign) a.tag;
for (Value op : b.getOps()) {
RegAssign bReg = (RegAssign) ((Local) op).tag;
if (aReg.excludes.contains(bReg)) {
introduceNewLocal = true;
break;
}
}
if (introduceNewLocal) {
Local newLocal = (Local) a.clone();
if (DEBUG) {
newLocal.debugName = "x" + method.locals.size();
}
phi.op1 = newLocal;
RegAssign newRegAssign = new RegAssign();
newLocal.tag = newRegAssign;
method.locals.add(newLocal);
Stmt newAssigStmt = Stmts.nAssign(a, newLocal);
Stmt next = labelStmt.getNext();
if (next != null && next.st == ST.IDENTITY && next.getOp2().vt == VT.EXCEPTION_REF) {
// it's a handler, insert after the exception ref
method.stmts.insertAfter(next, newAssigStmt);
} else {
method.stmts.insertAfter(labelStmt, newAssigStmt);
}
LiveV[] frame = (LiveV[]) labelStmt.frame;
if (DEBUG) {
LiveV[] copy = frame.clone();
LiveV n = new LiveV();
n.local = a;
n.used = true;
copy[a._ls_index] = new LiveV();
newAssigStmt.frame = copy;
}
LiveV thePhi = frame[a._ls_index];
thePhi.local = newLocal;
for (LiveV v : frame) {
if (v != null && v.used) {
RegAssign s = (RegAssign) v.local.tag;
s.excludes.add(newRegAssign);
newRegAssign.excludes.add(s);
}
}
}
}
}
}
Aggregations