Search in sources :

Example 1 with AssignStmt

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();
                    }
                }
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) Trap(com.googlecode.dex2jar.ir.Trap) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) PhiExpr(com.googlecode.dex2jar.ir.expr.PhiExpr) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 2 with AssignStmt

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;
        }
    }
}
Also used : AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 3 with AssignStmt

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;
}
Also used : AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 4 with AssignStmt

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();
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 5 with AssignStmt

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;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local)

Aggregations

AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)22 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)18 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)13 Local (com.googlecode.dex2jar.ir.expr.Local)12 Value (com.googlecode.dex2jar.ir.expr.Value)11 ArrayList (java.util.ArrayList)6 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)3 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)3 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 HashSet (java.util.HashSet)2 Trap (com.googlecode.dex2jar.ir.Trap)1 Constant (com.googlecode.dex2jar.ir.expr.Constant)1 UnopStmt (com.googlecode.dex2jar.ir.stmt.UnopStmt)1 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1