Search in sources :

Example 21 with Value

use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.

the class RemoveConstantFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean changed = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    Map<Local, Object> cstMap = new HashMap<>();
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL) {
                if (as.getOp2().vt == Value.VT.CONSTANT) {
                    assignStmtList.add(as);
                    cstMap.put((Local) as.getOp1(), ((Constant) as.getOp2()).value);
                } else if (as.getOp2().vt == Value.VT.LOCAL) {
                    cstMap.put((Local) as.getOp1(), as.getOp2());
                }
            }
        }
    }
    if (assignStmtList.size() == 0) {
        return false;
    }
    RemoveLocalFromSSA.fixReplace(cstMap);
    final Map<Local, Value> toReplace = new HashMap<>();
    Set<Value> usedInPhi = new HashSet<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    if (phiLabels != null) {
        boolean loopAgain = true;
        while (loopAgain) {
            loopAgain = false;
            usedInPhi.clear();
            for (Iterator<LabelStmt> it = phiLabels.iterator(); it.hasNext(); ) {
                LabelStmt labelStmt = it.next();
                if (labelStmt.phis != null) {
                    for (Iterator<AssignStmt> it2 = labelStmt.phis.iterator(); it2.hasNext(); ) {
                        AssignStmt phi = it2.next();
                        Value[] vs = phi.getOp2().getOps();
                        Object sameCst = null;
                        boolean allEqual = true;
                        for (Value p : vs) {
                            Object cst = cstMap.get(p);
                            if (cst == null) {
                                allEqual = false;
                                break;
                            }
                            if (sameCst == null) {
                                sameCst = cst;
                            } else if (!sameCst.equals(cst)) {
                                allEqual = false;
                                break;
                            }
                        }
                        if (allEqual) {
                            // all are same constant
                            cstMap.put((Local) phi.getOp1(), sameCst);
                            if (sameCst instanceof Local) {
                                phi.setOp2((Value) sameCst);
                            } else {
                                phi.setOp2(Exprs.nConstant(sameCst));
                                assignStmtList.add(phi);
                            }
                            it2.remove();
                            method.stmts.insertAfter(labelStmt, phi);
                            changed = true;
                            // loop again
                            loopAgain = true;
                        } else {
                            usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));
                        }
                    }
                    if (labelStmt.phis.size() == 0) {
                        it.remove();
                    }
                }
            }
        }
    }
    for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {
        AssignStmt as = it.next();
        if (!usedInPhi.contains(as.getOp1())) {
            it.remove();
            method.stmts.remove(as);
            method.locals.remove(as.getOp1());
            changed = true;
        }
        toReplace.put((Local) as.getOp1(), as.getOp2());
    }
    Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

        @Override
        public Value onAssign(Local v, AssignStmt as) {
            return v;
        }

        @Override
        public Value onUse(Local v) {
            Value n = toReplace.get(v);
            return n == null ? v : n.clone();
        }
    }, false);
    return changed;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) HashMap(java.util.HashMap) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) ArrayList(java.util.ArrayList) 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) Value(com.googlecode.dex2jar.ir.expr.Value) HashSet(java.util.HashSet)

Example 22 with Value

use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method collectPhiObjects.

private Map<Local, PhiObject> collectPhiObjects(List<LabelStmt> phiLabels) {
    Map<Local, PhiObject> phis;
    phis = new HashMap<>();
    for (LabelStmt labelStmt : phiLabels) {
        for (AssignStmt as : labelStmt.phis) {
            Local local = (Local) as.getOp1();
            PhiObject child = getOrCreate(phis, local);
            child.isInitByPhi = true;
            for (Value op : as.getOp2().getOps()) {
                if (op == local) {
                    continue;
                }
                PhiObject parent = getOrCreate(phis, (Local) op);
                linkPhiObject(parent, child);
            }
        }
    }
    return phis;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 23 with Value

use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method transformReportChanged.

@Override
public boolean transformReportChanged(IrMethod method) {
    boolean irChanged = false;
    List<AssignStmt> assignStmtList = new ArrayList<>();
    List<LabelStmt> phiLabels = method.phiLabels;
    for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == Stmt.ST.ASSIGN) {
            AssignStmt as = (AssignStmt) p;
            if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.LOCAL) {
                assignStmtList.add(as);
            }
        }
    }
    final Map<Local, Local> toReplace = new HashMap<>();
    Set<Value> set = new HashSet<>();
    boolean changed = true;
    while (changed) {
        changed = false;
        if (removeLoopFromPhi(phiLabels, toReplace)) {
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simplePhi(phiLabels, toReplace, set)) {
            // remove a = phi(b)
            fixReplace(toReplace);
            replacePhi(phiLabels, toReplace, set);
        }
        while (simpleAssign(phiLabels, assignStmtList, toReplace, method.stmts)) {
            // remove a=b
            fixReplace(toReplace);
            replaceAssign(assignStmtList, toReplace);
            changed = true;
            irChanged = true;
        }
        replacePhi(phiLabels, toReplace, set);
    }
    for (Local local : toReplace.keySet()) {
        method.locals.remove(local);
        irChanged = true;
    }
    if (toReplace.size() > 0) {
        Cfg.travelMod(method.stmts, new Cfg.TravelCallBack() {

            @Override
            public Value onAssign(Local v, AssignStmt as) {
                return v;
            }

            @Override
            public Value onUse(Local v) {
                Local n = toReplace.get(v);
                return n == null ? v : n;
            }
        }, true);
    }
    return irChanged;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) 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) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 24 with Value

use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method replaceAssign.

static <T extends Value> void replaceAssign(List<AssignStmt> assignStmtList, Map<Local, T> toReplace) {
    for (AssignStmt as : assignStmtList) {
        Value right = as.getOp2();
        T to = toReplace.get(right);
        if (to != null) {
            as.setOp2(to);
        }
    }
}
Also used : AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 25 with Value

use of com.googlecode.dex2jar.ir.expr.Value in project dex2jar by pxb1988.

the class SSATransformer method replaceLocalsWithSSA.

private void replaceLocalsWithSSA(final IrMethod method) {
    final List<Local> locals = method.locals;
    locals.clear();
    StmtList stmts = method.stmts;
    TravelCallBack tcb = new TravelCallBack() {

        @Override
        public Value onAssign(Local a, AssignStmt as) {
            if (a._ls_index < 0) {
                locals.add(a);
                return a;
            }
            SSAValue lsv = (SSAValue) a.tag;
            Local b = lsv.local;
            locals.add(b);
            return b;
        }

        @Override
        public Value onUse(Local a) {
            if (a._ls_index < 0) {
                return a;
            }
            SSAValue lsv = (SSAValue) a.tag;
            Local b = lsv.local;
            return b;
        }
    };
    Set<Value> froms = new HashSet<>();
    List<LabelStmt> phiLabels = new ArrayList<>();
    // 2. we are looking for Phis and insert Phi node to the code
    for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == ST.LABEL) {
            LabelStmt labelStmt = (LabelStmt) p;
            List<AssignStmt> phis = null;
            SSAValue[] frame = (SSAValue[]) p.frame;
            if (frame != null) {
                for (SSAValue v : frame) {
                    if (v == null || !v.used) {
                        continue;
                    }
                    if (v.parent != null) {
                        froms.add(v.parent.local);
                    }
                    if (v.otherParents != null) {
                        for (SSAValue parent : v.otherParents) {
                            froms.add(parent.local);
                        }
                    }
                    froms.remove(v.local);
                    if (phis == null) {
                        phis = new ArrayList<>();
                    }
                    locals.add(v.local);
                    phis.add(Stmts.nAssign(v.local, Exprs.nPhi(froms.toArray(new Value[froms.size()]))));
                    froms.clear();
                }
            }
            labelStmt.phis = phis;
            if (phis != null) {
                phiLabels.add(labelStmt);
            }
        } else {
            Cfg.travelMod(p, tcb, true);
        }
        p.frame = null;
    }
    if (phiLabels.size() > 0) {
        method.phiLabels = phiLabels;
    }
}
Also used : TravelCallBack(com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack) Local(com.googlecode.dex2jar.ir.expr.Local) Value(com.googlecode.dex2jar.ir.expr.Value) AnalyzeValue(com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)

Aggregations

Value (com.googlecode.dex2jar.ir.expr.Value)32 Local (com.googlecode.dex2jar.ir.expr.Local)19 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)11 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)9 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)8 Constant (com.googlecode.dex2jar.ir.expr.Constant)5 Exprs.nArrayValue (com.googlecode.dex2jar.ir.expr.Exprs.nArrayValue)4 ArrayList (java.util.ArrayList)4 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)3 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 TravelCallBack (com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack)2 DexLabel (com.googlecode.d2j.DexLabel)1 DexType (com.googlecode.d2j.DexType)1 Field (com.googlecode.d2j.Field)1 Method (com.googlecode.d2j.Method)1 DvmInterpreter (com.googlecode.d2j.node.analysis.DvmInterpreter)1 Op (com.googlecode.d2j.reader.Op)1 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 LocalVar (com.googlecode.dex2jar.ir.LocalVar)1 StmtSearcher (com.googlecode.dex2jar.ir.StmtSearcher)1