Пример #1
0
def insert_exception_handling(ir: FuncIR) -> None:
    # Generate error block if any ops may raise an exception. If an op
    # fails without its own error handler, we'll branch to this
    # block. The block just returns an error value.
    error_label = None
    for block in ir.blocks:
        can_raise = any(op.can_raise() for op in block.ops)
        if can_raise:
            error_label = add_handler_block(ir)
            break
    if error_label:
        ir.blocks = split_blocks_at_errors(ir.blocks, error_label, ir.name)
Пример #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)