Search in sources :

Example 1 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method merge.

private void merge(CongruenceClass conClassA, CongruenceClass conClassB) {
    conClassA.addAll(conClassB);
    for (Local l : conClassB) congruenceClasses.put(l, conClassA);
    for (Local l : conClassA) {
        Local in = equalAncIn.get(l);
        Local out = equalAncOut.get(l);
        if (in != null && out != null)
            equalAncIn.put(l, checkPreDomOrder(in, out) ? in : out);
        else
            equalAncIn.put(l, in != null ? in : out != null ? out : null);
    }
}
Also used : Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 2 with Local

use of org.mapleir.ir.locals.Local 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 3 with Local

use of org.mapleir.ir.locals.Local 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 4 with Local

use of org.mapleir.ir.locals.Local in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method tryCoalesceCopySharing.

// Process the copy a = b. Returns true of a and b can be coalesced via sharing.
private boolean tryCoalesceCopySharing(Local a, Local b) {
    // if (!DO_SHARE_COALESCE)
    // return false;
    CongruenceClass pccX = getCongruenceClass(a);
    CongruenceClass pccY = getCongruenceClass(b);
    for (Local c : values.get(a)) {
        if (c == b || c == a || !checkPreDomOrder(c, a) || !intersect(a, c))
            continue;
        CongruenceClass pccZ = getCongruenceClass(c);
        // If X = Z and X != Y, the copy is redundant.
        if (pccX == pccZ && pccX != pccY) {
            return true;
        }
        // after a and b have been coalesced as c already has the correct value.
        if (pccY != pccX && pccY != pccZ && pccX != pccZ && tryCoalesceCopyValue(a, c)) {
            return true;
        }
    }
    return false;
}
Also used : Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 5 with Local

use of org.mapleir.ir.locals.Local 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)

Aggregations

Local (org.mapleir.ir.locals.Local)49 VarExpr (org.mapleir.ir.code.expr.VarExpr)33 BasicBlock (org.mapleir.ir.cfg.BasicBlock)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)24 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)24 Expr (org.mapleir.ir.code.Expr)23 Stmt (org.mapleir.ir.code.Stmt)22 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)21 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)18 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)18 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)10 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)7 HashSet (java.util.HashSet)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)5 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)5 PopStmt (org.mapleir.ir.code.stmt.PopStmt)5 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)5 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)5 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)5 LocalsPool (org.mapleir.ir.locals.LocalsPool)5