Search in sources :

Example 6 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ControlFlowGraphDumper method dump.

public void dump() {
    // Clear methodnode
    m.instructions.removeAll(true);
    m.tryCatchBlocks.clear();
    m.visitCode();
    for (BasicBlock b : cfg.vertices()) {
        b.resetLabel();
    }
    // Linearize
    linearize();
    // Fix edges
    naturalise();
    // Sanity check linearization
    verifyOrdering();
    // Dump code
    for (BasicBlock b : order) {
        m.visitLabel(b.getLabel());
        for (Stmt stmt : b) {
            stmt.toCode(m, null);
        }
    }
    terminalLabel = new LabelNode();
    m.visitLabel(terminalLabel.getLabel());
    // Dump ranges
    for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
        dumpRange(er);
    }
    // Sanity check
    verifyRanges();
    m.visitEnd();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.mapleir.ir.cfg.BasicBlock) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt)

Example 7 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ControlFlowGraphDumper method verifyOrdering.

private void verifyOrdering() {
    ListIterator<BasicBlock> it = order.listIterator();
    while (it.hasNext()) {
        BasicBlock b = it.next();
        for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
            if (e.getType() == FlowEdges.IMMEDIATE) {
                if (it.hasNext()) {
                    BasicBlock n = it.next();
                    it.previous();
                    if (n != e.dst()) {
                        throw new IllegalStateException("Illegal flow " + e + " > " + n);
                    }
                } else {
                    throw new IllegalStateException("Trailing " + e);
                }
            }
        }
    }
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 8 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 9 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ControlFlowGraphDumper method dumpRange.

private void dumpRange(ExceptionRange<BasicBlock> er) {
    // Determine exception type
    Type type;
    Set<Type> typeSet = er.getTypes();
    if (typeSet.size() != 1) {
        // TODO: find base exception
        type = TypeUtils.THROWABLE;
    } else {
        type = typeSet.iterator().next();
    }
    final Label handler = er.getHandler().getLabel();
    List<BasicBlock> range = er.get();
    range.sort(Comparator.comparing(order::indexOf));
    Label start;
    int rangeIdx = -1, orderIdx;
    do {
        if (++rangeIdx == range.size()) {
            System.err.println("[warn] range is absent: " + m);
            return;
        }
        BasicBlock b = range.get(rangeIdx);
        orderIdx = order.indexOf(b);
        start = b.getLabel();
    } while (orderIdx == -1);
    for (; ; ) {
        // check for endpoints
        if (orderIdx + 1 == order.size()) {
            // end of method
            m.visitTryCatchBlock(start, terminalLabel.getLabel(), handler, type.getInternalName());
            break;
        } else if (rangeIdx + 1 == range.size()) {
            // end of range
            Label end = order.get(orderIdx + 1).getLabel();
            m.visitTryCatchBlock(start, end, handler, type.getInternalName());
            break;
        }
        // check for discontinuity
        BasicBlock nextBlock = range.get(rangeIdx + 1);
        int nextOrderIdx = order.indexOf(nextBlock);
        if (nextOrderIdx - orderIdx > 1) {
            // blocks in-between, end the handler and begin anew
            System.err.println("[warn] Had to split up a range: " + m);
            Label end = order.get(orderIdx + 1).getLabel();
            m.visitTryCatchBlock(start, end, handler, type.getInternalName());
            start = nextBlock.getLabel();
        }
        // next
        rangeIdx++;
        if (nextOrderIdx != -1)
            orderIdx = nextOrderIdx;
    }
}
Also used : Type(org.objectweb.asm.Type) Label(org.objectweb.asm.Label) BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 10 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class DominanceLivenessAnalyser method isLiveOut.

public boolean isLiveOut(BasicBlock q, Local a) {
    BasicBlock defBlock = defuse.defs.get(a);
    GenericBitSet<BasicBlock> uses = defuse.uses.getNonNull(a);
    if (defBlock == q) {
        return !uses.relativeComplement(defBlock).isEmpty() || defuse.phiUses.get(defBlock).contains(a);
    }
    boolean targ = !backTargets.contains(q);
    GenericBitSet<BasicBlock> sdomdef = sdoms.getNonNull(defBlock);
    if (sdomdef.contains(q)) {
        GenericBitSet<BasicBlock> tqa = tq.get(q).intersect(sdomdef);
        for (BasicBlock t : tqa) {
            GenericBitSet<BasicBlock> u = uses.copy();
            if (t == q && targ)
                u.remove(q);
            GenericBitSet<BasicBlock> rtt = rv.getNonNull(t).intersect(u);
            if (!rtt.isEmpty())
                return true;
        }
    }
    return false;
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Aggregations

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6