Search in sources :

Example 1 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method applyRemapping.

// Flatten ccs so that each local in each cc is replaced with a new representative local.
private void applyRemapping() {
    GenericBitSet<BasicBlock> processed = cfg.createBitSet();
    GenericBitSet<BasicBlock> processed2 = cfg.createBitSet();
    for (Local e : remap.keySet()) {
        for (BasicBlock used : defuse.uses.getNonNull(e)) {
            if (processed.contains(used))
                continue;
            processed.add(used);
            for (Stmt stmt : used) {
                for (Expr s : stmt.enumerateOnlyChildren()) {
                    if (s.getOpcode() == Opcode.LOCAL_LOAD) {
                        VarExpr v = (VarExpr) s;
                        v.setLocal(remap.getOrDefault(v.getLocal(), v.getLocal()));
                    }
                }
            }
        }
        BasicBlock b = defuse.defs.get(e);
        if (processed2.contains(b))
            continue;
        processed2.add(b);
        for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
            Stmt stmt = it.next();
            if (stmt instanceof ParallelCopyVarStmt) {
                ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
                for (Iterator<CopyPair> it2 = copy.pairs.iterator(); it2.hasNext(); ) {
                    CopyPair p = it2.next();
                    p.source = remap.getOrDefault(p.source, p.source);
                    p.targ = remap.getOrDefault(p.targ, p.targ);
                    if (p.source == p.targ)
                        it2.remove();
                }
                if (copy.pairs.isEmpty())
                    it.remove();
            } else if (stmt instanceof CopyVarStmt) {
                AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
                VarExpr v = copy.getVariable();
                v.setLocal(remap.getOrDefault(v.getLocal(), v.getLocal()));
                if (!copy.isSynthetic() && copy.getExpression().getOpcode() == Opcode.LOCAL_LOAD)
                    if (((VarExpr) copy.getExpression()).getLocal() == v.getLocal())
                        it.remove();
            } else if (stmt instanceof CopyPhiStmt) {
                throw new IllegalArgumentException("Phi copy still in block?");
            }
        }
    }
    for (Local e : remap.keySet()) {
        defuse.defs.remove(e);
        defuse.uses.remove(e);
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 2 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method coalesceCopies.

// Coalesce parallel and standard copies based on value interference, dropping coalesced copies
private void coalesceCopies() {
    // if they do not interfere merge the conClasses and those two vars can be coalesced. delete the copy.
    for (BasicBlock b : dom_dfs.getPreOrder()) {
        for (Iterator<Stmt> it = b.iterator(); it.hasNext(); ) {
            Stmt stmt = it.next();
            if (stmt instanceof CopyVarStmt) {
                CopyVarStmt copy = (CopyVarStmt) stmt;
                if (!copy.isSynthetic() && copy.getExpression() instanceof VarExpr) {
                    Local lhs = copy.getVariable().getLocal();
                    Local rhs = ((VarExpr) copy.getExpression()).getLocal();
                    if (!isReservedRegister((VersionedLocal) rhs)) {
                        if (tryCoalesceCopyValue(lhs, rhs)) {
                            // System.out.println("COPYKILL(1) " + lhs + " == " + rhs);
                            it.remove();
                        }
                        if (tryCoalesceCopySharing(lhs, rhs)) {
                            // System.out.println("SHAREKILL(1) " + lhs + " == " + rhs);
                            it.remove();
                        }
                    }
                }
            } else if (stmt instanceof ParallelCopyVarStmt) {
                // we need to do it for each one. if all of the copies are
                // removed then remove the pcvs
                ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
                for (Iterator<CopyPair> pairIter = copy.pairs.listIterator(); pairIter.hasNext(); ) {
                    CopyPair pair = pairIter.next();
                    Local lhs = pair.targ, rhs = pair.source;
                    if (!isReservedRegister((VersionedLocal) rhs)) {
                        if (tryCoalesceCopyValue(lhs, rhs)) {
                            // System.out.println("COPYKILL(2) " + lhs + " == " + rhs);
                            pairIter.remove();
                        }
                        if (tryCoalesceCopySharing(lhs, rhs)) {
                            // System.out.println("SHAREKILL(2) " + lhs + " == " + rhs);
                            pairIter.remove();
                        }
                    }
                }
                if (copy.pairs.isEmpty())
                    it.remove();
            }
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VarExpr(org.mapleir.ir.code.expr.VarExpr) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 3 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method coalescePhis.

// Initialize ccs based on phis and drop phi statements
private void coalescePhis() {
    GenericBitSet<BasicBlock> processed = cfg.createBitSet();
    for (Entry<Local, CopyPhiStmt> e : defuse.phiDefs.entrySet()) {
        Local l = e.getKey();
        BasicBlock b = e.getValue().getBlock();
        // since we are now in csaa, phi locals never interfere and are in the same congruence class.
        // therefore we can coalesce them all together and drop phis. with this, we leave cssa.
        PhiExpr phi = e.getValue().getExpression();
        CongruenceClass pcc = new CongruenceClass();
        pcc.add(l);
        congruenceClasses.put(l, pcc);
        for (Expr ex : phi.getArguments().values()) {
            VarExpr v = (VarExpr) ex;
            Local argL = v.getLocal();
            pcc.add(argL);
            congruenceClasses.put(argL, pcc);
        }
        // we can simply drop all the phis without further consideration
        if (!processed.contains(b)) {
            processed.add(b);
            Iterator<Stmt> it = b.iterator();
            while (it.hasNext()) {
                Stmt stmt = it.next();
                if (stmt.getOpcode() == Opcode.PHI_STORE) {
                    it.remove();
                } else {
                    break;
                }
            }
        }
    }
    defuse.phiDefs.clear();
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 4 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method computeValueInterference.

private void computeValueInterference() {
    List<BasicBlock> topoorder = dom_dfs.getTopoOrder();
    for (BasicBlock bl : topoorder) {
        for (Stmt stmt : bl) {
            int opcode = stmt.getOpcode();
            if (opcode == Opcode.LOCAL_STORE) {
                CopyVarStmt copy = (CopyVarStmt) stmt;
                Expr e = copy.getExpression();
                Local b = copy.getVariable().getLocal();
                if (!copy.isSynthetic() && e.getOpcode() == Opcode.LOCAL_LOAD) {
                    LinkedHashSet<Local> vc = values.get(((VarExpr) e).getLocal());
                    vc.add(b);
                    values.put(b, vc);
                } else {
                    values.getNonNull(b);
                }
            } else if (opcode == Opcode.PHI_STORE) {
                CopyPhiStmt copy = (CopyPhiStmt) stmt;
                values.getNonNull(copy.getVariable().getLocal());
            } else if (opcode == ParallelCopyVarStmt.PARALLEL_STORE) {
                ParallelCopyVarStmt copy = (ParallelCopyVarStmt) stmt;
                for (CopyPair p : copy.pairs) {
                    LinkedHashSet<Local> valueClass = values.getNonNull(p.source);
                    valueClass.add(p.targ);
                    values.put(p.targ, valueClass);
                }
            }
        }
    }
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Example 5 with VarExpr

use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method liftPhiOperands.

private void liftPhiOperands() {
    for (BasicBlock b : cfg.vertices()) {
        for (Stmt stmt : new ArrayList<>(b)) {
            if (stmt.getOpcode() == Opcode.PHI_STORE) {
                CopyPhiStmt copy = (CopyPhiStmt) stmt;
                for (Entry<BasicBlock, Expr> e : copy.getExpression().getArguments().entrySet()) {
                    Expr expr = e.getValue();
                    int opcode = expr.getOpcode();
                    if (opcode == Opcode.CONST_LOAD || opcode == Opcode.CATCH) {
                        VersionedLocal vl = locals.makeLatestVersion(locals.get(0, false));
                        CopyVarStmt cvs = new CopyVarStmt(new VarExpr(vl, expr.getType()), expr);
                        e.setValue(new VarExpr(vl, expr.getType()));
                        insertEnd(e.getKey(), cvs);
                    } else if (opcode != Opcode.LOCAL_LOAD) {
                        throw new IllegalArgumentException("Non-variable expression in phi: " + copy);
                    }
                }
            }
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) VarExpr(org.mapleir.ir.code.expr.VarExpr) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt)

Aggregations

VarExpr (org.mapleir.ir.code.expr.VarExpr)51 Expr (org.mapleir.ir.code.Expr)37 Local (org.mapleir.ir.locals.Local)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)30 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)29 BasicBlock (org.mapleir.ir.cfg.BasicBlock)26 Stmt (org.mapleir.ir.code.Stmt)25 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)21 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)15 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)13 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)12 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)7 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)7 Type (org.objectweb.asm.Type)7 HashSet (java.util.HashSet)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)6 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)5 PopStmt (org.mapleir.ir.code.stmt.PopStmt)5