Search in sources :

Example 1 with LocalsPool

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

the class SSAGenPass method generate.

private VersionedLocal generate(AbstractCopyStmt copy) {
    VarExpr v = copy.getVariable();
    Local oldLocal = v.getLocal();
    int index = oldLocal.getIndex();
    boolean isStack = oldLocal.isStack();
    LocalsPool handler = builder.graph.getLocals();
    Local l = handler.get(index, isStack);
    int subscript = counters.get(l);
    stacks.get(l).push(subscript);
    counters.put(l, subscript + 1);
    VersionedLocal ssaL = handler.get(index, subscript, isStack);
    if (OPTIMISE) {
        makeValue(copy, ssaL);
    }
    v.setLocal(ssaL);
    pool.defs.put(ssaL, copy);
    types.put(ssaL, copy.getExpression().getType());
    pool.uses.put(ssaL, new HashSet<>());
    return ssaL;
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) VarExpr(org.mapleir.ir.code.expr.VarExpr) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint)

Example 2 with LocalsPool

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

the class SSAGenPass method latest.

private VersionedLocal latest(int index, boolean isStack) {
    LocalsPool handler = builder.graph.getLocals();
    Local l = handler.get(index, isStack);
    Stack<Integer> stack = stacks.get(l);
    if (stack == null || stack.isEmpty()) {
        System.err.println(builder.method.owner.name + "#" + builder.method.name);
        System.err.println(builder.graph);
        System.err.println(stacks);
        throw new NullPointerException(l.toString());
    }
    return handler.get(index, stack.peek(), /*subscript*/
    isStack);
}
Also used : LocalsPool(org.mapleir.ir.locals.LocalsPool) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal)

Example 3 with LocalsPool

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

the class ConstantParameterPass method inlineConstant.

private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
    /* we don't actually demote the synthetic copy
		 * here as we would also need to change the
		 * method desc and we can't do that until
		 * later so we defer it. */
    LocalsPool pool = cfg.getLocals();
    /* create the spill variable but not the
		 * actual definition yet. */
    VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
    VersionedLocal spill = pool.makeLatestVersion(argLocal);
    AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
    ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
    /* we have to maintain local references in
		 * phis as opposed to direct constant refs,
		 * so we go through every use of the argLocal
		 * and either replace it with the constant or
		 * a reference to the spill local if it is in
		 * a phi. */
    Set<VarExpr> spillUses = new HashSet<>();
    boolean requireSpill = false;
    Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
    while (it.hasNext()) {
        VarExpr v = it.next();
        if (v.getParent() == null) {
            /* the use is in a phi, we can't
				 * remove the def. 
				 * 
				 * we also replace the old var
				 * with the new spill one so we
				 * have to add this as a use of
				 * the new spill local. */
            spillUses.add(v);
            v.setLocal(spill);
            requireSpill = true;
        } else {
            CodeUnit par = v.getParent();
            par.overwrite(rhsVal.copy(), par.indexOf(v));
        }
        /* this use is no longer associated
			 * with the old argLocal. */
        it.remove();
    }
    if (pool.uses.get(argLocal).size() != 0) {
        throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
    }
    if (requireSpill) {
        /* generate the copy for the spill (v = const) */
        CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
        synthParamCopy.getBlock().add(spillCopy);
        /* initialise data entries for the new spill
			 * variable. */
        pool.defs.put(spill, spillCopy);
        pool.uses.put(spill, spillUses);
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 4 with LocalsPool

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

the class DeadCodeEliminationPass method process.

public void process(ControlFlowGraph cfg) {
    LocalsPool lp = cfg.getLocals();
    boolean c;
    do {
        c = false;
        SimpleDfs<BasicBlock> dfs = new SimpleDfs<>(cfg, cfg.getEntries().iterator().next(), SimpleDfs.PRE);
        List<BasicBlock> pre = dfs.getPreOrder();
        for (BasicBlock b : new HashSet<>(cfg.vertices())) {
            if (!pre.contains(b)) {
                // System.out.println("proc1: " + b);
                for (FlowEdge<BasicBlock> fe : new HashSet<>(cfg.getEdges(b))) {
                    cfg.exciseEdge(fe);
                }
                // System.out.println("removed: ");
                for (Stmt stmt : b) {
                    // System.out.println(" " + (b.indexOf(stmt)) + ". " + stmt);
                    if (stmt instanceof AbstractCopyStmt) {
                        AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
                        lp.defs.remove(copy.getVariable().getLocal());
                    // System.out.println("  kill1 " + copy.getVariable().getLocal());
                    }
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.LOCAL_LOAD) {
                            VarExpr v = (VarExpr) e;
                            lp.uses.get(v.getLocal()).remove(v);
                        // System.out.println("  kill2 " + v.getLocal());
                        }
                    }
                }
                cfg.removeVertex(b);
                deadBlocks++;
                c = true;
            } else {
                // System.out.println("proc2: " + b);
                UnconditionalJumpEdge<BasicBlock> uncond = null;
                for (FlowEdge<BasicBlock> fe : cfg.getEdges(b)) {
                    if (fe.getType() == FlowEdges.UNCOND) {
                        uncond = (UnconditionalJumpEdge<BasicBlock>) fe;
                    }
                }
                if (uncond != null) {
                    BasicBlock dst = uncond.dst();
                    List<BasicBlock> verts = new ArrayList<>(cfg.vertices());
                    if (verts.indexOf(b) + 1 == verts.indexOf(dst)) {
                        ImmediateEdge<BasicBlock> im = new ImmediateEdge<>(b, dst);
                        cfg.exciseEdge(uncond);
                        cfg.addEdge(b, im);
                        Stmt stmt = b.remove(b.size() - 1);
                        if (stmt.getOpcode() != Opcode.UNCOND_JUMP) {
                            throw new IllegalStateException(b + " : " + stmt);
                        }
                        immediateJumps++;
                        c = true;
                    }
                }
                // if(cfg.getMethod().toString().equals("cf.k(IIIIII)V")) {}
                Iterator<Stmt> it = b.iterator();
                while (it.hasNext()) {
                    Stmt stmt = it.next();
                    if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                        AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
                        if (copy.isSynthetic()) {
                            continue;
                        }
                        Local l = copy.getVariable().getLocal();
                        LocalsPool pool = cfg.getLocals();
                        // System.out.println("copy: "+ copy);
                        if (!ConstraintUtil.isUncopyable(copy.getExpression()) && pool.uses.get(l).size() == 0) {
                            for (Expr e : copy.getExpression().enumerateWithSelf()) {
                                if (e.getOpcode() == Opcode.LOCAL_LOAD) {
                                    VarExpr v = (VarExpr) e;
                                    Local l2 = v.getLocal();
                                    pool.uses.remove(l2);
                                }
                            }
                            pool.uses.remove(l);
                            pool.defs.remove(l);
                            it.remove();
                            deadLocals++;
                            c = true;
                        }
                    } else if (stmt.getOpcode() == Opcode.NOP) {
                        it.remove();
                        c = true;
                    }
                }
            }
        }
    // for now
    } while (c);
}
Also used : ImmediateEdge(org.mapleir.flowgraph.edges.ImmediateEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ArrayList(java.util.ArrayList) Local(org.mapleir.ir.locals.Local) SimpleDfs(org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs) Stmt(org.mapleir.ir.code.Stmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) LocalsPool(org.mapleir.ir.locals.LocalsPool) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet)

Example 5 with LocalsPool

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

the class ConstantParameterPass method demoteDeadParamters.

private void demoteDeadParamters(IPAnalysis constAnalysis, ControlFlowGraph cfg, MethodNode n, boolean[] dead) {
    LocalsPool pool = cfg.getLocals();
    BasicBlock entry = cfg.getEntries().iterator().next();
    for (int i = 0; i < dead.length; i++) {
        if (dead[i]) {
            int localIndex = constAnalysis.getLocalIndex(n, i);
            VersionedLocal local = pool.get(localIndex, 0, false);
            AbstractCopyStmt copy = pool.defs.get(local);
            if (copy.getBlock() != entry) {
                System.err.printf("entry:%n%s%n", ControlFlowGraph.printBlock(entry));
                System.err.printf("block:%n%s%n", ControlFlowGraph.printBlock(copy.getBlock()));
                throw new IllegalStateException(String.format("See debug trace (entry vs block) in %s", n));
            }
            copy.delete();
            if (pool.uses.get(local).size() != 0) {
                throw new IllegalStateException(String.format("m: %s, l:%s, uses:%s", n, local, pool.uses.get(local)));
            }
            pool.defs.remove(local);
            pool.uses.remove(local);
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) BasicBlock(org.mapleir.ir.cfg.BasicBlock) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Aggregations

LocalsPool (org.mapleir.ir.locals.LocalsPool)6 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)5 VarExpr (org.mapleir.ir.code.expr.VarExpr)4 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)4 Local (org.mapleir.ir.locals.Local)4 HashSet (java.util.HashSet)3 BasicBlock (org.mapleir.ir.cfg.BasicBlock)3 Expr (org.mapleir.ir.code.Expr)2 Stmt (org.mapleir.ir.code.Stmt)2 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Set (java.util.Set)1 ImmediateEdge (org.mapleir.flowgraph.edges.ImmediateEdge)1 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)1 CodeUnit (org.mapleir.ir.code.CodeUnit)1 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)1 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)1 SimpleDfs (org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs)1 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)1