Search in sources :

Example 1 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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 CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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 CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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 4 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt 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)

Example 5 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class SSABlockLivenessAnalyser method precomputeBlock.

// compute def, use, and phi for given block
private void precomputeBlock(BasicBlock b) {
    def.getNonNull(b);
    use.getNonNull(b);
    phiUse.getNonNull(b);
    phiDef.getNonNull(b);
    // we have to iterate in reverse order because a definition will kill a use in the current block
    // this is so that uses do not escape a block if its def is in the same block. this is basically
    // simulating a statement graph analysis
    ListIterator<Stmt> it = b.listIterator(b.size());
    while (it.hasPrevious()) {
        Stmt stmt = it.previous();
        int opcode = stmt.getOpcode();
        if (opcode == Opcode.PHI_STORE) {
            CopyPhiStmt copy = (CopyPhiStmt) stmt;
            phiDef.get(b).add(copy.getVariable().getLocal());
            PhiExpr phi = copy.getExpression();
            for (Map.Entry<BasicBlock, Expr> e : phi.getArguments().entrySet()) {
                BasicBlock exprSource = e.getKey();
                Expr phiExpr = e.getValue();
                GenericBitSet<Local> useSet = phiUse.get(b).getNonNull(exprSource);
                if (phiExpr.getOpcode() == Opcode.LOCAL_LOAD) {
                    useSet.add(((VarExpr) phiExpr).getLocal());
                } else
                    for (Expr child : phiExpr.enumerateOnlyChildren()) {
                        if (child.getOpcode() == Opcode.LOCAL_LOAD) {
                            useSet.add(((VarExpr) child).getLocal());
                        }
                    }
            }
        } else {
            if (opcode == Opcode.LOCAL_STORE) {
                CopyVarStmt copy = (CopyVarStmt) stmt;
                Local l = copy.getVariable().getLocal();
                def.get(b).add(l);
                use.get(b).remove(l);
                Expr e = copy.getExpression();
                // adding it as live-in.
                if (e.getOpcode() == Opcode.CATCH) {
                    if (hasNaturalPredecessors(cfg, b)) {
                        use.get(b).add(l);
                    }
                }
            }
            for (Expr c : stmt.enumerateOnlyChildren()) {
                if (c.getOpcode() == Opcode.LOCAL_LOAD) {
                    VarExpr v = (VarExpr) c;
                    use.get(b).add(v.getLocal());
                }
            }
        }
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) 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) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) Map(java.util.Map)

Aggregations

CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)24 Stmt (org.mapleir.ir.code.Stmt)18 BasicBlock (org.mapleir.ir.cfg.BasicBlock)17 VarExpr (org.mapleir.ir.code.expr.VarExpr)17 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)16 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)14 Local (org.mapleir.ir.locals.Local)13 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)12 Expr (org.mapleir.ir.code.Expr)10 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)8 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)6 PopStmt (org.mapleir.ir.code.stmt.PopStmt)6 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)6 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)6 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)5 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)5 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)5 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)3 Type (org.objectweb.asm.Type)3