示例#1
0
    def test_multi_module_linking(self):
        # generate external library module
        m = Module.new('external-library-module')
        fnty = Type.function(Type.int(), [Type.int(), Type.int()])
        libfname = 'myadd'
        func = m.add_function(fnty, libfname)
        bb = func.append_basic_block('')
        bldr = Builder.new(bb)
        bldr.ret(bldr.add(*func.args))
        func.verify()

        # JIT the lib module and bind dynamic symbol
        libengine = EngineBuilder.new(m).mcjit(True).create()
        myadd_ptr = libengine.get_pointer_to_function(func)
        le.dylib_add_symbol(libfname, myadd_ptr)

        # reference external library
        m = Module.new('user')
        fnty = Type.function(Type.int(), [Type.int(), Type.int()])
        func = m.add_function(fnty, 'foo')
        bb = func.append_basic_block('')
        bldr = Builder.new(bb)
        extadd = m.get_or_insert_function(fnty, name=libfname)
        bldr.ret(bldr.call(extadd, func.args))
        func.verify()

        # JIT the user module
        engine = EngineBuilder.new(m).mcjit(True).create()
        ptr = engine.get_pointer_to_function(func)
        self.assertEqual(myadd_ptr,
                         engine.get_pointer_to_named_function(libfname))

        from ctypes import c_int, CFUNCTYPE
        callee = CFUNCTYPE(c_int, c_int, c_int)(ptr)
        self.assertEqual(321 + 123, callee(321, 123))
示例#2
0
文件: pythonapi.py 项目: genba/numba
    def _long_from_native_int(self, ival, func_name, native_int_type, signed):
        fnty = Type.function(self.pyobj, [native_int_type])
        fn = self._get_function(fnty, name=func_name)
        resptr = cgutils.alloca_once(self.builder, self.pyobj)

        if PYVERSION < (3, 0):
            # Under Python 2, we try to return a PyInt object whenever
            # the given number fits in a C long.
            pyint_fnty = Type.function(self.pyobj, [self.long])
            pyint_fn = self._get_function(pyint_fnty, name="PyInt_FromLong")
            long_max = Constant.int(native_int_type, _helperlib.long_max)
            if signed:
                long_min = Constant.int(native_int_type, _helperlib.long_min)
                use_pyint = self.builder.and_(
                    self.builder.icmp(lc.ICMP_SGE, ival, long_min),
                    self.builder.icmp(lc.ICMP_SLE, ival, long_max),
                )
            else:
                use_pyint = self.builder.icmp(lc.ICMP_ULE, ival, long_max)

            with cgutils.ifelse(self.builder, use_pyint) as (then, otherwise):
                with then:
                    downcast_ival = self.builder.trunc(ival, self.long)
                    res = self.builder.call(pyint_fn, [downcast_ival])
                    self.builder.store(res, resptr)
                with otherwise:
                    res = self.builder.call(fn, [ival])
                    self.builder.store(res, resptr)
        else:
            fn = self._get_function(fnty, name=func_name)
            self.builder.store(self.builder.call(fn, [ival]), resptr)

        return self.builder.load(resptr)
示例#3
0
    def _long_from_native_int(self, ival, func_name, native_int_type,
                              signed):
        fnty = Type.function(self.pyobj, [native_int_type])
        fn = self._get_function(fnty, name=func_name)
        resptr = cgutils.alloca_once(self.builder, self.pyobj)

        if PYVERSION < (3, 0):
            # Under Python 2, we try to return a PyInt object whenever
            # the given number fits in a C long.
            pyint_fnty = Type.function(self.pyobj, [self.long])
            pyint_fn = self._get_function(pyint_fnty, name="PyInt_FromLong")
            long_max = Constant.int(native_int_type, _helperlib.long_max)
            if signed:
                long_min = Constant.int(native_int_type, _helperlib.long_min)
                use_pyint = self.builder.and_(
                    self.builder.icmp(lc.ICMP_SGE, ival, long_min),
                    self.builder.icmp(lc.ICMP_SLE, ival, long_max),
                    )
            else:
                use_pyint = self.builder.icmp(lc.ICMP_ULE, ival, long_max)

            with cgutils.ifelse(self.builder, use_pyint) as (then, otherwise):
                with then:
                    downcast_ival = self.builder.trunc(ival, self.long)
                    res = self.builder.call(pyint_fn, [downcast_ival])
                    self.builder.store(res, resptr)
                with otherwise:
                    res = self.builder.call(fn, [ival])
                    self.builder.store(res, resptr)
        else:
            fn = self._get_function(fnty, name=func_name)
            self.builder.store(self.builder.call(fn, [ival]), resptr)

        return self.builder.load(resptr)
示例#4
0
文件: pythonapi.py 项目: genba/numba
 def dict_new(self, presize=0):
     if presize == 0:
         fnty = Type.function(self.pyobj, ())
         fn = self._get_function(fnty, name="PyDict_New")
         return self.builder.call(fn, ())
     else:
         fnty = Type.function(self.pyobj, [self.py_ssize_t])
         fn = self._get_function(fnty, name="_PyDict_NewPresized")
         return self.builder.call(fn,
                                  [Constant.int(self.py_ssize_t, presize)])
示例#5
0
 def dict_new(self, presize=0):
     if presize == 0:
         fnty = Type.function(self.pyobj, ())
         fn = self._get_function(fnty, name="PyDict_New")
         return self.builder.call(fn, ())
     else:
         fnty = Type.function(self.pyobj, [self.py_ssize_t])
         fn = self._get_function(fnty, name="_PyDict_NewPresized")
         return self.builder.call(fn,
                                  [Constant.int(self.py_ssize_t, presize)])
示例#6
0
    def declare_runtime_library(self):
        self.runtime = {}

        self.runtime['_print_int'] = Function.new(self.module,
                                                  Type.function(Type.void(), [int_type], False),
                                                  "_print_int")
        self.runtime['_print_float'] = Function.new(self.module,
                                                    Type.function(Type.void(), [float_type], False),
                                                    "_print_float")
        self.runtime['_print_bool'] = Function.new(self.module,
                                                   Type.function(Type.void(), [bool_type], False),
                                                   "_print_bool")
示例#7
0
文件: test_type.py 项目: zhihan/llvm
    def testCreateFunctionType(self):
        ty = Type.int8()
        ft = Type.function(ty, [ty], False)

        self.assertFalse(ft.is_function_vararg())
        self.assertEqual(ty, ft.return_type())
        self.assertEqual(1, ft.num_params())

        self.assertEqual([ty], ft.param_types())

        f2 = Type.function(ty, [ty], True)
        self.assertTrue(f2.is_function_vararg())
        self.assertEqual([ty], f2.param_types())
        self.assertEqual(1, f2.num_params())
示例#8
0
文件: test_type.py 项目: zhihan/llvm
    def testCreateFunctionType(self):
        ty = Type.int8()
        ft = Type.function(ty, [ty], False)

        self.assertFalse(ft.is_function_vararg())
        self.assertEqual(ty, ft.return_type())
        self.assertEqual(1, ft.num_params())

        self.assertEqual([ty], ft.param_types())

        f2 = Type.function(ty, [ty], True)
        self.assertTrue(f2.is_function_vararg())
        self.assertEqual([ty], f2.param_types())
        self.assertEqual(1, f2.num_params())
示例#9
0
    def CodeGen(self):
        # Make the function type, ex: double(double, double).
        function_type = Type.function(Type.double(),
                                      [Type.double()] * len(self.args), False)

        function = Function.new(g_llvm_module, function_type, self.name)

        # If the name conflicts, already something with the same name
        # If it has a body, don't allow redefinition or re-extern
        if function.name != self.name:
            function.delete()
            function = g_llvm_module.get_function_named(self.name)

            # If the function already has a body, reject it
            if not function.is_declaration:
                raise RuntimeError('Redefinition of function.')

            # THIS IS ESSENTIALLY FUNCTION OVERLOADING, MAYBE CHANGE IN FUTURE
            # If function took different number of args, reject it
            if len(callee.args) != len(self.args):
                raise RuntimeError('Redeclaration of function with different' +
                                   ' number of args')

            # Set names for all args and add them to var symbol table
            for arg, arg_name in zip(function.args, self.args):
                arg.name = arg_name
                # add args to variable symbol table
                g_named_values[arg_name] = arg

            return function
示例#10
0
文件: builtins.py 项目: genba/numba
def complex128_power_impl(context, builder, sig, args):
    [ca, cb] = args
    a = Complex128(context, builder, value=ca)
    b = Complex128(context, builder, value=cb)
    c = Complex128(context, builder)
    module = cgutils.get_module(builder)
    pa = a._getpointer()
    pb = b._getpointer()
    pc = c._getpointer()

    # Optimize for square because cpow looses a lot of precsiion
    TWO = context.get_constant(types.float64, 2)
    ZERO = context.get_constant(types.float64, 0)

    b_real_is_two = builder.fcmp(lc.FCMP_OEQ, b.real, TWO)
    b_imag_is_zero = builder.fcmp(lc.FCMP_OEQ, b.imag, ZERO)
    b_is_two = builder.and_(b_real_is_two, b_imag_is_zero)

    with cgutils.ifelse(builder, b_is_two) as (then, otherwise):
        with then:
            # Lower as multiplication
            res = complex_mul_impl(context, builder, sig, (ca, ca))
            cres = Complex128(context, builder, value=res)
            c.real = cres.real
            c.imag = cres.imag

        with otherwise:
            # Lower with call to external function
            fnty = Type.function(Type.void(), [pa.type] * 3)
            cpow = module.get_or_insert_function(fnty, name="numba.math.cpow")
            builder.call(cpow, (pa, pb, pc))

    return builder.load(pc)
示例#11
0
    def test_uses(self):
        m = Module.new("a")
        t = Type.int()
        ft = Type.function(t, [t, t, t])
        f = m.add_function(ft, "func")
        b = f.append_basic_block("entry")
        bld = Builder.new(b)
        tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1")
        tmp2 = bld.add(tmp1, f.args[1], "tmp2")
        tmp3 = bld.add(tmp1, f.args[2], "tmp3")
        bld.ret(tmp3)

        # Testing use count
        self.assertEqual(f.args[0].use_count, 1)
        self.assertEqual(f.args[1].use_count, 1)
        self.assertEqual(f.args[2].use_count, 1)
        self.assertEqual(tmp1.use_count, 2)
        self.assertEqual(tmp2.use_count, 0)
        self.assertEqual(tmp3.use_count, 1)

        # Testing uses
        self.assert_(f.args[0].uses[0] is tmp1)
        self.assertEqual(len(f.args[0].uses), 1)
        self.assert_(f.args[1].uses[0] is tmp2)
        self.assertEqual(len(f.args[1].uses), 1)
        self.assert_(f.args[2].uses[0] is tmp3)
        self.assertEqual(len(f.args[2].uses), 1)
        self.assertEqual(len(tmp1.uses), 2)
        self.assertEqual(len(tmp2.uses), 0)
        self.assertEqual(len(tmp3.uses), 1)
示例#12
0
    def test_bswap(self):
        # setup a function and a builder
        mod = Module.new("test")
        functy = Type.function(Type.int(), [])
        func = mod.add_function(functy, "showme")
        block = func.append_basic_block("entry")
        b = Builder.new(block)

        # let's do bswap on a 32-bit integer using llvm.bswap
        val = Constant.int(Type.int(), 0x42)
        bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()])

        bswap_res = b.call(bswap, [val])
        b.ret(bswap_res)

        # logging.debug(mod)

        # the output is:
        #
        #    ; ModuleID = 'test'
        #
        #    define void @showme() {
        #    entry:
        #      %0 = call i32 @llvm.bswap.i32(i32 42)
        #      ret i32 %0
        #    }

        # let's run the function
        ee = le.ExecutionEngine.new(mod)
        retval = ee.run_function(func, [])
        self.assertEqual(retval.as_int(), 0x42000000)
示例#13
0
def f_abs(mod):
    '''libc: compute the absolute value of an integer'''
    ret = Type.int()
    args = [Type.int()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "abs")
示例#14
0
def f_roundf(mod):
    '''libc: round to nearest integer, away from zero'''
    ret = Type.float()
    args = [Type.float()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "roundf")
示例#15
0
def f_sqrtf(mod):
    '''libc: square root function'''
    ret = Type.float()
    args = [Type.float()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "sqrtf")
示例#16
0
def f_powf(mod):
    '''libc: power function'''
    ret = Type.float()
    args = [Type.float(), Type.float()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "powf")
示例#17
0
    def test_issue100(self):
        m = Module.new('a')

        pm = FunctionPassManager.new(m)

        ee = ExecutionEngine.new(m)

        pm.add(ee.target_data)

        ti = Type.int()
        tf = Type.function(ti, [])

        f = m.add_function(tf, "func1")

        bb = f.append_basic_block('entry')

        b = Builder.new(bb)

        b.ret(Constant.int(ti, 0))

        f.verify()

        pm.run(f)

        assert ee.run_function(f, []).as_int() == 0
示例#18
0
 def code_gen(self, from_definition=False):
     top_context = self.context.parent_context
     func_name_with_tag = self.func_name_token.word + "()"
     return_type = Helper.get_type(self.ret_type.word)
     arg_types = [Helper.get_type(arg[1]) for arg in self.args if True]
     func_type = Type.function(return_type, arg_types, False)
     if not func_name_with_tag in top_context.type_table:
         function = Function.new(g_llvm_module, func_type,
                                 self.func_name_token.word)
         top_context.type_table[func_name_with_tag] = func_type
         for arg in self.args:
             self.context.type_table[arg[0]] = Helper.get_type(arg[1])
         return [function, self.context]
     else:
         old_func_type = top_context.type_table[func_name_with_tag]
         if old_func_type == func_type:
             if from_definition:
                 for arg in self.args:
                     self.context.type_table[arg[0]] = Helper.get_type(
                         arg[1])
                 return [
                     g_llvm_module.get_function_named(
                         self.func_name_token.word), self.context
                 ]
             else:
                 raise cmexception.RedefineException(
                     self.func_name_token, 'function')
         else:
             raise cmexception.RedefineException(self.func_name_token,
                                                 'function')
示例#19
0
    def test_atomic_ldst(self):
        mod = Module.new('mod')
        functype = Type.function(Type.void(), [])
        func = mod.add_function(functype, name='foo')
        bb = func.append_basic_block('entry')
        bldr = Builder.new(bb)
        ptr = bldr.alloca(Type.int())

        val = Constant.int(Type.int(), 1234)

        for ordering in self.orderings:
            loaded = bldr.atomic_load(ptr, ordering)
            self.assert_('load atomic' in str(loaded))
            self.assertEqual(ordering,
                             str(loaded).strip().split(' ')[-3].rstrip(','))
            self.assert_('align 1' in str(loaded))

            stored = bldr.atomic_store(loaded, ptr, ordering)
            self.assert_('store atomic' in str(stored))
            self.assertEqual(ordering,
                             str(stored).strip().split(' ')[-3].rstrip(','))
            self.assert_('align 1' in str(stored))

            fenced = bldr.fence(ordering)
            self.assertEqual(['fence', ordering],
                             str(fenced).strip().split(' '))
示例#20
0
def f_fabs(mod):
    '''libc: absolute value of floating-point number'''
    ret = Type.double()
    args = [Type.double()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "fabs")
示例#21
0
    def test_atomic_rmw(self):
        mod = Module.new("mod")
        functype = Type.function(Type.void(), [])
        func = mod.add_function(functype, name="foo")
        bb = func.append_basic_block("entry")
        bldr = Builder.new(bb)
        ptr = bldr.alloca(Type.int())

        old = bldr.load(ptr)
        val = Constant.int(Type.int(), 1234)

        for ordering in self.orderings:
            inst = bldr.atomic_rmw("xchg", ptr, val, ordering)
            self.assertEqual(ordering, str(inst).split(" ")[-1])

        for op in self.atomic_op:
            inst = bldr.atomic_rmw(op, ptr, val, ordering)
            self.assertEqual(op, str(inst).strip().split(" ")[3])

        inst = bldr.atomic_rmw("xchg", ptr, val, ordering, crossthread=False)
        self.assertEqual("singlethread", str(inst).strip().split(" ")[-2])

        for op in self.atomic_op:
            atomic_op = getattr(bldr, "atomic_%s" % op)
            inst = atomic_op(ptr, val, ordering)
            self.assertEqual(op, str(inst).strip().split(" ")[3])
示例#22
0
def f_exit(mod):
    '''libc: cause normal process termination'''
    ret = Type.void()
    args = [Type.int(32)]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "exit")
示例#23
0
 def testAppendBasicBlock(self):
     mod = Module.CreateWithName('module')
     ty = Type.int8(context=mod.context)
     ft = Type.function(ty, [ty], False)
     f = mod.add_function('timestwo', ft)
     bb = f.append_basic_block('body')
     self.assertEqual('body', bb.name)
示例#24
0
def f_atoi(mod):
    '''libc: convert a string to an integer'''
    ret = Type.int(32)
    args = [Type.pointer(Type.int(8))]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "atoi")
示例#25
0
文件: pythonapi.py 项目: genba/numba
 def dict_getitem_string(self, dic, name):
     """Returns a borrowed reference
     """
     fnty = Type.function(self.pyobj, [self.pyobj, self.cstring])
     fn = self._get_function(fnty, name="PyDict_GetItemString")
     cstr = self.context.insert_const_string(self.module, name)
     return self.builder.call(fn, [dic, cstr])
示例#26
0
文件: pythonapi.py 项目: genba/numba
 def tuple_pack(self, items):
     fnty = Type.function(self.pyobj, [self.py_ssize_t], var_arg=True)
     fn = self._get_function(fnty, name="PyTuple_Pack")
     n = self.context.get_constant(types.intp, len(items))
     args = [n]
     args.extend(items)
     return self.builder.call(fn, args)
示例#27
0
def f_main(mod):
    '''main function'''
    argc = Type.int(32)
    argv = Type.pointer(Type.pointer(Type.int(8)))
    type_ = Type.function(Type.void(), [argc, argv])

    return mod.get_or_insert_function(type_, "main")
示例#28
0
    def __init__(self, fundef, llvm_cxt=llvm_context.global_context):
        self.parakeet_fundef = fundef
        if config.opt_stack_allocation:
            self.may_escape = may_escape(fundef)
        else:
            self.may_escape = None
        self.llvm_context = llvm_cxt
        self.vars = {}
        self.initialized = set([])
        # Initializes the variables dictionary and returns a builder object
        llvm_input_types = map(llvm_ref_type, fundef.input_types)
        llvm_output_type = llvm_ref_type(fundef.return_type)
        llvm_fn_t = lltype.function(llvm_output_type, llvm_input_types)

        self.llvm_fn = self.llvm_context.module.add_function(
            llvm_fn_t, fundef.name)

        for arg in self.llvm_fn.args:
            if not llvm_types.is_scalar(arg.type):
                arg.add_attribute(ATTR_NO_CAPTURE)

        self.llvm_fn.does_not_throw = True

        self.entry_block, self.entry_builder = self.new_block("entry")
        self._init_vars(self.parakeet_fundef, self.entry_builder)
示例#29
0
文件: testing.py 项目: zhihan/llvm
def create_cumsum_module():
    mod = Module.CreateWithName('module')

    ty = Type.int8(context=mod.context)
    ft = Type.function(ty, [ty], False)

    f = mod.add_function('cumsum', ft)
    bb1 = f.append_basic_block('body')
    bb_hdr = f.append_basic_block('hdr')
    bb_loop = f.append_basic_block('loop')
    bb_exit = f.append_basic_block('exit')

    bldr = Builder.create(mod.context)
    bldr.position_at_end(bb1)
    bldr.branch(bb_hdr)

    bldr.position_at_end(bb_hdr)
    i = bldr.phi(ty, 'i')
    s = bldr.phi(ty, 's')
    zero = Value.const_int(ty, 0, True)
    c = bldr.int_signed_lt(zero, i, 'comp')
    bldr.conditional_branch(c, bb_loop, bb_exit)

    bldr.position_at_end(bb_loop)
    s1 = bldr.add(s, i, 's1')
    i1 = bldr.sub(i, Value.const_int(ty, 1, True), 'i1')
    bldr.branch(bb_hdr)

    i.add_incoming([f.get_param(0), i1], [bb1, bb_loop])
    s.add_incoming([Value.const_int(ty, 0, True), s1], [bb1, bb_loop])

    bldr.position_at_end(bb_exit)
    bldr.ret(s)
    return (mod, f)
示例#30
0
    def test_issue100(self):
        m = Module.new('a')

        pm = FunctionPassManager.new(m)

        ee = ExecutionEngine.new(m)

        pm.add(ee.target_data)

        ti = Type.int()
        tf = Type.function(ti, [])

        f = m.add_function(tf, "func1")

        bb = f.append_basic_block('entry')

        b = Builder.new(bb)

        b.ret(Constant.int(ti, 0))

        f.verify()

        pm.run(f)

        assert ee.run_function(f, []).as_int() == 0
示例#31
0
 def _build_module(self, float):
     mod = Module.new('test')
     functy = Type.function(float, [float])
     func = mod.add_function(functy, "mytest%s" % float)
     block = func.append_basic_block("entry")
     b = Builder.new(block)
     return mod, func, b
示例#32
0
 def call_function_pointer(self, builder, funcptr, signature, args):
     retty = self.get_value_type(signature.return_type)
     fnty = Type.function(retty, [a.type for a in args])
     fnptrty = Type.pointer(fnty)
     addr = self.get_constant(types.intp, funcptr)
     ptr = builder.inttoptr(addr, fnptrty)
     return builder.call(ptr, args)
示例#33
0
文件: testing.py 项目: zhihan/llvm
def create_abs_module():
    mod = Module.CreateWithName('module')

    ty = Type.int8(context=mod.context)
    ft = Type.function(ty, [ty], False)

    f = mod.add_function('abs', ft)
    bb1 = f.append_basic_block('body')
    bbt = f.append_basic_block('true')
    bbf = f.append_basic_block('false')
    bbm = f.append_basic_block('merge')

    bldr = Builder.create(mod.context)
    bldr.position_at_end(bb1)
    x = f.get_param(0)
    zero = Value.const_int(ty, 0, True)
    c = bldr.int_signed_lt(x, zero, 'comp')
    bldr.conditional_branch(c, bbt, bbf)

    # True branch
    bldr.position_at_end(bbt)
    y_t = bldr.neg(x, 'neg_x')
    bldr.branch(bbm)

    # False branch
    bldr.position_at_end(bbf)
    bldr.branch(bbm)

    bldr.position_at_end(bbm)
    y = bldr.phi(ty, 'y')
    y.add_incoming([y_t, x], [bbt, bbf])
    bldr.ret(y)
    return (mod, f)
示例#34
0
 def get_external_function_type(self, fndesc):
     argtypes = [self.get_argument_type(aty)
                 for aty in fndesc.argtypes]
     # don't wrap in pointer
     restype = self.get_argument_type(fndesc.restype)
     fnty = Type.function(restype, argtypes)
     return fnty
示例#35
0
    def test_bswap(self):
        # setup a function and a builder
        mod = Module.new('test')
        functy = Type.function(Type.int(), [])
        func = mod.add_function(functy, "showme")
        block = func.append_basic_block("entry")
        b = Builder.new(block)

        # let's do bswap on a 32-bit integer using llvm.bswap
        val = Constant.int(Type.int(), 0x42)
        bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()])

        bswap_res = b.call(bswap, [val])
        b.ret(bswap_res)

        # logging.debug(mod)

        # the output is:
        #
        #    ; ModuleID = 'test'
        #
        #    define void @showme() {
        #    entry:
        #      %0 = call i32 @llvm.bswap.i32(i32 42)
        #      ret i32 %0
        #    }

        # let's run the function
        ee = le.ExecutionEngine.new(mod)
        retval = ee.run_function(func, [])
        self.assertEqual(retval.as_int(), 0x42000000)
示例#36
0
    def build(self):
        wrapname = "wrapper.%s" % self.func.name

        # This is the signature of PyCFunctionWithKeywords
        # (see CPython's methodobject.h)
        pyobj = self.context.get_argument_type(types.pyobject)
        wrapty = Type.function(pyobj, [pyobj, pyobj, pyobj])
        wrapper = self.module.add_function(wrapty, name=wrapname)

        builder = Builder.new(wrapper.append_basic_block('entry'))

        # - `closure` will receive the `self` pointer stored in the
        #   PyCFunction object (see _dynfunc.c)
        # - `args` and `kws` will receive the tuple and dict objects
        #   of positional and keyword arguments, respectively.
        closure, args, kws = wrapper.args
        closure.name = 'py_closure'
        args.name = 'py_args'
        kws.name = 'py_kws'

        api = self.context.get_python_api(builder)
        self.build_wrapper(api, builder, closure, args, kws)

        wrapper.verify()
        return wrapper, api
示例#37
0
    def test_atomic_ldst(self):
        mod = Module.new('mod')
        functype = Type.function(Type.void(), [])
        func = mod.add_function(functype, name='foo')
        bb = func.append_basic_block('entry')
        bldr = Builder.new(bb)
        ptr = bldr.alloca(Type.int())

        val = Constant.int(Type.int(), 1234)

        for ordering in self.orderings:
            loaded = bldr.atomic_load(ptr, ordering)
            self.assert_('load atomic' in str(loaded))
            self.assertEqual(ordering,
                             str(loaded).strip().split(' ')[-3].rstrip(','))
            self.assert_('align 1' in str(loaded))

            stored = bldr.atomic_store(loaded, ptr, ordering)
            self.assert_('store atomic' in str(stored))
            self.assertEqual(ordering,
                             str(stored).strip().split(' ')[-3].rstrip(','))
            self.assert_('align 1' in str(stored))

            fenced = bldr.fence(ordering)
            self.assertEqual(['fence', ordering],
                             str(fenced).strip().split(' '))
示例#38
0
    def test_uses(self):
        m = Module.new('a')
        t = Type.int()
        ft = Type.function(t, [t, t, t])
        f = m.add_function(ft, "func")
        b = f.append_basic_block('entry')
        bld = Builder.new(b)
        tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1")
        tmp2 = bld.add(tmp1, f.args[1], "tmp2")
        tmp3 = bld.add(tmp1, f.args[2], "tmp3")
        bld.ret(tmp3)

        # Testing use count
        self.assertEqual(f.args[0].use_count, 1)
        self.assertEqual(f.args[1].use_count, 1)
        self.assertEqual(f.args[2].use_count, 1)
        self.assertEqual(tmp1.use_count, 2)
        self.assertEqual(tmp2.use_count, 0)
        self.assertEqual(tmp3.use_count, 1)

        # Testing uses
        self.assert_(f.args[0].uses[0] is tmp1)
        self.assertEqual(len(f.args[0].uses), 1)
        self.assert_(f.args[1].uses[0] is tmp2)
        self.assertEqual(len(f.args[1].uses), 1)
        self.assert_(f.args[2].uses[0] is tmp3)
        self.assertEqual(len(f.args[2].uses), 1)
        self.assertEqual(len(tmp1.uses), 2)
        self.assertEqual(len(tmp2.uses), 0)
        self.assertEqual(len(tmp3.uses), 1)
 def CodeGen(self):
     # Make the function type, eg. double(double,double).
     funct_type = Type.function(Type.double(), [Type.double()] * len(self.args), False)
                                                 
     function = Function.new(g_llvm_module, funct_type, self.name)
                                                     
     # If the name conflicted, there was already something with the same name.
     # If it has a body, don't allow redefinition or reextern.
     if function.name != self.name:
         function.delete()
         function = g_llvm_module.get_function_named(self.name)
                                                                 
         # If the function already has a body, reject this.
         if not function.is_declaration:
             raise RuntimeError('Redefinition of function.')
                                                                         
         # If the function took a different number of args, reject.
         if len(function.args) != len(self.args):
             raise RuntimeError('Redeclaration of a function with different number of args.')
                                                                                 
     # Set names for all arguments and add them to the variables symbol table.
     for arg, arg_name in zip(function.args, self.args):
         arg.name = arg_name
                                                                                         
     return function
示例#40
0
    def test_atomic_rmw(self):
        mod = Module.new('mod')
        functype = Type.function(Type.void(), [])
        func = mod.add_function(functype, name='foo')
        bb = func.append_basic_block('entry')
        bldr = Builder.new(bb)
        ptr = bldr.alloca(Type.int())

        old = bldr.load(ptr)
        val = Constant.int(Type.int(), 1234)

        for ordering in self.orderings:
            inst = bldr.atomic_rmw('xchg', ptr, val, ordering)
            self.assertEqual(ordering, str(inst).split(' ')[-1])

        for op in self.atomic_op:
            inst = bldr.atomic_rmw(op, ptr, val, ordering)
            self.assertEqual(op, str(inst).strip().split(' ')[3])

        inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False)
        self.assertEqual('singlethread', str(inst).strip().split(' ')[-2])

        for op in self.atomic_op:
            atomic_op = getattr(bldr, 'atomic_%s' % op)
            inst = atomic_op(ptr, val, ordering)
            self.assertEqual(op, str(inst).strip().split(' ')[3])
示例#41
0
    def build(self):
        wrapname = "wrapper.%s" % self.func.name

        # This is the signature of PyCFunctionWithKeywords
        # (see CPython's methodobject.h)
        pyobj = self.context.get_argument_type(types.pyobject)
        wrapty = Type.function(pyobj, [pyobj, pyobj, pyobj])
        wrapper = self.module.add_function(wrapty, name=wrapname)

        builder = Builder.new(wrapper.append_basic_block('entry'))

        # - `closure` will receive the `self` pointer stored in the
        #   PyCFunction object (see _dynfunc.c)
        # - `args` and `kws` will receive the tuple and dict objects
        #   of positional and keyword arguments, respectively.
        closure, args, kws = wrapper.args
        closure.name = 'py_closure'
        args.name = 'py_args'
        kws.name = 'py_kws'

        api = self.context.get_python_api(builder)
        self.build_wrapper(api, builder, closure, args, kws)

        wrapper.verify()
        return wrapper, api
示例#42
0
文件: pythonapi.py 项目: genba/numba
 def numba_array_adaptor(self, ary, ptr):
     voidptr = Type.pointer(Type.int(8))
     fnty = Type.function(Type.int(), [self.pyobj, voidptr])
     fn = self._get_function(fnty, name="numba_adapt_ndarray")
     fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE)
     fn.args[1].add_attribute(lc.ATTR_NO_CAPTURE)
     return self.builder.call(fn, (ary, ptr))
示例#43
0
文件: pythonapi.py 项目: genba/numba
 def parse_tuple_and_keywords(self, args, kws, fmt, keywords, *objs):
     charptr = Type.pointer(Type.int(8))
     charptrary = Type.pointer(charptr)
     argtypes = [self.pyobj, self.pyobj, charptr, charptrary]
     fnty = Type.function(Type.int(), argtypes, var_arg=True)
     fn = self._get_function(fnty, name="PyArg_ParseTupleAndKeywords")
     return self.builder.call(fn, [args, kws, fmt, keywords] + list(objs))
示例#44
0
文件: pythonapi.py 项目: genba/numba
 def object_dump(self, obj):
     """
     Dump a Python object on C stderr.  For debugging purposes.
     """
     fnty = Type.function(Type.void(), [self.pyobj])
     fn = self._get_function(fnty, name="_PyObject_Dump")
     return self.builder.call(fn, (obj, ))
示例#45
0
文件: pythonapi.py 项目: scchan/numba
 def object_dump(self, obj):
     """
     Dump a Python object on C stderr.  For debugging purposes.
     """
     fnty = Type.function(Type.void(), [self.pyobj])
     fn = self._get_function(fnty, name="_PyObject_Dump")
     return self.builder.call(fn, (obj,))
示例#46
0
def complex128_power_impl(context, builder, sig, args):
    [ca, cb] = args
    a = Complex128(context, builder, value=ca)
    b = Complex128(context, builder, value=cb)
    c = Complex128(context, builder)
    module = cgutils.get_module(builder)
    pa = a._getpointer()
    pb = b._getpointer()
    pc = c._getpointer()

    # Optimize for square because cpow looses a lot of precsiion
    TWO = context.get_constant(types.float64, 2)
    ZERO = context.get_constant(types.float64, 0)

    b_real_is_two = builder.fcmp(lc.FCMP_OEQ, b.real, TWO)
    b_imag_is_zero = builder.fcmp(lc.FCMP_OEQ, b.imag, ZERO)
    b_is_two = builder.and_(b_real_is_two, b_imag_is_zero)

    with cgutils.ifelse(builder, b_is_two) as (then, otherwise):
        with then:
            # Lower as multiplication
            res = complex_mul_impl(context, builder, sig, (ca, ca))
            cres = Complex128(context, builder, value=res)
            c.real = cres.real
            c.imag = cres.imag

        with otherwise:
            # Lower with call to external function
            fnty = Type.function(Type.void(), [pa.type] * 3)
            cpow = module.get_or_insert_function(fnty, name="numba.math.cpow")
            builder.call(cpow, (pa, pb, pc))

    return builder.load(pc)
示例#47
0
 def _build_module(self, float):
     mod     = Module.new('test')
     functy  = Type.function(float, [float])
     func    = mod.add_function(functy, "mytest%s" % float)
     block   = func.append_basic_block("entry")
     b       = Builder.new(block)
     return mod, func, b
示例#48
0
 def testAppendBasicBlock(self):
     mod = Module.CreateWithName('module')
     ty = Type.int8(context=mod.context)
     ft = Type.function(ty, [ty], False)
     f = mod.add_function('timestwo', ft)
     bb = f.append_basic_block('body')
     self.assertEqual('body', bb.name)
示例#49
0
def create_instance(mod, spec, ctx):

    #  Spine
    #    |
    #
    # T ... = A .. | B .. | C ..
    #
    #                |
    #              Values

    lvals = []
    instances = []

    # Values
    # ======
    for value in spec.values:
        tys = [ctx[id] for id in value.params]
        lvals += [(value.name, Type.struct(tys, value.name))]

    # Spine
    # ======
    spine = Type.struct([a[1] for a in lvals], 'maybe')

    for i, (name, value) in enumerate(lvals):
        fn_spec = Type.function(void, value.elements)
        F = mod.add_function(fn_spec, value.name)
        instances += [F]

        build_constructor(F, value, spine, 1)

    return spine, instances
示例#50
0
文件: pythonapi.py 项目: albop/numba
 def dict_getitem_string(self, dic, name):
     """Returns a borrowed reference
     """
     fnty = Type.function(self.pyobj, [self.pyobj, self.cstring])
     fn = self._get_function(fnty, name="PyDict_GetItemString")
     cstr = self.context.insert_const_string(self.module, name)
     return self.builder.call(fn, [dic, cstr])
示例#51
0
文件: pythonapi.py 项目: albop/numba
 def parse_tuple_and_keywords(self, args, kws, fmt, keywords, *objs):
     charptr = Type.pointer(Type.int(8))
     charptrary = Type.pointer(charptr)
     argtypes = [self.pyobj, self.pyobj, charptr, charptrary]
     fnty = Type.function(Type.int(), argtypes, var_arg=True)
     fn = self._get_function(fnty, name="PyArg_ParseTupleAndKeywords")
     return self.builder.call(fn, [args, kws, fmt, keywords] + list(objs))
示例#52
0
文件: pythonapi.py 项目: albop/numba
 def numba_array_adaptor(self, ary, ptr):
     voidptr = Type.pointer(Type.int(8))
     fnty = Type.function(Type.int(), [self.pyobj, voidptr])
     fn = self._get_function(fnty, name="NumbaArrayAdaptor")
     fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE)
     fn.args[1].add_attribute(lc.ATTR_NO_CAPTURE)
     return self.builder.call(fn, (ary, ptr))
示例#53
0
文件: pythonapi.py 项目: albop/numba
 def tuple_pack(self, items):
     fnty = Type.function(self.pyobj, [self.py_ssize_t], var_arg=True)
     fn = self._get_function(fnty, name="PyTuple_Pack")
     n = self.context.get_constant(types.intp, len(items))
     args = [n]
     args.extend(items)
     return self.builder.call(fn, args)
示例#54
0
文件: pythonapi.py 项目: genba/numba
 def list_setitem(self, seq, idx, val):
     """
     Warning: Steals reference to ``val``
     """
     fnty = Type.function(Type.int(),
                          [self.pyobj, self.py_ssize_t, self.pyobj])
     fn = self._get_function(fnty, name="PyList_SetItem")
     return self.builder.call(fn, [seq, idx, val])
示例#55
0
文件: pythonapi.py 项目: genba/numba
 def string_as_string(self, strobj):
     fnty = Type.function(self.cstring, [self.pyobj])
     if PYVERSION >= (3, 0):
         fname = "PyUnicode_AsUTF8"
     else:
         fname = "PyString_AsString"
     fn = self._get_function(fnty, name=fname)
     return self.builder.call(fn, [strobj])
示例#56
0
文件: pythonapi.py 项目: genba/numba
 def tuple_setitem(self, tuple_val, index, item):
     """
     Steals a reference to `item`.
     """
     fnty = Type.function(Type.int(), [self.pyobj, Type.int(), self.pyobj])
     setitem_fn = self._get_function(fnty, name='PyTuple_SetItem')
     index = self.context.get_constant(types.int32, index)
     self.builder.call(setitem_fn, [tuple_val, index, item])
示例#57
0
文件: pythonapi.py 项目: genba/numba
 def tuple_getitem(self, tup, idx):
     """
     Borrow reference
     """
     fnty = Type.function(self.pyobj, [self.pyobj, self.py_ssize_t])
     fn = self._get_function(fnty, name="PyTuple_GetItem")
     idx = self.context.get_constant(types.intp, idx)
     return self.builder.call(fn, [tup, idx])
示例#58
0
文件: pythonapi.py 项目: genba/numba
 def bytes_from_string_and_size(self, string, size):
     fnty = Type.function(self.pyobj, [self.cstring, self.py_ssize_t])
     if PYVERSION >= (3, 0):
         fname = "PyBytes_FromStringAndSize"
     else:
         fname = "PyString_FromStringAndSize"
     fn = self._get_function(fnty, name=fname)
     return self.builder.call(fn, [string, size])