neo-decompiler 0.10.1

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use std::collections::{BTreeMap, BTreeSet};

use crate::decompiler::cfg::{BlockId, Cfg};

use super::traversal::idom_parent;

/// Compute dominance frontiers for φ node insertion.
///
/// A block n is in the dominance frontier of block d if:
/// - d dominates a predecessor of n
/// - d does NOT strictly dominate n
pub(super) fn compute_df(
    cfg: &Cfg,
    idom: &BTreeMap<BlockId, Option<BlockId>>,
) -> BTreeMap<BlockId, BTreeSet<BlockId>> {
    let mut df: BTreeMap<BlockId, BTreeSet<BlockId>> = BTreeMap::new();

    for block in cfg.blocks() {
        df.insert(block.id, BTreeSet::new());
    }

    for block in cfg.blocks() {
        let predecessors = cfg.predecessors(block.id);

        if predecessors.len() < 2 {
            continue;
        }

        let block_idom = idom.get(&block.id).copied().flatten();

        for &pred in predecessors {
            let mut runner = pred;
            while Some(runner) != block_idom {
                df.entry(runner).or_default().insert(block.id);
                match idom_parent(idom, runner) {
                    Some(next) => runner = next,
                    None => break,
                }
            }
        }
    }

    df
}