示例#1
0
def rewrite_obj_return(func, env):
    """
    Handle returning stack-allocated objects.
    """
    if should_skip(env):
        return

    context = env['flypy.typing.context']
    restype = env['flypy.typing.restype']
    envs = env['flypy.state.envs']

    builder = Builder(func)

    stack_alloc = representation.byref(restype)

    if stack_alloc:
        out = func.add_arg(func.temp("out"), opaque_t)
        context[out] = Pointer[restype]
        func.type = types.Function(types.Void, func.type.argtypes, False)

    for arg in func.args:
        arg.type = opaque_t
    func.type = types.Function(func.type.restype,
                               (opaque_t, ) * len(func.args), False)

    is_generator = env['flypy.state.generator']
    for op in func.ops:
        if (op.opcode == 'ret' and op.args[0] is not None and stack_alloc
                and not is_generator):
            # ret val =>
            #     store (load val) out ; ret void
            [val] = op.args
            builder.position_before(op)
            newval = builder.load(val)
            builder.store(newval, out)
            op.set_args([None])

            # Update context
            context[newval] = StackVar[context[val]]

        elif op.opcode == 'call' and op.type != types.Void:
            # result = call(f, ...) =>
            #     alloca result ; call(f, ..., &result)
            ty = context[op]
            if conversion.byref(ty):
                f, args = op.args
                if not is_flypy_cc(f) or should_skip(envs[f]):
                    continue

                builder.position_before(op)
                retval = builder.alloca(opaque_t)
                builder.position_after(op)
                op.replace_uses(retval)

                newargs = args + [retval]
                op.set_args([f, newargs])

                # Update context
                context[retval] = context[op]
                context[op] = void
示例#2
0
    def initialize(self):
        """Initialize pykit untypes structures"""

        # Setup Function
        sig = types.Function(types.Opaque, [types.Opaque] * len(self.argnames),
                             False)
        self.dst = Function(func_name(self.func), self.argnames, sig)

        # Setup Builder
        self.builder = Builder(self.dst)

        # Setup Blocks
        for offset in self.bytecode.labels:
            name = blockname(self.func, offset)
            block = self.dst.new_block(name)
            self.blocks[offset] = block
            self.stacks[block] = []

        # Setup Variables
        self.builder.position_at_beginning(self.dst.startblock)
        for varname in self.varnames:
            stackvar = self.builder.alloca(types.Pointer(types.Opaque),
                                           result=self.dst.temp(varname))
            self.allocas[varname] = stackvar

            # Initialize function arguments
            if varname in self.argnames:
                self.builder.store(self.dst.get_arg(varname), stackvar)
示例#3
0
文件: parser.py 项目: nouiz/pykit
def _build_function(type, args):
    restype, name, func_args = args[1]
    argtypes, argnames = func_args[::2], func_args[1::2]
    type = types.Function(restype, argtypes)
    f = Function(name, argnames, type)

    blocks = args[2:-2]  # omit the footer and newline
    for name, ops in blocks:
        f.add_block(name).extend(ops)

    return f
    def test_exc_rewrite(self):
        func = Function("foo", [], types.Function(types.Void, (), False))
        entry = func.new_block("entry")
        catch_block = func.new_block("catch")
        b = Builder(func)

        with b.at_front(entry):
            b.exc_setup([catch_block])
            b.exc_throw(Const(StopIteration, types.Exception))
        with b.at_front(catch_block):
            b.exc_catch([Const(Exception, types.Exception)])

        local_exceptions.run(func, {})
        self.assertNotIn('exc_throw', opcodes(func))
示例#5
0
文件: utils.py 项目: inaimathi/pykit
    def lower_into_runtime(self, op, insert_decl=False):
        """
        Lower op into a runtime call.

        :param decl: Whether to insert an external declaration if not present
        """
        _verify_args(op)
        if insert_decl and not self.mod.get_global(op.opcode):
            signature = types.Function(op.type, [arg.type for arg in op.args])
            self.mod.add_global(
                GlobalValue(op.opcode, signature, external=True))

        call = self.builder.gen_call_external(op.opcode, op.args, op.result)
        op.replace(call)
示例#6
0
def from_expr(graph, expr_context, env):
    """
    Map a Blaze expression graph to blaze AIR

    Parameters
    ----------
    graph: blaze.expr.Op
        Expression graph

    expr_context: ExprContext
        Context of the expression

    ctx: ExecutionContext
    """
    inputs = expr_context.params

    # -------------------------------------------------
    # Types

    argtypes = [operand.dshape for operand in inputs]
    signature = types.Function(graph.dshape, argtypes, varargs=False)

    # -------------------------------------------------
    # Setup function

    name = "expr"
    argnames = ["e%d" % i for i in range(len(inputs))]
    f = Function(name, argnames, signature)
    builder = Builder(f)
    builder.position_at_beginning(f.new_block('entry'))

    # -------------------------------------------------
    # Generate function

    valuemap = dict(
        (expr, f.get_arg("e%d" % i)) for i, expr in enumerate(inputs))
    _from_expr(graph, f, builder, valuemap)

    retval = valuemap[graph]
    builder.ret(retval)

    # Update environment with runtime arguments
    runtime_args = [expr_context.terms[input] for input in inputs]
    env['runtime.args'] = dict(zip(f.args, runtime_args))

    return f
示例#7
0
    def __init__(self, function):
        self.theano = function

        argnames = ["arg%d" % i for i in range(len(function.inputs))]
        argtypes = [map_type(i.type) for i in function.inputs]

        restype = type_from_outputs(function.outputs)
        signature = types.Function(restype, argtypes)

        # Setup up pykit function
        self.func = ir.Function("theano_func", argnames, signature)
        self.builder = ir.Builder(self.func)
        self.builder.position_at_end(self.func.new_block('entry'))

        # Theano Variable -> PyKit Operation
        self.values = {}

        self.update_dict = {}  # Z_new[...] = Z_old[...]
示例#8
0
def from_ctypes_type(ctypes_type, memo=None):
    """
    Convert a ctypes type to a pykit type.

    Supported are structs, unit types (int/float)
    """
    if memo is None:
        memo = {}
    if hashable(ctypes_type) and ctypes_type in memo:
        return memo[ctypes_type]

    if hashable(ctypes_type) and ctypes_type in ctypes_map:
        result = ctypes_map[ctypes_type]
    elif ctypes_type is ctypes.c_void_p:
        result = types.Pointer(types.Void)
    elif is_ctypes_array_type(ctypes_type):
        result = types.Array(from_ctypes_type(ctypes_type._type_, memo),
                             ctypes_type._length_)
    elif is_ctypes_pointer_type(ctypes_type):
        result = types.Pointer(from_ctypes_type(ctypes_type._type_, memo))
    elif is_ctypes_struct_type(ctypes_type):
        # pre-order caching for recursive data structures
        f_names = []
        f_types = []
        result = types.Struct(f_names, f_types)
        memo[ctypes_type] = result

        fields = [(name, from_ctypes_type(field_type, memo))
                  for name, field_type in ctypes_type._fields_]
        fieldnames, fieldtypes = zip(*fields) or (('dummy', ), (types.Int8, ))

        f_names.extend(fieldnames)
        f_types.extend(fieldtypes)
    elif is_ctypes_function_type(ctypes_type):
        c_restype = from_ctypes_type(ctypes_type._restype_, memo)
        c_argtypes = [
            from_ctypes_type(argty, memo) for argty in ctypes_type._argtypes_
        ]
        result = types.Function(c_restype, c_argtypes, False)
    else:
        raise NotImplementedError(ctypes_type)

    memo[ctypes_type] = result
    return result
示例#9
0
    def impl(py_func, argtypes):
        # TODO: do this better
        from flypy.compiler import representation_type

        ll_argtypes = [representation_type(x) for x in argtypes]
        argnames = list(string.ascii_letters[:len(argtypes)])

        # Determine return type
        if restype_func:
            result_type = restype_func(argtypes)
        else:
            result_type = restype or ll_argtypes[0]

        type = ptypes.Function(result_type, tuple(ll_argtypes), False)
        func = ir.Function(name, argnames, type)
        func.new_block("entry")
        b = ir.Builder(func)
        b.position_at_beginning(func.startblock)
        implementation(b, argtypes, *func.args)
        return func
示例#10
0
文件: externs.py 项目: pombreda/flypy
def rewrite_externs(func, env):
    """Rewrite external symbol references

    Base on flypy.compiler.lower.constants.rewrite_constants
    """
    if env['flypy.state.opaque']:
        return
    target = env['flypy.target']
    # For each operation
    for op in func.ops:
        # Only for call operation
        if op.opcode == 'call':
            # For each constant
            constants = ir.collect_constants(op)
            new_constants = []
            for c in constants:
                extern = c.const

                if extern_support.is_extern_symbol(extern):
                    # Make a declare-only function
                    argtypes = extern.type.argtypes
                    restype = extern.type.restype

                    if target == "cpu":
                        # Install external symbol for CPU target
                        extern.install()

                    functype = ptypes.Function(lltype(restype),
                                               [lltype(t) for t in argtypes],
                                               extern.type.varargs)
                    # Note: Global value should really be part inserted into
                    # a module.  But there are no module support at this point.
                    replacment = ir.GlobalValue(extern.name, functype,
                                                external=True)
                else:
                    # No change
                    replacment = c
                # Add replacement
                new_constants.append(replacment)
            # Replace
            ir.substitute_args(op, constants, new_constants)
示例#11
0
def lltyping(func, env):
    """Annotate the function with the low-level representation types"""
    if not env['flypy.state.opaque']:
        context = env['flypy.typing.context']
        resolve = partial(resolve_type, context)

        for arg in func.args:
            resolve(arg)
        for op in func.ops:
            if op.opcode == 'exc_catch':
                continue
            op.replace(resolve(op))
            op.set_args(nestedmap(resolve, op.args))

        restype = env['flypy.typing.restype']
        if conversion.byref(restype):
            ll_restype = ptypes.Void
        else:
            ll_restype = compiler.representation_type(restype)

        func.type = ptypes.Function(ll_restype,
                                    [arg.type for arg in func.args], False)
示例#12
0
 def visit_FuncDecl(self, decl):
     if decl.args:
         params = self.visits(decl.args.params)
     else:
         params = []
     return types.Function(self.visit(decl.type), params)
示例#13
0
 def setUp(self):
     self.f = Function("testfunc", ['a'],
                       types.Function(types.Float32, [types.Int32]))
     self.b = Builder(self.f)
     self.b.position_at_end(self.f.add_block('entry'))
     self.a = self.f.get_arg('a')
示例#14
0

def resolve_restype(func, env):
    """Figure out the return type and update the context and environment"""
    context = env['flypy.typing.context']
    restype = env['flypy.typing.restype']
    signature = env['flypy.typing.signature']

    typeset = context['return']
    inferred_restype = signature.restype

    if restype is None:
        restype = inferred_restype
    elif inferred_restype != restype:
        try:
            [restype] = unify([(inferred_restype, restype)])
        except UnificationError, e:
            raise TypeError("Annotated result type %s does not match inferred "
                            "type %s for function %r: %s" %
                            (restype, inferred_restype, func.name, e))

    if isinstance(restype, set):
        raise TypeError("Undetermined return type for function %s" %
                        (func.name, ))

    env['flypy.typing.restype'] = restype

    if restype == void or env['flypy.state.generator']:
        _, argtypes, varargs = func.type
        func.type = types.Function(types.Void, argtypes, varargs)
示例#15
0
 def visit_FuncDecl(self, decl):
     return types.Function(self.visit(decl.type),
                           self.visits(decl.args.params))
示例#16
0
 def add_arg(self, argname, argtype):
     self.argnames.append(argname)
     argtypes = tuple(self.type.argtypes) + (argtype, )
     self.type = types.Function(self.type.restype, argtypes,
                                self.type.varargs)
     return self.get_arg(argname)