Search in sources :

Example 1 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6