Пример #1
0
    def testCreateVectorType(self):
        ty = Type.int8()
        a = Type.vector(ty, 2)
        self.assertEqual(2, a.vector_size())

        t = a.element_type()
        self.assertEqual(ty.name, t.name)
Пример #2
0
    def code_gen(self):

        if self.context.parent_context is None:
            if self.var_name_token.word in self.context.type_table:
                raise cmexception.RedefineException(self.var_name_token, 'Global Variable')
            else:
                t = Helper.get_type(self.typo.word)
                gv = GlobalVariable.new(g_llvm_module, t, self.var_name_token.word)
                self.context.type_table[self.var_name_token.word] = t
                self.context.value_table[self.var_name_token.word] = gv
                if self.typo.word == 'int':
                    gv.initializer = Constant.int(Type.int(32), 0)
                elif self.typo.word == 'double':
                    gv.initializer = Constant.real(Type.double(), 0)
                elif self.typo.word == 'char':
                    gv.initializer = Constant.int(Type.int(8), 0)
                else:
                    gv.initializer = Constant.stringz("")
        else:
            if not self.var_name_token.word in self.context.type_table:
                t = Helper.get_type(self.typo.word)
                var_address = g_llvm_builder.alloca(t, name=self.var_name_token.word)
                self.context.type_table[self.var_name_token.word] = t
                self.context.value_table[self.var_name_token.word] = var_address
            else:
                raise cmexception.RedefineException(self.var_name_token)
Пример #3
0
    def testCreateArrayType(self):
        ty = Type.int8()
        a = Type.array(ty, 2)
        self.assertEqual(2, a.array_length())

        t = a.element_type()
        self.assertEqual(ty.name, t.name)
Пример #4
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
Пример #5
0
 def code_gen(self):
     if self.context.parent_context is None:
         if self.array_name_token.word in self.context.type_table:
             raise cmexception.RedefineException(self.array_name_token)
         else:
             t = Helper.get_array_type(self.typo.word, int(self.length.word))
             gv = GlobalVariable.new(g_llvm_module, t, self.array_name_token.word)
             initials = [i.code_gen() for i in self.initial_value if True]
             constant_array = ConstantArray.array(Helper.get_type(self.typo.word), initials)
             gv.initializer = constant_array
             self.context.type_table[self.array_name_token.word] = t
             self.context.value_table[self.array_name_token.word] = gv
     else:
         if self.array_name_token.word in self.context.type_table:
             raise cmexception.RedefineException(self.array_name_token)
         else:
             t = Helper.get_array_type(self.typo.word, int(self.length.word))
             array_address = g_llvm_builder.alloca(t, name=self.array_name_token.word)
             inx = 0
             for i in self.initial_value:
                 value = i.code_gen()
                 if value in g_llvm_module.global_variables:
                     string_value_ptr = g_llvm_builder.gep(
                         value, [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0)])
                     var_address = g_llvm_builder.gep(
                         array_address, [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), inx)])
                     g_llvm_builder.store(string_value_ptr, var_address)
                 else:
                     var_address = g_llvm_builder.gep(
                         array_address, [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), inx)])
                     g_llvm_builder.store(value, var_address)
                 inx += 1
             self.context.type_table[self.array_name_token.word] = t
             self.context.value_table[self.array_name_token.word] = array_address
Пример #6
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")
Пример #7
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")
Пример #8
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")
Пример #9
0
def _generic_array(context, builder, shape, dtype, symbol_name, addrspace,
                   can_dynsized=False):
    elemcount = reduce(operator.mul, shape)
    lldtype = context.get_data_type(dtype)
    laryty = Type.array(lldtype, elemcount)

    if addrspace == nvvm.ADDRSPACE_LOCAL:
        # Special case local addrespace allocation to use alloca
        # NVVM is smart enough to only use local memory if no register is
        # available
        dataptr = builder.alloca(laryty, name=symbol_name)
    else:
        lmod = cgutils.get_module(builder)

        # Create global variable in the requested address-space
        gvmem = lmod.add_global_variable(laryty, symbol_name, addrspace)

        if elemcount <= 0:
            if can_dynsized:    # dynamic shared memory
                gvmem.linkage = lc.LINKAGE_EXTERNAL
            else:
                raise ValueError("array length <= 0")
        else:
            gvmem.linkage = lc.LINKAGE_INTERNAL
            gvmem.initializer = lc.Constant.undef(laryty)

        if dtype not in types.number_domain:
            raise TypeError("unsupported type: %s" % dtype)

        # Convert to generic address-space
        conv = nvvmutils.insert_addrspace_conv(lmod, Type.int(8), addrspace)
        addrspaceptr = gvmem.bitcast(Type.pointer(Type.int(8), addrspace))
        dataptr = builder.call(conv, [addrspaceptr])

    return _make_array(context, builder, dataptr, dtype, shape)
Пример #10
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)
Пример #11
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")
Пример #12
0
    def insert_string_const_addrspace(self, builder, string):
        """
        Insert a constant string in the constant addresspace and return a
        generic i8 pointer to the data.

        This function attempts to deduplicate.
        """
        lmod = builder.basic_block.function.module
        text = Constant.stringz(string)
        name = "__conststring__.%s" % string
        charty = Type.int(8)

        for gv in lmod.global_variables:
            if gv.name == name and gv.type.pointee == text.type:
                break
        else:
            gl = lmod.add_global_variable(text.type, name=name,
                                          addrspace=nvvm.ADDRSPACE_CONSTANT)
            gl.linkage = LINKAGE_INTERNAL
            gl.global_constant = True
            gl.initializer = text

            constcharptrty = Type.pointer(charty, nvvm.ADDRSPACE_CONSTANT)
            charptr = builder.bitcast(gl, constcharptrty)

        conv = nvvmutils.insert_addrspace_conv(lmod, charty,
                                               nvvm.ADDRSPACE_CONSTANT)
        return builder.call(conv, [charptr])
Пример #13
0
def set_branch_weight(builder, brinst, trueweight, falseweight):
    module = get_module(builder)
    mdid = lc.MetaDataString.get(module, "branch_weights")
    trueweight = lc.Constant.int(Type.int(), trueweight)
    falseweight = lc.Constant.int(Type.int(), falseweight)
    md = lc.MetaData.get(module, [mdid, trueweight, falseweight])
    brinst.set_metadata("prof", md)
Пример #14
0
def args_to_kernel_data_struct(kinds, argtypes):
    # Build up the kernel data structure. Currently, this means
    # adding a shape field for each array argument. First comes
    # the kernel data prefix with a spot for the 'owner' reference added.
    input_field_indices = []
    kernel_data_fields = [Type.struct([int8_p_type]*3)]
    kernel_data_ctypes_fields = [('base', JITCKernelData)]
    for i, (kind, a) in enumerate(izip(kinds, argtypes)):
        if isinstance(kind, tuple):
            if kind[0] != lla.C_CONTIGUOUS:
                raise ValueError('only support C contiguous array presently')
            input_field_indices.append(len(kernel_data_fields))
            kernel_data_fields.append(Type.array(
                            intp_type, len(bek.dshapes[i])-1))
            kernel_data_ctypes_fields.append(('operand_%d' % i,
                            c_ssize_t * (len(bek.dshapes[i])-1)))
        elif kind in [lla.SCALAR, lla.POINTER]:
            input_field_indices.append(None)
        else:
            raise TypeError(("unbound_single_ckernel codegen doesn't " +
                            "support the parameter kind %r yet") % (k,))
    # Make an LLVM and ctypes type for the extra data pointer.
    kernel_data_llvmtype = Type.struct(kernel_data_fields)
    class kernel_data_ctypestype(ctypes.Structure):
        _fields_ = kernel_data_ctypes_fields
    return (kernel_data_llvmtype, kernel_data_ctypestype)
Пример #15
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)
Пример #16
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(' '))
Пример #17
0
def is_scalar_zero(builder, value):
    nullval = Constant.null(value.type)
    if value.type in (Type.float(), Type.double()):
        isnull = builder.fcmp(lc.FCMP_OEQ, nullval, value)
    else:
        isnull = builder.icmp(lc.ICMP_EQ, nullval, value)
    return isnull
Пример #18
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])
Пример #19
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)
Пример #20
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)
Пример #21
0
    def __init__(self, context, builder, value=None, ref=None, cast_ref=False):
        self._type = context.get_struct_type(self)
        self._context = context
        self._builder = builder
        if ref is None:
            self._value = alloca_once(builder, self._type)
            if value is not None:
                assert not is_pointer(value.type)
                assert value.type == self._type, (value.type, self._type)
                builder.store(value, self._value)
        else:
            assert value is None
            assert is_pointer(ref.type)
            if self._type != ref.type.pointee:
                if cast_ref:
                    ref = builder.bitcast(ref, Type.pointer(self._type))
                else:
                    raise TypeError(
                        "mismatching pointer type: got %s, expected %s"
                        % (ref.type.pointee, self._type))
            self._value = ref

        self._namemap = {}
        self._fdmap = []
        self._typemap = []
        base = Constant.int(Type.int(), 0)
        for i, (k, tp) in enumerate(self._fields):
            self._namemap[k] = i
            self._fdmap.append((base, Constant.int(Type.int(), i)))
            self._typemap.append(tp)
Пример #22
0
 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))
Пример #23
0
 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,))
Пример #24
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)
Пример #25
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)
Пример #26
0
 def __init__(self):
     self.nbranch = 0
     self.nlabel = 0
     self.op_assign = {
         'ASSIGN': '',
         'ASSIGN_PLUS': '',
         'ASSIGN_MINUS': ''
     }
     self.op_arithmetic = {
         'PLUS': 'add',
         'MINUS': 'sub',
         'MULT': 'imul',
         'DIV': 'idiv'
     }
     self.op_compare = {
         'EQ': IPRED_EQ,
         'NEQ': IPRED_NE,
         'LT': IPRED_SLT,
         'LTE': IPRED_SLE,
         'GT': IPRED_SGT,
         'GTE': IPRED_SGE
     }
     self.op_logical = {
         'LAND': '',
         'LOR': ''
     }
     self.types = {
         'bool': Type.int(1),
         'int': Type.int(32)
     }
     self.undefined_functions = {}
     self.returns = {}
Пример #27
0
 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))
Пример #28
0
    def code_gen(self):
        condition = self.condition.code_gen()
        condition_bool = g_llvm_builder.fcmp(FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcmd')
        function = g_llvm_builder.basic_block.function

        then_block = function.append_basic_block('then')
        else_block = function.append_basic_block('else')
        merge_block = function.append_basic_block('ifcond')

        g_llvm_builder.cbranch(condition_bool, then_block, else_block)
        g_llvm_builder.position_at_end(then_block)
        then_value = self.then_branch.code_gen()
        g_llvm_builder.branch(merge_block)

        then_block = g_llvm_builder.basic_block

        g_llvm_builder.position_at_end(else_block)
        else_value = self.else_branch.code_gen()
        g_llvm_builder.branch(merge_block)

        else_block = g_llvm_builder.basic_block

        g_llvm_builder.position_at_end(merge_block)
        phi = g_llvm_builder.phi(Type.double(), 'iftmp')
        phi.add_incoming(then_value, then_block)
        phi.add_incoming(else_value, else_block)

        return phi
Пример #29
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")
 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
Пример #31
0
 def number_float(self, val):
     fnty = Type.function(self.pyobj, [self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_Float")
     return self.builder.call(fn, [val])
Пример #32
0
 def number_positive(self, obj):
     fnty = Type.function(self.pyobj, [self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_Positive")
     return self.builder.call(fn, (obj, ))
Пример #33
0
 def number_power(self, lhs, rhs, inplace=False):
     fnty = Type.function(self.pyobj, [self.pyobj] * 3)
     fname = "PyNumber_InPlacePower" if inplace else "PyNumber_Power"
     fn = self._get_function(fnty, fname)
     return self.builder.call(fn, [lhs, rhs, self.borrow_none()])
Пример #34
0
 def _get_number_operator(self, name):
     fnty = Type.function(self.pyobj, [self.pyobj, self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_%s" % name)
     return fn
Пример #35
0
 def long_as_longlong(self, numobj):
     fnty = Type.function(self.ulonglong, [self.pyobj])
     fn = self._get_function(fnty, name="PyLong_AsLongLong")
     return self.builder.call(fn, [numobj])
Пример #36
0
import llvm.ee as le
import llvm.core as lc
import llvm.passes as lp

from llvm import LLVMException
from llvm.core import Module, Builder, Function, Type, Constant, GlobalVariable

from collections import defaultdict

#------------------------------------------------------------------------
# LLVM Types
#------------------------------------------------------------------------

ptrsize = ctypes.sizeof(ctypes.c_void_p)

int_type = Type.int()
float_type = Type.double()
bool_type = Type.int(1)
void_type = Type.void()
char_type = Type.int(8)

pointer = Type.pointer

any_type = pointer(Type.int(ptrsize))
string_type = pointer(char_type)

# { i32*, i32, i32* }
array_type = lambda elt_type: Type.struct(
    [
        pointer(elt_type),  # data         | (<type>)*
        int_type,  # dimensions   | int
Пример #37
0
 def bool_from_long(self, ival):
     fnty = Type.function(self.pyobj, [self.long])
     fn = self._get_function(fnty, name="PyBool_FromLong")
     return self.builder.call(fn, [ival])
Пример #38
0
 def dict_setitem(self, dictobj, nameobj, valobj):
     fnty = Type.function(Type.int(), (self.pyobj, self.pyobj, self.pyobj))
     fn = self._get_function(fnty, name="PyDict_SetItem")
     return self.builder.call(fn, (dictobj, nameobj, valobj))
Пример #39
0
 def err_set_object(self, exctype, excval):
     fnty = Type.function(Type.void(), [self.pyobj, self.pyobj])
     fn = self._get_function(fnty, name="PyErr_SetObject")
     return self.builder.call(fn, (exctype, excval))
Пример #40
0
 def err_occurred(self):
     fnty = Type.function(self.pyobj, ())
     fn = self._get_function(fnty, name="PyErr_Occurred")
     return self.builder.call(fn, ())
Пример #41
0
    def op_DEF_FOREIGN(self, name, retty, argtys):
        largtys = map(arg_typemap, argtys)
        lretty = arg_typemap(retty)

        func_type = Type.function(lretty, largtys, False)
        self.globals[name] = Function.new(self.module, func_type, name)
Пример #42
0
 def number_invert(self, obj):
     fnty = Type.function(self.pyobj, [self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_Invert")
     return self.builder.call(fn, (obj, ))
Пример #43
0
 def float_as_double(self, fobj):
     fnty = Type.function(self.double, [self.pyobj])
     fn = self._get_function(fnty, name="PyFloat_AsDouble")
     return self.builder.call(fn, [fobj])
Пример #44
0
    def test_mysin(self):
        if sys.platform == 'win32' and BITS == 32:
            # float32 support is known to fail on 32-bit Windows
            return

        # mysin(x) = sqrt(1.0 - pow(cos(x), 2))
        mod = Module.new('test')

        float = Type.float()
        mysinty = Type.function(float, [float])
        mysin = mod.add_function(mysinty, "mysin")
        block = mysin.append_basic_block("entry")
        b = Builder.new(block)

        sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float])
        pow = Function.intrinsic(mod, lc.INTR_POWI, [float])
        cos = Function.intrinsic(mod, lc.INTR_COS, [float])

        mysin.args[0].name = "x"
        x = mysin.args[0]
        one = Constant.real(float, "1")
        cosx = b.call(cos, [x], "cosx")
        cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2")
        onemc2 = b.fsub(one, cos2, "onemc2")  # Should use fsub
        sin = b.call(sqrt, [onemc2], "sin")
        b.ret(sin)
        #logging.debug(mod)

        #   ; ModuleID = 'test'
        #
        #   define void @showme() {
        #   entry:
        #       call i32 @llvm.bswap.i32( i32 42 )              ; <i32>:0 [#uses
        #   }
        #
        #   declare i32 @llvm.bswap.i32(i32) nounwind readnone
        #
        #   define float @mysin(float %x) {
        #   entry:
        #       %cosx = call float @llvm.cos.f32( float %x )            ; <float
        #       %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 )
        #       %onemc2 = sub float 1.000000e+00, %cos2         ; <float> [#uses
        #       %sin = call float @llvm.sqrt.f32( float %onemc2 )
        #       ret float %sin
        #   }
        #
        #   declare float @llvm.sqrt.f32(float) nounwind readnone
        #
        #   declare float @llvm.powi.f32(float, i32) nounwind readnone
        #
        #   declare float @llvm.cos.f32(float) nounwind readnone

        # let's run the function

        from llvm.workaround.avx_support import detect_avx_support
        if not detect_avx_support():
            ee = le.EngineBuilder.new(mod).mattrs("-avx").create()
        else:
            ee = le.EngineBuilder.new(mod).create()

        arg = le.GenericValue.real(Type.float(), 1.234)
        retval = ee.run_function(mysin, [arg])

        golden = math.sin(1.234)
        answer = retval.as_real(Type.float())
        self.assertTrue(abs(answer - golden) / golden < 1e-5)
Пример #45
0
def create_ckernel_interface(bek, strided):
    """Create a function wrapper with a CKernel interface according to
    `strided`.

    Parameters
    ----------
    bek : BlazeElementKernel
        The blaze kernel to compile into an unbound single ckernel.
    strided : bool
        If true, returns an ExprStridedOperation, otherwise an
        ExprSingleOperation.
    """

    # TODO: Decouple this from BlazeElementKernel

    inarg_count = len(bek.kinds)-1
    module = bek.module.clone()
    if strided:
        ck_func_name = bek.func.name +"_strided_ckernel"
        ck_func = Function.new(module, strided_ckernel_func_type,
                                          name=ck_func_name)
    else:
        ck_func_name = bek.func.name +"_single_ckernel"
        ck_func = Function.new(module, single_ckernel_func_type,
                                          name=ck_func_name)
    entry_block = ck_func.append_basic_block('entry')
    builder = lc.Builder.new(entry_block)
    if strided:
        dst_ptr_arg, dst_stride_arg, \
            src_ptr_arr_arg, src_stride_arr_arg, \
            count_arg, extra_ptr_arg = ck_func.args
        dst_stride_arg.name = 'dst_stride'
        src_stride_arr_arg.name = 'src_strides'
        count_arg.name = 'count'
    else:
        dst_ptr_arg, src_ptr_arr_arg, extra_ptr_arg = ck_func.args
    dst_ptr_arg.name = 'dst_ptr'
    src_ptr_arr_arg.name = 'src_ptrs'
    extra_ptr_arg.name = 'extra_ptr'

    if strided:
        # Allocate an array of pointer counters for the
        # strided loop
        src_ptr_arr_tmp = builder.alloca_array(int8_p_type,
                        lc.Constant.int(int32_type, inarg_count), 'src_ptr_arr')
        # Copy the pointers
        for i in range(inarg_count):
            builder.store(builder.load(builder.gep(src_ptr_arr_arg,
                            (lc.Constant.int(int32_type, i),))),
                          builder.gep(src_ptr_arr_tmp,
                            (lc.Constant.int(int32_type, i),)))
        # Get all the src strides
        src_stride_vals = [builder.load(builder.gep(src_stride_arr_arg,
                                        (lc.Constant.int(int32_type, i),)))
                            for i in range(inarg_count)]
        # Replace src_ptr_arr_arg with this local variable
        src_ptr_arr_arg = src_ptr_arr_tmp

        # Initialize some more basic blocks for the strided loop
        looptest_block = ck_func.append_basic_block('looptest')
        loopbody_block = ck_func.append_basic_block('loopbody')
        end_block = ck_func.append_basic_block('finish')

        # Finish the entry block by branching
        # to the looptest block
        builder.branch(looptest_block)

        # The looptest block continues the loop while counter != 0
        builder.position_at_end(looptest_block)
        counter_phi = builder.phi(count_arg.type)
        counter_phi.add_incoming(count_arg, entry_block)
        dst_ptr_phi = builder.phi(dst_ptr_arg.type)
        dst_ptr_phi.add_incoming(dst_ptr_arg, entry_block)
        dst_ptr_arg = dst_ptr_phi
        kzero = lc.Constant.int(count_arg.type, 0)
        pred = builder.icmp(lc.ICMP_NE, counter_phi, kzero)
        builder.cbranch(pred, loopbody_block, end_block)

        # The loopbody block decrements the counter, and executes
        # one kernel iteration
        builder.position_at_end(loopbody_block)
        kone = lc.Constant.int(counter_phi.type, 1)
        counter_dec = builder.sub(counter_phi, kone)
        counter_phi.add_incoming(counter_dec, loopbody_block)

    # Convert the src pointer args to the
    # appropriate kinds for the llvm call
    args = build_llvm_src_ptrs(builder, src_ptr_arr_arg,
                    bek.dshapes, bek.kinds[:-1], bek.argtypes)
    # Call the function and store in the dst
    kind = bek.kinds[-1]
    func = module.get_function_named(bek.func.name)
    if kind == lla.SCALAR:
        dst_ptr = builder.bitcast(dst_ptr_arg,
                        Type.pointer(bek.return_type))
        dst_val = builder.call(func, args)
        builder.store(dst_val, dst_ptr)
    else:
        dst_ptr = build_llvm_arg_ptr(builder, dst_ptr_arg,
                        bek.dshapes[-1], kind, bek.argtypes[-1])
        builder.call(func, args + [dst_ptr])

    if strided:
        # Finish the loopbody block by incrementing all the pointers
        # and branching to the looptest block
        dst_ptr_inc = builder.gep(dst_ptr_arg, (dst_stride_arg,))
        dst_ptr_phi.add_incoming(dst_ptr_inc, loopbody_block)
        # Increment the src pointers
        for i in range(inarg_count):
            src_ptr_val = builder.load(builder.gep(src_ptr_arr_tmp,
                            (lc.Constant.int(int32_type, i),)))
            src_ptr_inc = builder.gep(src_ptr_val, (src_stride_vals[i],))
            builder.store(src_ptr_inc,
                          builder.gep(src_ptr_arr_tmp,
                            (lc.Constant.int(int32_type, i),)))
        builder.branch(looptest_block)

        # The end block just returns
        builder.position_at_end(end_block)

    builder.ret_void()

    #print("Function before optimization passes:")
    #print(ck_func)
    #module.verify()

    return module, ck_func
Пример #46
0
def int_utruediv_impl(context, builder, sig, args):
    x, y = args
    fx = builder.uitofp(x, Type.double())
    fy = builder.uitofp(y, Type.double())
    cgutils.guard_zero(context, builder, y)
    return builder.fdiv(fx, fy)
Пример #47
0
from __future__ import print_function, absolute_import
import sys
from llvm.core import Type, Function, Builder, Module
import llvm.core as lc
import llvm.ee as le
import multiprocessing
from ctypes import *

INTRINSICS = {}

CTYPES_MAP = {
    Type.int(): c_int32,
    Type.int(64): c_int64,
    Type.float(): c_float,
    Type.double(): c_double,
}


def register(name, retty, *args):
    def wrap(fn):
        INTRINSICS[name] = (retty, args), fn
        return fn
    return wrap


def intr_impl(intrcode, *types):
    def impl(module, builder, args):
        intr = Function.intrinsic(module, intrcode, types)
        r = builder.call(intr, args)
        return r
    return impl
Пример #48
0
import sys
import ctypes
import struct as struct_
from llvm.core import Type

_trace_refs_ = hasattr(sys, 'getobjects')
_plat_bits = struct_.calcsize('@P') * 8

_int8 = Type.int(8)
_int32 = Type.int(32)

_void_star = Type.pointer(_int8)

_int8_star = _void_star
_pyobject_head_struct_p = _void_star

_sizeof_py_ssize_t = ctypes.sizeof(getattr(ctypes, 'c_size_t'))
_llvm_py_ssize_t = Type.int(_sizeof_py_ssize_t * 8)
Пример #49
0
 def number_long(self, numobj):
     fnty = Type.function(self.pyobj, [self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_Long")
     return self.builder.call(fn, [numobj])
Пример #50
0
 def create_module(self):
     # create a module
     m = Module.new('module1')
     m.add_global_variable(Type.int(), 'i')
     return m
Пример #51
0
def as_bool_byte(builder, value):
    return builder.zext(value, Type.int(8))
Пример #52
0
 def value(self, backend):
     '''Representation when used in a function and as a return value.
         '''
     return Type.pointer(Type.vector(Type.float(), 4))
Пример #53
0
from __future__ import print_function, division, absolute_import
from contextlib import contextmanager
import functools
from llvm.core import Constant, Type
import llvm.core as lc
from . import errcode

true_bit = Constant.int(Type.int(1), 1)
false_bit = Constant.int(Type.int(1), 0)
true_byte = Constant.int(Type.int(8), 1)
false_byte = Constant.int(Type.int(8), 0)


def _block_terminator(bb):
    # XXX: replace this with bb.terminator when llvmpy 0.12.6 (or 0.13) is
    # released.
    inst = bb._ptr.getTerminator()
    return lc._make_value(inst) if inst is not None else None


def as_bool_byte(builder, value):
    return builder.zext(value, Type.int(8))


class Structure(object):
    def __init__(self, context, builder, value=None, ref=None):
        self._type = context.get_struct_type(self)
        self._builder = builder
        if ref is None:
            self._value = alloca_once(builder, self._type)
            if value is not None:
Пример #54
0
def get_record_member(builder, record, offset, typ):
    pdata = get_record_data(builder, record)
    pval = inbound_gep(builder, pdata, 0, offset)
    assert not is_pointer(pval.type.pointee)
    return builder.bitcast(pval, Type.pointer(typ))
Пример #55
0
 def dict_setitem_string(self, dictobj, name, valobj):
     fnty = Type.function(Type.int(),
                          (self.pyobj, self.cstring, self.pyobj))
     fn = self._get_function(fnty, name="PyDict_SetItemString")
     cstr = self.context.insert_const_string(self.module, name)
     return self.builder.call(fn, (dictobj, cstr, valobj))
Пример #56
0
 def argument(self, backend):
     '''Representation when used as an argument.
         '''
     return Type.pointer(Type.float())
Пример #57
0
 def float_from_double(self, fval):
     fnty = Type.function(self.pyobj, [self.double])
     fn = self._get_function(fnty, name="PyFloat_FromDouble")
     return self.builder.call(fn, [fval])
Пример #58
0
 def number_as_ssize_t(self, numobj):
     fnty = Type.function(self.py_ssize_t, [self.pyobj])
     fn = self._get_function(fnty, name="PyNumber_AsSsize_t")
     return self.builder.call(fn, [numobj])
Пример #59
0
 def err_clear(self):
     fnty = Type.function(Type.void(), ())
     fn = self._get_function(fnty, name="PyErr_Clear")
     return self.builder.call(fn, ())
Пример #60
0
def vector(ty, ct):
    return Type.vector(ty, 4)