Search in sources :

Example 1 with ImmediateEdge

use of org.mapleir.flowgraph.edges.ImmediateEdge in project maple-ir by LLVM-but-worse.

the class ControlFlowGraphDumper method naturalise.

private void naturalise() {
    for (int i = 0; i < order.size(); i++) {
        BasicBlock b = order.get(i);
        for (FlowEdge<BasicBlock> e : new HashSet<>(cfg.getEdges(b))) {
            BasicBlock dst = e.dst();
            if (e instanceof ImmediateEdge && order.indexOf(dst) != i + 1) {
                // Fix immediates
                b.add(new UnconditionalJumpStmt(dst));
                cfg.removeEdge(b, e);
                cfg.addEdge(b, new UnconditionalJumpEdge<>(b, dst));
            } else if (e instanceof UnconditionalJumpEdge && order.indexOf(dst) == i + 1) {
                // Remove extraneous gotos
                for (ListIterator<Stmt> it = b.listIterator(b.size()); it.hasPrevious(); ) {
                    if (it.previous() instanceof UnconditionalJumpStmt) {
                        it.remove();
                        break;
                    }
                }
                cfg.removeEdge(b, e);
                cfg.addEdge(b, new ImmediateEdge<>(b, dst));
            }
        }
    }
}
Also used : ImmediateEdge(org.mapleir.flowgraph.edges.ImmediateEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock) UnconditionalJumpEdge(org.mapleir.flowgraph.edges.UnconditionalJumpEdge) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt)

Example 2 with ImmediateEdge

use of org.mapleir.flowgraph.edges.ImmediateEdge 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 3 with ImmediateEdge

use of org.mapleir.flowgraph.edges.ImmediateEdge in project maple-ir by LLVM-but-worse.

the class ControlFlowGraphDumper method linearize.

private void linearize() {
    if (cfg.getEntries().size() != 1)
        throw new IllegalStateException("CFG doesn't have exactly 1 entry");
    BasicBlock entry = cfg.getEntries().iterator().next();
    // Build bundle graph
    Map<BasicBlock, BlockBundle> bundles = new HashMap<>();
    Map<BlockBundle, List<BlockBundle>> bunches = new HashMap<>();
    // Build bundles
    List<BasicBlock> topoorder = new SimpleDfs<>(cfg, entry, SimpleDfs.TOPO).getTopoOrder();
    for (BasicBlock b : topoorder) {
        if (// Already in a bundle
        bundles.containsKey(b))
            continue;
        if (// Look for heads of bundles only
        b.getIncomingImmediateEdge() != null)
            continue;
        BlockBundle bundle = new BlockBundle();
        while (b != null) {
            bundle.add(b);
            bundles.put(b, bundle);
            b = b.getImmediate();
        }
        List<BlockBundle> bunch = new ArrayList<>();
        bunch.add(bundle);
        bunches.put(bundle, bunch);
    }
    // Group bundles by exception ranges
    for (ExceptionRange<BasicBlock> range : cfg.getRanges()) {
        BlockBundle prevBundle = null;
        for (BasicBlock b : range.getNodes()) {
            BlockBundle curBundle = bundles.get(b);
            if (prevBundle == null) {
                prevBundle = curBundle;
                continue;
            }
            if (curBundle != prevBundle) {
                List<BlockBundle> bunchA = bunches.get(prevBundle);
                List<BlockBundle> bunchB = bunches.get(curBundle);
                if (bunchA != bunchB) {
                    bunchA.addAll(bunchB);
                    for (BlockBundle bundle : bunchB) {
                        bunches.put(bundle, bunchA);
                    }
                }
                prevBundle = curBundle;
            }
        }
    }
    // Rebuild bundles
    bundles.clear();
    for (Map.Entry<BlockBundle, List<BlockBundle>> e : bunches.entrySet()) {
        BlockBundle bundle = e.getKey();
        if (bundles.containsKey(bundle.getFirst()))
            continue;
        BlockBundle bunch = new BlockBundle();
        e.getValue().forEach(bunch::addAll);
        for (BasicBlock b : bunch) bundles.put(b, bunch);
    }
    // Connect bundle graph
    BundleGraph bundleGraph = new BundleGraph();
    BlockBundle entryBundle = bundles.get(entry);
    bundleGraph.addVertex(entryBundle);
    for (BasicBlock b : topoorder) {
        for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
            if (e instanceof ImmediateEdge)
                continue;
            BlockBundle src = bundles.get(b);
            bundleGraph.addEdge(src, new FastGraphEdgeImpl<>(src, bundles.get(e.dst())));
        }
    }
    // Linearize & flatten
    order = new IndexedList<>();
    // for efficiency
    Set<BlockBundle> bundlesSet = new HashSet<>(bundles.values());
    ControlFlowGraphDumper.linearize(bundlesSet, bundleGraph, entryBundle).forEach(order::addAll);
}
Also used : ImmediateEdge(org.mapleir.flowgraph.edges.ImmediateEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock) IndexedList(org.mapleir.stdlib.util.IndexedList)

Aggregations

ImmediateEdge (org.mapleir.flowgraph.edges.ImmediateEdge)3 BasicBlock (org.mapleir.ir.cfg.BasicBlock)3 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 UnconditionalJumpEdge (org.mapleir.flowgraph.edges.UnconditionalJumpEdge)1 Expr (org.mapleir.ir.code.Expr)1 Stmt (org.mapleir.ir.code.Stmt)1 VarExpr (org.mapleir.ir.code.expr.VarExpr)1 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)1 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)1 Local (org.mapleir.ir.locals.Local)1 LocalsPool (org.mapleir.ir.locals.LocalsPool)1 SimpleDfs (org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs)1 IndexedList (org.mapleir.stdlib.util.IndexedList)1