Search in sources :

Example 1 with CopyPhiStmt

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

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

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

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

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

CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)20 VarExpr (org.mapleir.ir.code.expr.VarExpr)17 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)16 BasicBlock (org.mapleir.ir.cfg.BasicBlock)15 Expr (org.mapleir.ir.code.Expr)15 Local (org.mapleir.ir.locals.Local)14 Stmt (org.mapleir.ir.code.Stmt)13 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)13 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)12 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)10 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 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)4 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)4 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)4 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)4 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)2