Example #1
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)
Example #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)
Example #3
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)
Example #4
0
def scanf(mod, bu, s):
  v = mod.get_global_variable_named(s)
  sf = mod.get_function_named("scanf")
  t1 = bu.alloca(Type.int())
  t2 = bu.gep(v, [Constant.int(Type.int(), 0), Constant.int(Type.int(), 0)])
  bu.call(sf, [t2, t1])
  return bu.load(t1)
Example #5
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])
Example #6
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(' '))
Example #7
0
    def body(self, idx):

        get_id = self.get_function_named('P86.getmutationid')
        get_cnt = self.get_function_named('P86.getmutationcount')
        set_mut = self.get_function_named('P86.setmutation')

        index = self.var(Type.int(32), 0)
        one = self.constant(Type.int(32), 1)
        zero = self.constant(Type.int(32), 0)
        cnt = get_cnt()

        with self.loop() as loop:
            with loop.condition() as setcond:
                setcond(index <= cnt)

            with loop.body():
                set_mut(index)
                with self.ifelse(get_id() == idx) as ifelse:
                    with ifelse.then():
                        set_mut(index)
                        self.ret()
                index += one

        set_mut(zero)
        self.ret()
Example #8
0
File: llvm.py Project: ymyzk/tinyc
 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 = {}
Example #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)
Example #10
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))
Example #11
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)
Example #12
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))
Example #13
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")
Example #14
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")
Example #15
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")
Example #16
0
def f_scanf(mod):
    '''libc: input format conversion'''
    ret = Type.int(32)
    arg = Type.pointer(Type.int(8))

    type_ = Type.function(ret, [arg], True)
    return mod.get_or_insert_function(type_, "scanf")
Example #17
0
def f_printf(mod):
    '''libc: formatted output conversion'''
    ret = Type.int(32)
    arg = Type.pointer(Type.int(8))

    type_ = Type.function(ret, [arg], True)
    return mod.get_or_insert_function(type_, "printf")
Example #18
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
Example #19
0
 def test_constexpr_opcode(self):
     mod = Module.new("test_constexpr_opcode")
     func = mod.add_function(Type.function(Type.void(), []), name="foo")
     builder = Builder.new(func.append_basic_block("entry"))
     a = builder.inttoptr(Constant.int(Type.int(), 123), Type.pointer(Type.int()))
     self.assertTrue(isinstance(a, lc.ConstantExpr))
     self.assertEqual(a.opcode, lc.OPCODE_INTTOPTR)
     self.assertEqual(a.opcode_name, "inttoptr")
Example #20
0
 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])
Example #21
0
    def body(self):
        mod = self.function.module

        cnt_var = mod.add_global_variable(Type.int(32), "P86.mutant_count")
        cnt_var.initializer = Constant.int(Type.int(32), 0)
        cnt_var.linkage = core.LINKAGE_EXTERNAL

        self.ret(CTemp(self, self.builder.load(cnt_var)))
Example #22
0
def int_upower_impl(context, builder, sig, args):
    module = cgutils.get_module(builder)
    x, y = args
    if y.type.width > 32:
        y = builder.trunc(y, Type.int(32))
    elif y.type.width < 32:
        y = builder.zext(y, Type.int(32))
    powerfn = lc.Function.intrinsic(module, lc.INTR_POWI, [x.type])
    return builder.call(powerfn, (x, y))
Example #23
0
 def test_scalar_type(self):
     i32a = Type.int(32)
     i32b = Type.int(32)
     i64a = Type.int(64)
     i64b = Type.int(64)
     ts = set([i32a, i32b, i64a, i64b])
     self.assertTrue(len(ts))
     self.assertTrue(i32a in ts)
     self.assertTrue(i64b in ts)
Example #24
0
 def test_struct_type(self):
     ta = Type.struct([Type.int(32), Type.float()])
     tb = Type.struct([Type.int(32), Type.float()])
     tc = Type.struct([Type.int(32), Type.int(32), Type.float()])
     ts = set([ta, tb, tc])
     self.assertTrue(len(ts) == 2)
     self.assertTrue(ta in ts)
     self.assertTrue(tb in ts)
     self.assertTrue(tc in ts)
Example #25
0
    def get_data_type(self, ty):
        """
        Get a data representation of the type

        Returns None if it is an opaque pointer
        """
        if (isinstance(ty, types.Dummy) or
                isinstance(ty, types.Module) or
                isinstance(ty, types.Function) or
                isinstance(ty, types.Dispatcher) or
                isinstance(ty, types.Object) or
                isinstance(ty, types.Macro)):
            return Type.pointer(Type.int(8))

        elif isinstance(ty, types.CPointer):
            dty = self.get_data_type(ty.dtype)
            return Type.pointer(dty)

        elif isinstance(ty, types.Optional):
            return self.get_data_type(ty.type)

        elif isinstance(ty, types.Array):
            return self.get_struct_type(self.make_array(ty))

        elif isinstance(ty, types.UniTuple):
            dty = self.get_value_type(ty.dtype)
            return Type.array(dty, ty.count)

        elif isinstance(ty, types.Tuple):
            dtys = [self.get_value_type(t) for t in ty]
            return Type.struct(dtys)

        elif isinstance(ty, types.UniTupleIter):
            stty = self.get_struct_type(self.make_unituple_iter(ty))
            return stty

        elif isinstance(ty, types.Record):
            # Record are represented as byte array
            return Type.struct([Type.array(Type.int(8), ty.size)])

        elif isinstance(ty, types.UnicodeCharSeq):
            charty = Type.int(numpy_support.sizeof_unicode_char * 8)
            return Type.struct([Type.array(charty, ty.count)])

        elif isinstance(ty, types.CharSeq):
            charty = Type.int(8)
            return Type.struct([Type.array(charty, ty.count)])

        elif ty in STRUCT_TYPES:
            return self.get_struct_type(STRUCT_TYPES[ty])

        elif isinstance(ty, types.Pair):
            pairty = self.make_pair(ty.first_type, ty.second_type)
            return self.get_struct_type(pairty)

        else:
            return LTYPEMAP[ty]
Example #26
0
 def make_test_module(self):
     module = Module.new("testmodule")
     fnty = Type.function(Type.int(), [])
     function = module.add_function(fnty, "foo")
     bb_entry = function.append_basic_block("entry")
     builder = Builder.new(bb_entry)
     builder.ret(Constant.int(Type.int(), 0xCAFE))
     module.verify()
     return module
Example #27
0
    def code_gen(self):

        d = Type.double()
        i32 = Type.int(32)
        i1 = Type.int(1)

        op = self.operator.word
        left = self.left.code_gen()
        right = self.right.code_gen()

        if op == '||' or op == '&&':
            if left.type != right.type:
                if left.type == d or right.type == d:
                    left = Helper.auto_cast(g_llvm_builder, left, d)
                    right = Helper.auto_cast(g_llvm_builder, right, d)
                else:
                    left = Helper.auto_cast(g_llvm_builder, left, i32)
                    right = Helper.auto_cast(g_llvm_builder, right, i32)
            if left.type == d:
                if g_llvm_builder is None:
                    return left.fcmp(RPRED_UEQ, right)
                else:
                    return g_llvm_builder.fcmp(RPRED_UEQ, left, right)
            else:
                if g_llvm_builder is None:
                    return left.icmp(IPRED_EQ, right)
                else:
                    return g_llvm_builder.icmp(IPRED_EQ, left, right)

        method = Helper.choose_method(left, op, right)

        if method[0] == 'f':
            left = Helper.auto_cast(g_llvm_builder, left, d)
            right = Helper.auto_cast(g_llvm_builder, right, d)
        elif method == 'and_' or method == 'or_':
            if left.type == d or right.type == d:
                raise cmexception.InvalidOperandException(self.operator, str(left.type), str(right.type))
            else:
                if left.type != right.type:
                    left = Helper.auto_cast(g_llvm_builder, left, i32)
                    right = Helper.auto_cast(g_llvm_builder, right, i32)
        else:
            if left.type != right.type:
                left = Helper.auto_cast(g_llvm_builder, left, i32)
                right = Helper.auto_cast(g_llvm_builder, right, i32)
        if op == '<' or op == '>' or op == '<=' or op == '>=' or op == '==' or op == '!=':
            flag = Helper.choose_flag(op, left)
            if g_llvm_builder is None:
                return getattr(left, method)(flag, right)
            else:
                return getattr(g_llvm_builder, method)(flag, left, right)
        else:
            if g_llvm_builder is None:
                return getattr(left, method)(right)
            else:
                return getattr(g_llvm_builder, method)(left, right)
Example #28
0
    def create_iter_indices(self):
        intpty = self.context.get_value_type(types.intp)
        ZERO = Constant.int(Type.int(intpty.width), 0)

        indices = []
        for i in range(self.ndim):
            x = self.builder.alloca(Type.int(intpty.width))
            self.builder.store(ZERO, x)
            indices.append(x)
        return _ArrayIndexingHelper(self, indices)
Example #29
0
    def template(self, iop, fop):
        inttys = [Type.int(32), Type.int(64)]
        flttys = [Type.float(), Type.double()]

        if iop:
            for ty in inttys:
                self.func_template(ty, iop)
        if fop:
            for ty in flttys:
                self.func_template(ty, fop)
Example #30
0
 def get_array_type(typo, length):
     if typo == 'int':
         return Type.array(Type.int(32), length)
     elif typo == 'double':
         return Type.array(Type.double(), length)
     elif typo == 'String':
         ch = Type.int(8)
         return Type.array(Type.pointer(ch), length)
     elif typo == 'char':
         return Type.array(Type.int(8), length)
Example #31
0
    def test_alloca_alignment(self):
        m = Module.new('')
        f = m.add_function(Type.function(Type.void(), []), "foo")
        b = Builder.new(f.append_basic_block(''))
        inst = b.alloca(Type.int(32))
        inst.alignment = 4
        b.ret_void()
        m.verify()

        self.assertTrue(inst.is_static)
        self.assertFalse(inst.is_array)
        self.assertEqual(inst.alignment, 4)
        self.assertEqual(str(inst.array_size), 'i32 1')
Example #32
0
    def func_template(self, ty, op):
        m = Module.new('dofjaa')
        fnty = Type.function(ty, [ty, ty])
        fn = m.add_function(fnty, 'foo')
        bldr = Builder.new(fn.append_basic_block(''))
        bldr.ret(getattr(bldr, op)(*fn.args))

        engine = EngineBuilder.new(m).mcjit(True).create()
        ptr = engine.get_pointer_to_function(fn)

        from ctypes import c_uint32, c_uint64, c_float, c_double, CFUNCTYPE

        maptypes = {
            Type.int(32): c_uint32,
            Type.int(64): c_uint64,
            Type.float(): c_float,
            Type.double(): c_double,
        }
        cty = maptypes[ty]
        prototype = CFUNCTYPE(*[cty] * 3)
        callee = prototype(ptr)
        callee(12, 23)
Example #33
0
 def insert_const_string(self, mod, string):
     stringtype = Type.pointer(Type.int(8))
     text = Constant.stringz(string)
     name = ".const.%s" % string
     for gv in mod.global_variables:
         if gv.name == name and gv.type.pointee == text.type:
             break
     else:
         gv = mod.add_global_variable(text.type, name=name)
         gv.global_constant = True
         gv.initializer = text
         gv.linkage = lc.LINKAGE_INTERNAL
     return Constant.bitcast(gv, stringtype)
Example #34
0
    def test_inline_call(self):
        mod = Module.new(__name__)
        callee = mod.add_function(Type.function(Type.int(), [Type.int()]),
                                  name='bar')

        builder = Builder.new(callee.append_basic_block('entry'))
        builder.ret(builder.add(callee.args[0], callee.args[0]))

        caller = mod.add_function(Type.function(Type.int(), []), name='foo')

        builder = Builder.new(caller.append_basic_block('entry'))
        callinst = builder.call(callee, [Constant.int(Type.int(), 1234)])
        builder.ret(callinst)

        pre_inlining = str(caller)
        self.assertIn('call', pre_inlining)

        self.assertTrue(inline_function(callinst))

        post_inlining = str(caller)
        self.assertNotIn('call', post_inlining)
        self.assertIn('2468', post_inlining)
Example #35
0
 def test_metadata(self):
     m = Module.new('a')
     t = Type.int()
     metadata = MetaData.get(
         m, [Constant.int(t, 100),
             MetaDataString.get(m, 'abcdef'), None])
     MetaData.add_named_operand(m, 'foo', metadata)
     self.assertEqual(MetaData.get_named_operands(m, 'foo'), [metadata])
     self.assertEqual(MetaData.get_named_operands(m, 'bar'), [])
     self.assertEqual(len(metadata.operands), 3)
     self.assertEqual(metadata.operands[0].z_ext_value, 100)
     self.assertEqual(metadata.operands[1].string, 'abcdef')
     self.assertTrue(metadata.operands[2] is None)
Example #36
0
def pointer_add(builder, ptr, offset, return_type=None):
    """
    Add an integral *offset* to pointer *ptr*, and return a pointer
    of *return_type* (or, if omitted, the same type as *ptr*).

    Note the computation is done in bytes, and ignores the width of
    the pointed item type.
    """
    intptr_t = Type.int(utils.MACHINE_BITS)
    intptr = builder.ptrtoint(ptr, intptr_t)
    if isinstance(offset, int):
        offset = Constant.int(intptr_t, offset)
    intptr = builder.add(intptr, offset)
    return builder.inttoptr(intptr, return_type or ptr.type)
Example #37
0
def llvm_type(type, memo=None):
    if memo is None:
        memo = {}
    if hashable(type) and type in memo:
        return memo[type]

    ty = type.__class__
    if ty == Boolean:
        result = Type.int(1)
    elif ty == Integral:
        result = Type.int(type.bits)
    elif type == Float32:
        result = Type.float()
    elif type == Float64:
        result = Type.double()
    elif ty == Array:
        result = Type.array(llvm_type(type.base, memo), type.count)
    elif ty == Vector:
        result = Type.vector(llvm_type(type.base, memo), type.count)
    elif ty == Struct:
        result = handle_struct(type, memo)
    elif ty == Pointer:
        if type.base.is_void:
            return Type.pointer(Type.int(8))
        result = Type.pointer(llvm_type(type.base, memo))
    elif ty == Function:
        result = Type.function(
            llvm_type(type.restype, memo),
            [llvm_type(argtype, memo) for argtype in type.argtypes],
            var_arg=type.varargs)
    elif ty == VoidT:
        result = Type.void()
    else:
        raise TypeError("Cannot convert type %s" % (type,))

    memo[type] = result
    return result
Example #38
0
 def auto_cast(builder, value, target_type):
     if value.type != target_type:
         d = Type.double()
         i32 = Type.int(32)
         i8 = Type.int(8)
         i1 = Type.int(1)
         if target_type == d:
             if value.type != d:
                 if builder:
                     value = builder.sitofp(value, d)
                 else:
                     value = value.sitofp(d)
         elif target_type == i32:
             if value.type == d:
                 return None
             elif value.type == i1:
                 if builder:
                     value = builder.zext(value, i32)
                 else:
                     value = value.zext(i32)
             else:
                 if builder:
                     value = builder.sext(value, i32)
                 else:
                     value = value.sext(i32)
         elif target_type == i8:
             if value.type == i1:
                 if builder:
                     value = builder.zext(value, i8)
                 else:
                     value = value.zext(i8)
             else:
                 return None
         elif target_type == Type.pointer(Type.int(8)):
             return None
     return value
Example #39
0
    def test_arg_attr(self):
        m = Module.new('oifjda')
        fnty = Type.function(Type.void(), [Type.int()])
        func = m.add_function(fnty, 'foo')
        bb = func.append_basic_block('')
        bbdef = func.append_basic_block('')
        bbsw1 = func.append_basic_block('')
        bbsw2 = func.append_basic_block('')
        bldr = Builder.new(bb)

        swt = bldr.switch(func.args[0], bbdef, n=2)
        swt.add_case(Constant.int(Type.int(), 0), bbsw1)
        swt.add_case(Constant.int(Type.int(), 1), bbsw2)

        bldr.position_at_end(bbsw1)
        bldr.ret_void()

        bldr.position_at_end(bbsw2)
        bldr.ret_void()

        bldr.position_at_end(bbdef)
        bldr.ret_void()

        func.verify()
Example #40
0
    def test_issue10(self):
        m = Module.new('a')
        ti = Type.int()
        tf = Type.function(ti, [ti, ti])

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

        bb = f.append_basic_block('entry')

        b = Builder.new(bb)

        # There are no instructions in bb. Positioning of the
        # builder at beginning (or end) should succeed (trivially).
        b.position_at_end(bb)
        b.position_at_beginning(bb)
Example #41
0
 def to_native_array(self, typ, ary):
     # TODO check matching dtype.
     #      currently, mismatching dtype will still work and causes
     #      potential memory corruption
     voidptr = Type.pointer(Type.int(8))
     nativearycls = self.context.make_array(typ)
     nativeary = nativearycls(self.context, self.builder)
     aryptr = nativeary._getpointer()
     ptr = self.builder.bitcast(aryptr, voidptr)
     errcode = self.numba_array_adaptor(ary, ptr)
     failed = cgutils.is_not_null(self.builder, errcode)
     with cgutils.if_unlikely(self.builder, failed):
         # TODO
         self.builder.unreachable()
     return self.builder.load(aryptr)
Example #42
0
    def make_keywords(self, kws):
        strings = []
        stringtype = Type.pointer(Type.int(8))
        for k in kws:
            strings.append(self.make_const_string(k))

        strings.append(Constant.null(stringtype))

        kwlist = Constant.array(stringtype, strings)

        gv = self.module.add_global_variable(kwlist.type, name=".kwlist")
        gv.global_constant = True
        gv.initializer = kwlist
        gv.linkage = lc.LINKAGE_INTERNAL

        return Constant.bitcast(gv, Type.pointer(stringtype))
Example #43
0
    def lower_inst(self, inst):
        if isinstance(inst, ir.Assign):
            value = self.lower_assign(inst)
            self.storevar(value, inst.target.name)

        elif isinstance(inst, ir.SetItem):
            target = self.loadvar(inst.target.name)
            index = self.loadvar(inst.index.name)
            value = self.loadvar(inst.value.name)
            ok = self.pyapi.object_setitem(target, index, value)
            negone = lc.Constant.int_signextend(ok.type, -1)
            pred = self.builder.icmp(lc.ICMP_EQ, ok, negone)
            with cgutils.if_unlikely(self.builder, pred):
                self.return_exception_raised()

        elif isinstance(inst, ir.Return):
            retval = self.loadvar(inst.value.name)
            self.incref(retval)
            self.cleanup()
            self.context.return_value(self.builder, retval)

        elif isinstance(inst, ir.Branch):
            cond = self.loadvar(inst.cond.name)
            if cond.type == Type.int(1):
                istrue = cond
            else:
                istrue = self.pyapi.object_istrue(cond)
            zero = lc.Constant.null(istrue.type)
            pred = self.builder.icmp(lc.ICMP_NE, istrue, zero)
            tr = self.blkmap[inst.truebr]
            fl = self.blkmap[inst.falsebr]
            self.builder.cbranch(pred, tr, fl)

        elif isinstance(inst, ir.Jump):
            target = self.blkmap[inst.target]
            self.builder.branch(target)

        elif isinstance(inst, ir.Del):
            obj = self.loadvar(inst.value)
            self.decref(obj)

        elif isinstance(inst, ir.Raise):
            self.pyapi.raise_exception(inst.exception, inst.exception)
            self.return_exception_raised()

        else:
            raise NotImplementedError(type(inst), inst)
Example #44
0
    def test_nvvm_from_llvm(self):
        m = Module.new("test_nvvm_from_llvm")
        fty = Type.function(Type.void(), [Type.int()])
        kernel = m.add_function(fty, name='mycudakernel')
        bldr = Builder.new(kernel.append_basic_block('entry'))
        bldr.ret_void()
        print(m)
        set_cuda_kernel(kernel)

        fix_data_layout(m)
        ptx = llvm_to_ptx(str(m)).decode('utf8')
        print(ptx)
        self.assertTrue('mycudakernel' in ptx)
        if is64bit:
            self.assertTrue('.address_size 64' in ptx)
        else:
            self.assertTrue('.address_size 32' in ptx)
Example #45
0
    def unpack_value(self, builder, ty, ptr):
        """Unpack data from array storage
        """

        if isinstance(ty, types.Record):
            vt = self.get_value_type(ty)
            tmp = cgutils.alloca_once(builder, vt)
            dataptr = cgutils.inbound_gep(builder, ptr, 0, 0)
            builder.store(dataptr, cgutils.inbound_gep(builder, tmp, 0, 0))
            return builder.load(tmp)

        assert cgutils.is_pointer(ptr.type)
        value = builder.load(ptr)
        if ty == types.boolean:
            return builder.trunc(value, Type.int(1))
        else:
            return value
Example #46
0
 def get_function_type(self, fndesc):
     """
     Calling Convention
     ------------------
     Returns: -2 for return none in native function;
              -1 for failure with python exception set;
               0 for success;
              >0 for user error code.
     Return value is passed by reference as the first argument.
     It MUST NOT be used if the function is in nopython mode.
     Actual arguments starts at the 2nd argument position.
     Caller is responsible to allocate space for return value.
     """
     argtypes = [self.get_argument_type(aty) for aty in fndesc.argtypes]
     resptr = self.get_return_type(fndesc.restype)
     fnty = Type.function(Type.int(), [resptr] + argtypes)
     return fnty
Example #47
0
    def __init__(self, builder, api, nargs):
        self.builder = builder
        self.api = api
        self.arg_count = 0  # how many function arguments have been processed
        self.cleanups = []

        # set up switch for error processing of function arguments
        self.elseblk = cgutils.append_basic_block(self.builder, "arg.ok")
        with cgutils.goto_block(self.builder, self.elseblk):
            self.builder.ret(self.api.get_null_object())

        self.swtblk = cgutils.append_basic_block(self.builder, ".arg.err")
        with cgutils.goto_block(self.builder, self.swtblk):
            self.swt_val = cgutils.alloca_once(self.builder, Type.int(32))
            self.swt = self.builder.switch(self.builder.load(self.swt_val),
                                           self.elseblk, nargs)

        self.prev = self.elseblk
Example #48
0
    def test_bitcode(self):
        # create a module
        m = Module.new('module1')
        m.add_global_variable(Type.int(), 'i')

        # write it's assembly representation to a file
        asm = str(m)

        testasm_bc = os.path.join(self.tmpdir, 'testasm.bc')
        with open(testasm_bc, "wb") as fout:
            m.to_bitcode(fout)

        # read it back into a module
        with open(testasm_bc, "rb") as fin:
            m2 = Module.from_bitcode(fin)
            # The default `m.id` is '<string>'.
            m2.id = m.id  # Copy the name from `m`

        self.assertEqual(str(m2).strip(), asm.strip())
Example #49
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
Example #50
0
    def get_data_type(self, ty):
        """
        Get a data representation of the type

        Returns None if it is an opaque pointer
        """
        if (isinstance(ty, types.Dummy) or isinstance(ty, types.Module)
                or isinstance(ty, types.Function)
                or isinstance(ty, types.Dispatcher)
                or isinstance(ty, types.Object)
                or isinstance(ty, types.Macro)):
            return Type.pointer(Type.int(8))

        elif isinstance(ty, types.CPointer):
            dty = self.get_data_type(ty.dtype)
            return Type.pointer(dty)

        elif isinstance(ty, types.Optional):
            return self.get_data_type(ty.type)

        elif isinstance(ty, types.Array):
            return self.get_struct_type(self.make_array(ty))

        elif isinstance(ty, types.UniTuple):
            dty = self.get_value_type(ty.dtype)
            return Type.array(dty, ty.count)

        elif isinstance(ty, types.Tuple):
            dtys = [self.get_value_type(t) for t in ty]
            return Type.struct(dtys)

        elif isinstance(ty, types.UniTupleIter):
            stty = self.get_struct_type(self.make_unituple_iter(ty))
            return stty

        elif ty in STRUCT_TYPES:
            return self.get_struct_type(STRUCT_TYPES[ty])

        else:
            return LTYPEMAP[ty]
Example #51
0
    def _build_test_module(self):
        mod = Module.new('test')

        float = Type.double()
        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)
        return mod, mysin
Example #52
0
    def get_function_type(self, fndesc):
        """
        Get the implemented Function type for the high-level *fndesc*.
        Some parameters can be added or shuffled around.
        This is kept in sync with call_function() and get_arguments().

        Calling Convention
        ------------------
        Returns: -2 for return none in native function;
                 -1 for failure with python exception set;
                  0 for success;
                 >0 for user error code.
        Return value is passed by reference as the first argument.

        Actual arguments starts at the 2rd argument position.
        Caller is responsible to allocate space for return value.
        """
        argtypes = [self.get_argument_type(aty)
                    for aty in fndesc.argtypes]
        resptr = self.get_return_type(fndesc.restype)
        fnty = Type.function(Type.int(), [resptr] + argtypes)
        return fnty
Example #53
0
    def get_constant(self, ty, val):
        assert not self.is_struct_type(ty)

        lty = self.get_value_type(ty)

        if ty == types.none:
            assert val is None
            return self.get_dummy_value()

        elif ty == types.boolean:
            return Constant.int(Type.int(1), int(val))

        elif ty in types.signed_domain:
            return Constant.int_signextend(lty, val)

        elif ty in types.real_domain:
            return Constant.real(lty, val)

        elif isinstance(ty, types.UniTuple):
            consts = [self.get_constant(ty.dtype, v) for v in val]
            return Constant.array(consts[0].type, consts)

        raise NotImplementedError(ty)
Example #54
0
 def code_gen(self):
     if self.constant_token.lexme_type == LexmeType.Integer:
         return Constant.int(
             Helper.get_type(self.constant_token.lexme_type),
             self.constant_token.word)
     elif self.constant_token.lexme_type == LexmeType.Double:
         return Constant.real(
             Helper.get_type(self.constant_token.lexme_type),
             self.constant_token.word)
     elif self.constant_token.lexme_type == LexmeType.String:
         s = self.constant_token.word.strip('"')
         global constant_string_num
         global_string = GlobalVariable.new(
             g_llvm_module, Type.array(Type.int(8),
                                       len(s) + 1),
             ".str%d" % constant_string_num)
         constant_string_num += 1
         global_string.initializer = Constant.stringz(s)
         return global_string
     elif self.constant_token.lexme_type == LexmeType.Char:
         ascii = ord(self.constant_token.word.strip("'"))
         return Constant.int(
             Helper.get_type(self.constant_token.lexme_type), ascii)
Example #55
0
    def test_volatile_another(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())

        # test load inst
        val = bldr.load(ptr, volatile=True)
        self.assertTrue(val.is_volatile, "volatile kwarg does not work")
        val.set_volatile(False)
        self.assertFalse(val.is_volatile, "fail to unset volatile")
        val.set_volatile(True)
        self.assertTrue(val.is_volatile, "fail to set volatile")

        # test store inst
        store_inst = bldr.store(val, ptr, volatile=True)
        self.assertTrue(store_inst.is_volatile, "volatile kwarg does not work")
        store_inst.set_volatile(False)
        self.assertFalse(store_inst.is_volatile, "fail to unset volatile")
        store_inst.set_volatile(True)
        self.assertTrue(store_inst.is_volatile, "fail to set volatile")
Example #56
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())

        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(' '))
Example #57
0
 def get_dummy_type(self):
     return Type.pointer(Type.int(8))
Example #58
0
 def print_string(self, builder, text):
     mod = builder.basic_block.function.module
     cstring = Type.pointer(Type.int(8))
     fnty = Type.function(Type.int(), [cstring])
     puts = mod.get_or_insert_function(fnty, "puts")
     return builder.call(puts, [text])
Example #59
0
    def cast(self, builder, val, fromty, toty):
        if fromty == toty or toty == types.Any or isinstance(toty, types.Kind):
            return val

        elif ((fromty in types.unsigned_domain and
                       toty in types.signed_domain) or
                  (fromty in types.integer_domain and
                           toty in types.unsigned_domain)):
            lfrom = self.get_value_type(fromty)
            lto = self.get_value_type(toty)
            if lfrom.width <= lto.width:
                return builder.zext(val, lto)
            elif lfrom.width > lto.width:
                return builder.trunc(val, lto)

        elif fromty in types.signed_domain and toty in types.signed_domain:
            lfrom = self.get_value_type(fromty)
            lto = self.get_value_type(toty)
            if lfrom.width <= lto.width:
                return builder.sext(val, lto)
            elif lfrom.width > lto.width:
                return builder.trunc(val, lto)

        elif fromty in types.real_domain and toty in types.real_domain:
            lty = self.get_value_type(toty)
            if fromty == types.float32 and toty == types.float64:
                return builder.fpext(val, lty)
            elif fromty == types.float64 and toty == types.float32:
                return builder.fptrunc(val, lty)

        elif fromty in types.real_domain and toty in types.complex_domain:
            if fromty == types.float32:
                if toty == types.complex128:
                    real = self.cast(builder, val, fromty, types.float64)
                else:
                    real = val

            elif fromty == types.float64:
                if toty == types.complex64:
                    real = self.cast(builder, val, fromty, types.float32)
                else:
                    real = val

            if toty == types.complex128:
                imag = self.get_constant(types.float64, 0)
            elif toty == types.complex64:
                imag = self.get_constant(types.float32, 0)
            else:
                raise Exception("unreachable")

            cmplx = self.make_complex(toty)(self, builder)
            cmplx.real = real
            cmplx.imag = imag
            return cmplx._getvalue()

        elif fromty in types.integer_domain and toty in types.real_domain:
            lty = self.get_value_type(toty)
            if fromty in types.signed_domain:
                return builder.sitofp(val, lty)
            else:
                return builder.uitofp(val, lty)

        elif toty in types.integer_domain and fromty in types.real_domain:
            lty = self.get_value_type(toty)
            if toty in types.signed_domain:
                return builder.fptosi(val, lty)
            else:
                return builder.fptoui(val, lty)

        elif fromty in types.integer_domain and toty in types.complex_domain:
            cmplxcls, flty = builtins.get_complex_info(toty)
            cmpl = cmplxcls(self, builder)
            cmpl.real = self.cast(builder, val, fromty, flty)
            cmpl.imag = self.get_constant(flty, 0)
            return cmpl._getvalue()

        elif fromty in types.complex_domain and toty in types.complex_domain:
            srccls, srcty = builtins.get_complex_info(fromty)
            dstcls, dstty = builtins.get_complex_info(toty)

            src = srccls(self, builder, value=val)
            dst = dstcls(self, builder)
            dst.real = self.cast(builder, src.real, srcty, dstty)
            dst.imag = self.cast(builder, src.imag, srcty, dstty)
            return dst._getvalue()

        elif (isinstance(toty, types.UniTuple) and
                  isinstance(fromty, types.UniTuple) and
                      len(fromty) == len(toty)):
            olditems = cgutils.unpack_tuple(builder, val, len(fromty))
            items = [self.cast(builder, i, fromty.dtype, toty.dtype)
                     for i in olditems]
            tup = self.get_constant_undef(toty)
            for idx, val in enumerate(items):
                tup = builder.insert_value(tup, val, idx)
            return tup

        elif toty == types.boolean:
            return self.is_true(builder, fromty, val)

        elif fromty == types.boolean:
            # first promote to int32
            asint = builder.zext(val, Type.int())
            # then promote to number
            return self.cast(builder, asint, types.int32, toty)

        raise NotImplementedError("cast", val, fromty, toty)
Example #60
0
 def return_user_exc(self, builder, code):
     assert code > 0
     builder.ret(Constant.int(Type.int(), code))