Search in sources :

Example 11 with BasicBlock

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

the class DominanceLivenessAnalyser method isLiveIn.

public boolean isLiveIn(BasicBlock b, Local l) {
    BasicBlock defBlock = defuse.defs.get(l);
    if (defuse.phiDefs.containsKey(l) && defBlock == b) {
        return true;
    }
    GenericBitSet<BasicBlock> tqa = tq.get(b).intersect(sdoms.getNonNull(defBlock));
    for (BasicBlock t : tqa) {
        GenericBitSet<BasicBlock> rt = rv.get(t).intersect(defuse.uses.get(l));
        if (!rt.isEmpty())
            return true;
    }
    return false;
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 12 with BasicBlock

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

the class DominanceLivenessAnalyser method reduce.

private ControlFlowGraph reduce(ControlFlowGraph cfg, Set<FastGraphEdge<BasicBlock>> back) {
    ControlFlowGraph reducedCfg = cfg.copy();
    for (FastGraphEdge<BasicBlock> e : back) {
        reducedCfg.removeEdge(e.src(), (FlowEdge<BasicBlock>) e);
        backTargets.add(e.dst());
        backEdges.getNonNull(e.src()).add(e.dst());
    }
    return reducedCfg;
}
Also used : ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 13 with BasicBlock

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

Example 14 with BasicBlock

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

the class SSABlockLivenessAnalyser method init.

private void init() {
    // initialize in and out
    for (BasicBlock b : cfg.vertices()) {
        in.getNonNull(b);
        out.getNonNull(b);
    }
    // compute def, use, and phi for each block
    for (BasicBlock b : cfg.vertices()) precomputeBlock(b);
    // enqueue every block
    for (BasicBlock b : cfg.vertices()) enqueue(b);
// System.out.println();
// System.out.println();
// for (BasicBlock b : cfg.vertices())
// System.out.println(b.getId() + " |||| DEF: " + def.get(b) + " ||||| USE: " + use.get(b));
// System.out.println();
// for (BasicBlock b : cfg.vertices())
// System.out.println(b.getId() + " |||| \u0278DEF: " + phiDef.get(b) + " ||||| \u0278USE: " + phiUse.get(b));
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 15 with BasicBlock

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

the class SSABlockLivenessAnalyser method compute.

public void compute() {
    // negative handling always goes after positive and any adds
    while (!queue.isEmpty()) {
        BasicBlock b = queue.remove();
        // System.out.println("\n\nProcessing " + b.getId());
        GenericBitSet<Local> oldIn = new GenericBitSet<>(in.get(b));
        GenericBitSet<Local> curIn = new GenericBitSet<>(use.get(b));
        GenericBitSet<Local> curOut = locals.createBitSet();
        // out[n] = U(s in succ[n])(in[s])
        for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.addAll(in.get(succEdge.dst()));
        // negative phi handling for defs
        for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.removeAll(phiDef.get(succEdge.dst()));
        // positive phi handling for uses, see ยง5.4.2 "Meaning of copy statements in Sreedhar's method"
        for (FlowEdge<BasicBlock> succEdge : cfg.getEdges(b)) curOut.addAll(phiUse.get(succEdge.dst()).getNonNull(b));
        // negative phi handling for uses
        for (FlowEdge<BasicBlock> predEdge : cfg.getReverseEdges(b)) curIn.removeAll(phiUse.get(b).getNonNull(predEdge.src()).relativeComplement(use.get(b)));
        // positive phi handling for defs
        curIn.addAll(phiDef.get(b));
        oldIn.addAll(phiDef.get(b));
        // in[n] = use[n] U(out[n] - def[n])
        curIn.addAll(curOut.relativeComplement(def.get(b)));
        in.put(b, curIn);
        out.put(b, curOut);
        // queue preds if dataflow state changed
        if (!oldIn.equals(curIn)) {
            cfg.getReverseEdges(b).stream().map(e -> e.src()).forEach(this::enqueue);
        // for (BasicBlock b2 : cfg.vertices())
        // System.out.println(b2.getId() + " |||| IN: " + in.get(b2) + " ||||| OUT: " + out.get(b2));
        }
    }
}
Also used : Local(org.mapleir.ir.locals.Local) ListIterator(java.util.ListIterator) VarExpr(org.mapleir.ir.code.expr.VarExpr) GenericBitSet(org.mapleir.stdlib.collections.bitset.GenericBitSet) Expr(org.mapleir.ir.code.Expr) FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) LocalsPool(org.mapleir.ir.locals.LocalsPool) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) Opcode(org.mapleir.ir.code.Opcode) FlowEdges(org.mapleir.flowgraph.edges.FlowEdges) Map(java.util.Map) Queue(java.util.Queue) LinkedList(java.util.LinkedList) BasicBlock(org.mapleir.ir.cfg.BasicBlock) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) GenericBitSet(org.mapleir.stdlib.collections.bitset.GenericBitSet)

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