Search in sources :

Example 1 with Expr

use of org.mapleir.ir.code.Expr 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 Expr

use of org.mapleir.ir.code.Expr 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 Expr

use of org.mapleir.ir.code.Expr 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 Expr

use of org.mapleir.ir.code.Expr 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 Expr

use of org.mapleir.ir.code.Expr 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

Expr (org.mapleir.ir.code.Expr)87 VarExpr (org.mapleir.ir.code.expr.VarExpr)46 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)45 BasicBlock (org.mapleir.ir.cfg.BasicBlock)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 Stmt (org.mapleir.ir.code.Stmt)29 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)26 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)26 Local (org.mapleir.ir.locals.Local)22 Type (org.objectweb.asm.Type)21 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)20 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)19 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)17 ComparisonType (org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType)14 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)14 ValueComparisonType (org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType)13 ArrayType (org.mapleir.ir.TypeUtils.ArrayType)12 HashSet (java.util.HashSet)11 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)11 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)9