Пример #1
0
def insert_ref_count_opcodes(ir: FuncIR) -> None:
    """Insert reference count inc/dec opcodes to a function.

    This is the entry point to this module.
    """
    cfg = get_cfg(ir.blocks)
    borrowed = set(reg for reg in ir.env.regs() if reg.is_borrowed)
    args = set(reg for reg in ir.env.regs()
               if ir.env.indexes[reg] < len(ir.args))
    regs = [reg for reg in ir.env.regs() if isinstance(reg, Register)]
    live = analyze_live_regs(ir.blocks, cfg)
    borrow = analyze_borrowed_arguments(ir.blocks, cfg, borrowed)
    defined = analyze_must_defined_regs(ir.blocks, cfg, args, regs)
    cache = {}  # type: BlockCache
    for block in ir.blocks[:]:
        if isinstance(block.ops[-1], (Branch, Goto)):
            insert_branch_inc_and_decrefs(block, cache, ir.blocks, live.before,
                                          borrow.before, borrow.after,
                                          defined.after, ir.env)
        transform_block(block, live.before, live.after, borrow.before,
                        defined.after, ir.env)

    # Find all the xdecs we inserted and note the registers down as
    # needing to be initialized.
    for block in ir.blocks:
        for op in block.ops:
            if isinstance(op, DecRef) and op.is_xdec:
                ir.env.vars_needing_init.add(op.src)

    cleanup_cfg(ir.blocks)
Пример #2
0
def insert_uninit_checks(ir: FuncIR) -> None:
    # Remove dead blocks from the CFG, which helps avoid spurious
    # checks due to unused error handling blocks.
    cleanup_cfg(ir.blocks)

    cfg = get_cfg(ir.blocks)
    args = set(reg for reg in ir.env.regs() if ir.env.indexes[reg] < len(ir.args))
    must_defined = analyze_must_defined_regs(ir.blocks, cfg, args, ir.env.regs())

    ir.blocks = split_blocks_at_uninits(ir.env, ir.blocks, must_defined.before)