예제 #1
0
def generate_native_function(fn: FuncIR, emitter: Emitter, source_path: str,
                             module_name: str) -> None:
    declarations = Emitter(emitter.context)
    names = generate_names_for_ir(fn.arg_regs, fn.blocks)
    body = Emitter(emitter.context, names)
    visitor = FunctionEmitterVisitor(body, declarations, source_path,
                                     module_name)

    declarations.emit_line(f'{native_function_header(fn.decl, emitter)} {{')
    body.indent()

    for r in all_values(fn.arg_regs, fn.blocks):
        if isinstance(r.type, RTuple):
            emitter.declare_tuple_struct(r.type)
        if isinstance(r.type, RArray):
            continue  # Special: declared on first assignment

        if r in fn.arg_regs:
            continue  # Skip the arguments

        ctype = emitter.ctype_spaced(r.type)
        init = ''
        declarations.emit_line('{ctype}{prefix}{name}{init};'.format(
            ctype=ctype, prefix=REG_PREFIX, name=names[r], init=init))

    # Before we emit the blocks, give them all labels
    blocks = fn.blocks
    for i, block in enumerate(blocks):
        block.label = i

    common = frequently_executed_blocks(fn.blocks[0])

    for i in range(len(blocks)):
        block = blocks[i]
        visitor.rare = block not in common
        next_block = None
        if i + 1 < len(blocks):
            next_block = blocks[i + 1]
        body.emit_label(block)
        visitor.next_block = next_block

        ops = block.ops
        visitor.ops = ops
        visitor.op_index = 0
        while visitor.op_index < len(ops):
            ops[visitor.op_index].accept(visitor)
            visitor.op_index += 1

    body.emit_line('}')

    emitter.emit_from_emitter(declarations)
    emitter.emit_from_emitter(body)
예제 #2
0
파일: emitfunc.py 프로젝트: quark-zju/mypy
def generate_native_function(fn: FuncIR,
                             emitter: Emitter,
                             source_path: str,
                             module_name: str,
                             optimize_int: bool = True) -> None:
    if optimize_int:
        const_int_regs = find_constant_integer_registers(fn.blocks)
    else:
        const_int_regs = {}
    declarations = Emitter(emitter.context)
    names = generate_names_for_ir(fn.arg_regs, fn.blocks)
    body = Emitter(emitter.context, names)
    visitor = FunctionEmitterVisitor(body, declarations, source_path,
                                     module_name, const_int_regs)

    declarations.emit_line('{} {{'.format(
        native_function_header(fn.decl, emitter)))
    body.indent()

    for r in all_values(fn.arg_regs, fn.blocks):
        if isinstance(r.type, RTuple):
            emitter.declare_tuple_struct(r.type)

        if r in fn.arg_regs:
            continue  # Skip the arguments

        ctype = emitter.ctype_spaced(r.type)
        init = ''
        if r not in const_int_regs:
            declarations.emit_line('{ctype}{prefix}{name}{init};'.format(
                ctype=ctype, prefix=REG_PREFIX, name=names[r], init=init))

    # Before we emit the blocks, give them all labels
    for i, block in enumerate(fn.blocks):
        block.label = i

    for block in fn.blocks:
        body.emit_label(block)
        for op in block.ops:
            op.accept(visitor)

    body.emit_line('}')

    emitter.emit_from_emitter(declarations)
    emitter.emit_from_emitter(body)
예제 #3
0
파일: emitfunc.py 프로젝트: Akuli/mypy
def generate_native_function(fn: FuncIR,
                             emitter: Emitter,
                             source_path: str,
                             module_name: str) -> None:
    declarations = Emitter(emitter.context, fn.env)
    body = Emitter(emitter.context, fn.env)
    visitor = FunctionEmitterVisitor(body, declarations, source_path, module_name)

    declarations.emit_line('{} {{'.format(native_function_header(fn.decl, emitter)))
    body.indent()

    for r, i in fn.env.indexes.items():
        if isinstance(r.type, RTuple):
            emitter.declare_tuple_struct(r.type)
        if i < len(fn.args):
            continue  # skip the arguments
        ctype = emitter.ctype_spaced(r.type)
        init = ''
        if r in fn.env.vars_needing_init:
            init = ' = {}'.format(declarations.c_error_value(r.type))
        declarations.emit_line('{ctype}{prefix}{name}{init};'.format(ctype=ctype,
                                                                     prefix=REG_PREFIX,
                                                                     name=r.name,
                                                                     init=init))

    # Before we emit the blocks, give them all labels
    for i, block in enumerate(fn.blocks):
        block.label = i

    for block in fn.blocks:
        body.emit_label(block)
        for op in block.ops:
            op.accept(visitor)

    body.emit_line('}')

    emitter.emit_from_emitter(declarations)
    emitter.emit_from_emitter(body)