Exemplo n.º 1
0
    def make_exception_switch(self, api, builder, code):
        """Handle user defined exceptions.
        Build a switch to check which exception class was raised.
        """
        nexc = len(self.exceptions)
        elseblk = cgutils.append_basic_block(builder, ".invalid.user.exception")
        swt = builder.switch(code, elseblk, n=nexc)
        for num, exc in self.exceptions.items():
            bb = cgutils.append_basic_block(builder,
                                            ".user.exception.%d" % num)
            swt.add_case(Constant.int(code.type, num), bb)
            builder.position_at_end(bb)
            api.raise_exception(exc, exc)
            builder.ret(api.get_null_object())

        builder.position_at_end(elseblk)

        # Handle native error
        elseblk = cgutils.append_basic_block(builder, ".invalid.native.error")
        swt = builder.switch(code, elseblk, n=len(errcode.error_names))

        msgfmt = "{error} in native function: {fname}"
        for errnum, errname in errcode.error_names.items():
            bb = cgutils.append_basic_block(builder,
                                            ".native.error.%d" % errnum)
            swt.add_case(Constant.int(code.type, errnum), bb)
            builder.position_at_end(bb)

            api.raise_native_error(msgfmt.format(error=errname,
                                                 fname=self.fndesc.mangled_name))
            builder.ret(api.get_null_object())

        builder.position_at_end(elseblk)
        msg = "unknown error in native function: %s" % self.fndesc.mangled_name
        api.raise_native_error(msg)
Exemplo n.º 2
0
    def op_LOAD_CONST(self, value, target):
        if isinstance(value, bool):
            self.stack[target] = Constant.int(bool_type, value)
        elif isinstance(value, int):
            self.stack[target] = Constant.int(int_type, value)
        elif isinstance(value, (float, long)):
            self.stack[target] = Constant.real(float_type, value)
        elif isinstance(value, str):
            # create null terminated string
            n = 0
            content = Constant.stringz(value)

            # create a unique global constant name, keep hashing
            # until we find one
            while True:
                try:
                    name = CONSTANT_NAMING % (abs(hash(value)) ^ n)
                    break
                except LLVMException:
                    n += 1
                    pass

            globalstr = self.module.add_global_variable(content.type, name)
            globalstr.initializer = content
            globalstr.linkage = lc.LINKAGE_LINKONCE_ODR
            self.stack[target] = globalstr.bitcast(
                pointer(content.type.element))
        else:
            raise NotImplementedError
Exemplo n.º 3
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
        ee = le.ExecutionEngine.new(mod)
        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)
Exemplo n.º 4
0
    def code_gen(self):

        function_prototype_and_context = self.prototype.code_gen(True)
        function_prototype = function_prototype_and_context[0]
        context = function_prototype_and_context[1]
        block = function_prototype.append_basic_block('entry')
        global g_llvm_builder
        g_llvm_builder = Builder.new(block)
        for i in range(len(self.prototype.args)):
            context.value_table[self.prototype.args[i][0]] = function_prototype.args[i]
        if self.body:
            for stmt in self.body:
                stmt.code_gen()
        key = self.prototype.func_name_token.word + '()'
        expected_return_type = self.context.type_table[key].return_type
        void_type = Type.void()
        if expected_return_type == void_type:
            g_llvm_builder.ret_void()
        else:
            if str(expected_return_type) == 'double':
                g_llvm_builder.ret(Constant.real(expected_return_type, 0))
            else:
                g_llvm_builder.ret(Constant.int(expected_return_type, 0))
        # Validate the generated code, checking for consistency.
        try:
            function_prototype.verify()
            g_llvm_pass_manager.run(function_prototype)
        except:
            print function_prototype.delete()
Exemplo n.º 5
0
def int_power_func_body(context, builder, x, y):
    pcounter = builder.alloca(y.type)
    presult = builder.alloca(x.type)
    result = Constant.int(x.type, 1)
    counter = y
    builder.store(counter, pcounter)
    builder.store(result, presult)

    bbcond = cgutils.append_basic_block(builder, ".cond")
    bbbody = cgutils.append_basic_block(builder, ".body")
    bbexit = cgutils.append_basic_block(builder, ".exit")

    del counter
    del result

    builder.branch(bbcond)

    with cgutils.goto_block(builder, bbcond):
        counter = builder.load(pcounter)
        ONE = Constant.int(counter.type, 1)
        ZERO = Constant.null(counter.type)
        builder.store(builder.sub(counter, ONE), pcounter)
        pred = builder.icmp(lc.ICMP_SGT, counter, ZERO)
        builder.cbranch(pred, bbbody, bbexit)

    with cgutils.goto_block(builder, bbbody):
        result = builder.load(presult)
        builder.store(builder.mul(result, x), presult)
        builder.branch(bbcond)

    builder.position_at_end(bbexit)
    return builder.load(presult)
Exemplo n.º 6
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)
                expr = self.expr_node.code_gen()
                if expr in g_llvm_module.global_variables:
                    expr.name = self.var_name_token.word
                    self.context.value_table[self.var_name_token.word] = expr
                else:
                    gv = GlobalVariable.new(g_llvm_module, t, self.var_name_token.word)
                    gv.initializer = expr
                    self.context.value_table[self.var_name_token.word] = gv
                self.context.type_table[self.var_name_token.word] = t

        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
                expr = self.expr_node.code_gen()
                if expr in g_llvm_module.global_variables:
                    expr = g_llvm_builder.gep(expr, [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0)])
                casted_expr = Helper.auto_cast(g_llvm_builder, expr, t)
                if casted_expr:
                    g_llvm_builder.store(casted_expr, var_address)
                else:
                    raise cmexception.CastException(self.var_name_token, t, expr.type)
            else:
                raise cmexception.RedefineException(self.var_name_token)
Exemplo n.º 7
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)
Exemplo n.º 8
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)
Exemplo n.º 9
0
def for_range(builder, count, intp):
    start = Constant.int(intp, 0)
    stop = count

    bbcond = append_basic_block(builder, "for.cond")
    bbbody = append_basic_block(builder, "for.body")
    bbend = append_basic_block(builder, "for.end")

    bbstart = builder.basic_block
    builder.branch(bbcond)

    ONE = Constant.int(intp, 1)

    with goto_block(builder, bbcond):
        index = builder.phi(intp, name="loop.index")
        pred = builder.icmp(lc.ICMP_SLT, index, stop)
        builder.cbranch(pred, bbbody, bbend)

    with goto_block(builder, bbbody):
        yield index
        bbbody = builder.basic_block
        incr = builder.add(index, ONE)
        terminate(builder, bbcond)

    index.add_incoming(start, bbstart)
    index.add_incoming(incr, bbbody)

    builder.position_at_end(bbend)
Exemplo n.º 10
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)
Exemplo n.º 11
0
 def code_gen(self):
     if self.var_name_token.word in self.context.type_table:
         var_type = self.context.type_table[self.var_name_token.word]
         value_addr = self.context.value_table[self.var_name_token.word]
         expr = self.expr_node.code_gen()
         if expr in g_llvm_module.global_variables:
             expr = g_llvm_builder.gep(expr, [
                 Constant.int(Type.int(32), 0),
                 Constant.int(Type.int(32), 0)
             ])
         casted_expr = Helper.auto_cast(g_llvm_builder, expr, var_type)
         if casted_expr:
             g_llvm_builder.store(casted_expr, value_addr)
         else:
             raise cmexception.CastException(self.var_name_token, var_type,
                                             expr.type)
     else:
         if self.var_name_token.word in self.context.parent_context.type_table:
             gv = g_llvm_module.get_global_variable_named(
                 self.var_name_token.word)
             expr = self.expr_node.code_gen()
             g_llvm_builder.store(expr, gv)
         else:
             raise cmexception.NotDefinedException(self.var_name_token,
                                                   'Variable')
Exemplo n.º 12
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)
Exemplo n.º 13
0
def divmod_by_constant(builder, val, divisor):
    """
    Compute the (quotient, remainder) of *val* divided by the constant
    positive *divisor*.  The semantics reflects those of Python integer
    floor division, rather than C's / LLVM's signed division and modulo.
    The difference lies with a negative *val*.
    """
    assert divisor > 0
    divisor = Constant.int(val.type, divisor)
    one = Constant.int(val.type, 1)

    quot = alloca_once(builder, val.type)

    with ifelse(builder, is_neg_int(builder, val)) as (if_neg, if_pos):
        with if_pos:
            # quot = val / divisor
            quot_val = builder.sdiv(val, divisor)
            builder.store(quot_val, quot)
        with if_neg:
            # quot = -1 + (val + 1) / divisor
            val_plus_one = builder.add(val, one)
            quot_val = builder.sdiv(val_plus_one, divisor)
            builder.store(builder.sub(quot_val, one), quot)

    # rem = val - quot * divisor
    # (should be slightly faster than a separate modulo operation)
    quot_val = builder.load(quot)
    rem_val = builder.sub(val, builder.mul(quot_val, divisor))
    return quot_val, rem_val
Exemplo n.º 14
0
    def make_constant_array(self, builder, typ, ary):
        assert typ.layout == 'C'                # assumed in typeinfer.py
        ary = numpy.ascontiguousarray(ary)
        flat = ary.flatten()

        # Handle data
        if self.is_struct_type(typ.dtype):
            # FIXME
            raise TypeError("Do not support structure dtype as constant "
                            "array, yet.")

        values = [self.get_constant(typ.dtype, flat[i])
                  for i in range(flat.size)]

        lldtype = values[0].type
        consts = Constant.array(lldtype, values)
        data = cgutils.global_constant(builder, ".const.array.data", consts)

        # Handle shape
        llintp = self.get_value_type(types.intp)
        shapevals = [self.get_constant(types.intp, s) for s in ary.shape]
        cshape = Constant.array(llintp, shapevals)


        # Handle strides
        stridevals = [self.get_constant(types.intp, s) for s in ary.strides]
        cstrides = Constant.array(llintp, stridevals)

        # Create array structure
        cary = self.make_array(typ)(self, builder)
        cary.data = builder.bitcast(data, cary.data.type)
        cary.shape = cshape
        cary.strides = cstrides
        return cary._getvalue()
Exemplo n.º 15
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.unsigned_domain:
            return Constant.int(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)
Exemplo n.º 16
0
    def op_LOAD_CONST(self, value, target):
        if isinstance(value, bool):
            self.stack[target] = Constant.int(bool_type, value)
        elif isinstance(value, int):
            self.stack[target] = Constant.int(int_type, value)
        elif isinstance(value, (float, long)):
            self.stack[target] = Constant.real(float_type, value)
        elif isinstance(value, str):
            # create null terminated string
            n = 0
            content = Constant.stringz(value)

            # create a unique global constant name, keep hashing
            # until we find one
            while True:
                try:
                    name = CONSTANT_NAMING % (abs(hash(value)) ^ n)
                    break
                except LLVMException:
                    n += 1
                    pass

            globalstr = self.module.add_global_variable(content.type, name)
            globalstr.initializer = content
            globalstr.linkage = lc.LINKAGE_LINKONCE_ODR
            self.stack[target] = globalstr.bitcast(pointer(content.type.element))
        else:
            raise NotImplementedError
Exemplo n.º 17
0
 def code_gen(self):
     index = self.index_expr_node.code_gen()
     expr = self.value_expr_node.code_gen()
     if self.array_name_token.word in self.context.type_table:
         t = self.context.type_table[self.array_name_token.word]
         if t.count <= index.z_ext_value:
             raise cmexception.ArrayIndexOutOfBoundException(
                 self.index_expr_node.constant_token, t.count)
         value_address = self.context.value_table[
             self.array_name_token.word]
         address = g_llvm_builder.gep(
             value_address, [Constant.int(Type.int(32), 0), index])
         g_llvm_builder.store(expr, address)
     else:
         if self.array_name_token.word in self.context.parent_context.type_table:
             t = self.context.parent_context.type_table[
                 self.array_name_token.word]
             if t.count <= index.z_ext_value:
                 raise cmexception.ArrayIndexOutOfBoundException(
                     self.index_expr_node.constant_token, t.count)
             global_array = g_llvm_module.get_global_variable_named(
                 self.array_name_token.word)
             address = g_llvm_builder.gep(
                 global_array, [Constant.int(Type.int(32), 0), index])
             g_llvm_builder.store(expr, address)
         else:
             raise cmexception.NotDefinedException(self.array_name_token,
                                                   'Array')
Exemplo n.º 18
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)
Exemplo n.º 19
0
    def make_constant_array(self, builder, typ, ary):
        assert typ.layout == 'C'                # assumed in typeinfer.py
        ary = numpy.ascontiguousarray(ary)
        flat = ary.flatten()

        # Handle data
        if self.is_struct_type(typ.dtype):
            # FIXME
            raise TypeError("Do not support structure dtype as constant "
                            "array, yet.")

        values = [self.get_constant(typ.dtype, flat[i])
                  for i in range(flat.size)]

        lldtype = values[0].type
        consts = Constant.array(lldtype, values)
        data = cgutils.global_constant(builder, ".const.array.data", consts)

        # Handle shape
        llintp = self.get_value_type(types.intp)
        shapevals = [self.get_constant(types.intp, s) for s in ary.shape]
        cshape = Constant.array(llintp, shapevals)


        # Handle strides
        stridevals = [self.get_constant(types.intp, s) for s in ary.strides]
        cstrides = Constant.array(llintp, stridevals)

        # Create array structure
        cary = self.make_array(typ)(self, builder)
        cary.data = builder.bitcast(data, cary.data.type)
        cary.shape = cshape
        cary.strides = cstrides
        return cary._getvalue()
Exemplo n.º 20
0
 def getptr(self, *indices):
     assert len(indices) == self.nd
     indices = [auto_const_intp(x) for x in indices]
     shape = self.shape
     strides = self.strides
     order = self._order
     data = self._data_ptr
     builder = self.builder
     intp = intp_type
     if self.nd == 0:
         ptr = builder.gep(data, [zero_p])
     elif order in 'CF':
         # optimize for C and F contiguous
         if order == 'F':
             shape = list(reversed(shape))
         loc = Constant.null(intp)
         for ival, sval in zip(indices, shape[1:]):
             tmp = builder.mul(ival, sval)
             loc = builder.add(loc, tmp)
         loc = builder.add(loc, indices[-1])
         ptr = builder.gep(data, [loc])
     else:
         # any order
         loc = Constant.null(intp)
         for i, s in zip(indices, strides):
             tmp = builder.mul(i, s)
             loc = builder.add(loc, tmp)
         base = builder.ptrtoint(data, intp)
         target = builder.add(base, loc)
         ptr = builder.inttoptr(target, data.type)
     return ptr
Exemplo n.º 21
0
 def getptr(self, *indices):
     assert len(indices) == self.nd
     indices = [auto_const_intp(x) for x in indices]
     shape = self.shape
     strides = self.strides
     order = self._order
     data = self._data_ptr
     builder = self.builder
     intp = intp_type
     if self.nd == 0:
         ptr = builder.gep(data, [zero_p])
     elif order in 'CF':
         # optimize for C and F contiguous
         if order == 'F':
             shape = list(reversed(shape))
         loc = Constant.null(intp)
         for ival, sval in zip(indices, shape[1:]):
             tmp = builder.mul(ival, sval)
             loc = builder.add(loc, tmp)
         loc = builder.add(loc, indices[-1])
         ptr = builder.gep(data, [loc])
     else:
         # any order
         loc = Constant.null(intp)
         for i, s in zip(indices, strides):
             tmp = builder.mul(i, s)
             loc = builder.add(loc, tmp)
         base = builder.ptrtoint(data, intp)
         target = builder.add(base, loc)
         ptr = builder.inttoptr(target, data.type)
     return ptr
Exemplo n.º 22
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)
Exemplo n.º 23
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)
Exemplo n.º 24
0
def int_power_func_body(context, builder, x, y):
    pcounter = cgutils.alloca_once(builder, y.type)
    presult = cgutils.alloca_once(builder, x.type)
    result = Constant.int(x.type, 1)
    counter = y
    builder.store(counter, pcounter)
    builder.store(result, presult)

    bbcond = cgutils.append_basic_block(builder, ".cond")
    bbbody = cgutils.append_basic_block(builder, ".body")
    bbexit = cgutils.append_basic_block(builder, ".exit")

    del counter
    del result

    builder.branch(bbcond)

    with cgutils.goto_block(builder, bbcond):
        counter = builder.load(pcounter)
        ONE = Constant.int(counter.type, 1)
        ZERO = Constant.null(counter.type)
        builder.store(builder.sub(counter, ONE), pcounter)
        pred = builder.icmp(lc.ICMP_SGT, counter, ZERO)
        builder.cbranch(pred, bbbody, bbexit)

    with cgutils.goto_block(builder, bbbody):
        result = builder.load(presult)
        builder.store(builder.mul(result, x), presult)
        builder.branch(bbcond)

    builder.position_at_end(bbexit)
    return builder.load(presult)
Exemplo n.º 25
0
 def emit(self):
     if self.text.lower() == "true":
         return Constant.int(tp_bool, 1)
     elif self.text.lower() == "false":
         return Constant.int(tp_bool, 0)
     else:
         raise RuntimeError("Invalid boolean value.")
Exemplo n.º 26
0
def divmod_by_constant(builder, val, divisor):
    """
    Compute the (quotient, remainder) of *val* divided by the constant
    positive *divisor*.  The semantics reflects those of Python integer
    floor division, rather than C's / LLVM's signed division and modulo.
    The difference lies with a negative *val*.
    """
    assert divisor > 0
    divisor = Constant.int(val.type, divisor)
    one = Constant.int(val.type, 1)

    quot = alloca_once(builder, val.type)

    with ifelse(builder, is_neg_int(builder, val)) as (if_neg, if_pos):
        with if_pos:
            # quot = val / divisor
            quot_val = builder.sdiv(val, divisor)
            builder.store(quot_val, quot)
        with if_neg:
            # quot = -1 + (val + 1) / divisor
            val_plus_one = builder.add(val, one)
            quot_val = builder.sdiv(val_plus_one, divisor)
            builder.store(builder.sub(quot_val, one), quot)

    # rem = val - quot * divisor
    # (should be slightly faster than a separate modulo operation)
    quot_val = builder.load(quot)
    rem_val = builder.sub(val, builder.mul(quot_val, divisor))
    return quot_val, rem_val
Exemplo n.º 27
0
    def code_gen(self):

        function_prototype_and_context = self.prototype.code_gen(True)
        function_prototype = function_prototype_and_context[0]
        context = function_prototype_and_context[1]
        block = function_prototype.append_basic_block('entry')
        global g_llvm_builder
        g_llvm_builder = Builder.new(block)
        for i in range(len(self.prototype.args)):
            context.value_table[self.prototype.args[i]
                                [0]] = function_prototype.args[i]
        if self.body:
            for stmt in self.body:
                stmt.code_gen()
        key = self.prototype.func_name_token.word + '()'
        expected_return_type = self.context.type_table[key].return_type
        void_type = Type.void()
        if expected_return_type == void_type:
            g_llvm_builder.ret_void()
        else:
            if str(expected_return_type) == 'double':
                g_llvm_builder.ret(Constant.real(expected_return_type, 0))
            else:
                g_llvm_builder.ret(Constant.int(expected_return_type, 0))
        # Validate the generated code, checking for consistency.
        try:
            function_prototype.verify()
            g_llvm_pass_manager.run(function_prototype)
        except:
            print function_prototype.delete()
Exemplo n.º 28
0
def getiter_range_generic(context, builder, iterobj, start, stop, step):
    diff = builder.sub(stop, start)
    intty = start.type
    zero = Constant.int(intty, 0)
    one = Constant.int(intty, 1)
    pos_diff = builder.icmp(lc.ICMP_SGT, diff, zero)
    pos_step = builder.icmp(lc.ICMP_SGT, step, zero)
    sign_differs = builder.xor(pos_diff, pos_step)
    zero_step = builder.icmp(lc.ICMP_EQ, step, zero)

    with cgutils.if_unlikely(builder, zero_step):
        # step shouldn't be zero
        context.return_errcode(builder, 1)

    with cgutils.ifelse(builder, sign_differs) as (then, orelse):
        with then:
            builder.store(zero, iterobj.count)

        with orelse:
            rem = builder.srem(diff, step)
            uneven = builder.icmp(lc.ICMP_SGT, rem, zero)
            newcount = builder.add(builder.sdiv(diff, step),
                                   builder.select(uneven, one, zero))
            builder.store(newcount, iterobj.count)

    return iterobj._getvalue()
Exemplo n.º 29
0
def for_range(builder, count, intp):
    start = Constant.int(intp, 0)
    stop = count

    bbcond = append_basic_block(builder, "for.cond")
    bbbody = append_basic_block(builder, "for.body")
    bbend = append_basic_block(builder, "for.end")

    bbstart = builder.basic_block
    builder.branch(bbcond)

    ONE = Constant.int(intp, 1)

    with goto_block(builder, bbcond):
        index = builder.phi(intp, name="loop.index")
        pred = builder.icmp(lc.ICMP_SLT, index, stop)
        builder.cbranch(pred, bbbody, bbend)

    with goto_block(builder, bbbody):
        yield index
        bbbody = builder.basic_block
        incr = builder.add(index, ONE)
        terminate(builder, bbcond)

    index.add_incoming(start, bbstart)
    index.add_incoming(incr, bbbody)

    builder.position_at_end(bbend)
Exemplo n.º 30
0
def from_S_ints(arr, key):
    raise NotImplementedError
    builder = arr.builder
    num = len(key)
    newnd = arr.nd - num
    if newnd < 0:
        raise ValueError("Too many keys")
    new = arr.getview(nd=newnd)

    oldshape = get_shape_ptr(builder, arr.array_ptr)
    newshape = get_shape_ptr(builder, new.array_ptr)
    # Load the shape array
    for i in range(newnd):
        val = load_at(builder, oldshape, i + num)
        store_at(builder, newshape, i, val)

    # Load the data-pointer
    old_data_ptr = get_data_ptr(builder, arr.array_ptr)
    new_data_ptr = get_data_ptr(builder, new.array_ptr)

    loc = Constant.int(intp_type, 0)
    factor = Constant.int(intp_type, 1)
    for index in range(arr.nd - 1, -1, -1):
        val = load_at(builder, oldshape, index)
        factor = builder.mul(factor, val)
        if index < num:  #
            keyval = auto_const_intp(key[index])
            # Multiply by strides
            tmp = builder.mul(keyval, factor)
            # Add to location
            loc = builder.add(loc, tmp)
    ptr = builder.gep(old_data_ptr, [loc])
    builder.store(ptr, new_data_ptr)
    return new
Exemplo n.º 31
0
    def code_gen(self):
        condition = self.expr.code_gen()
        if str(condition.type) == 'double':
            condition_value = g_llvm_builder.fcmp(
                RPRED_UNE, condition, Constant.real(condition.type, 0))
        else:
            condition_value = g_llvm_builder.icmp(
                IPRED_NE, condition, Constant.int(condition.type, 0))
        function = g_llvm_builder.basic_block.function
        #pre_header_block = g_llvm_builder.basic_block
        loop_block = function.append_basic_block('while')
        afterloop_block = function.append_basic_block('afterwhile')

        g_llvm_builder.cbranch(condition_value, loop_block, afterloop_block)
        g_llvm_builder.position_at_end(loop_block)

        for stmt in self.stmts:
            stmt.code_gen()

        condition = self.expr.code_gen()
        if str(condition.type) == 'double':
            condition_value = g_llvm_builder.fcmp(
                RPRED_UNE, condition, Constant.real(condition.type, 0))
        else:
            condition_value = g_llvm_builder.icmp(
                IPRED_NE, condition, Constant.int(condition.type, 0))
        g_llvm_builder.cbranch(condition_value, loop_block, afterloop_block)
        g_llvm_builder.position_at_end(afterloop_block)
Exemplo n.º 32
0
    def code_gen(self):
        condition = self.condition.code_gen()

        if str(condition.type) == 'double':
            condition_value = g_llvm_builder.fcmp(
                RPRED_UNE, condition, Constant.real(condition.type, 0))
        else:
            condition_value = g_llvm_builder.icmp(
                IPRED_NE, condition, Constant.int(condition.type, 0))

        function = g_llvm_builder.basic_block.function
        if_block = function.append_basic_block('if')
        else_block = function.append_basic_block('else')
        merge_block = function.append_basic_block('merge')
        g_llvm_builder.cbranch(condition_value, if_block, else_block)

        g_llvm_builder.position_at_end(if_block)
        self.if_node.code_gen()
        g_llvm_builder.branch(merge_block)

        g_llvm_builder.position_at_end(else_block)
        if self.else_node is not None:
            self.else_node.code_gen()
        g_llvm_builder.branch(merge_block)

        g_llvm_builder.position_at_end(merge_block)
Exemplo n.º 33
0
def from_S_ints(arr, key):
    raise NotImplementedError
    builder = arr.builder
    num = len(key)
    newnd = arr.nd - num
    if newnd < 0:
        raise ValueError("Too many keys")
    new = arr.getview(nd=newnd)

    oldshape = get_shape_ptr(builder, arr.array_ptr)
    newshape = get_shape_ptr(builder, new.array_ptr)
    # Load the shape array
    for i in range(newnd):
        val = load_at(builder, oldshape, i + num)
        store_at(builder, newshape, i, val)

    # Load the data-pointer
    old_data_ptr = get_data_ptr(builder, arr.array_ptr)
    new_data_ptr = get_data_ptr(builder, new.array_ptr)

    loc = Constant.int(intp_type, 0)
    factor = Constant.int(intp_type, 1)
    for index in range(arr.nd - 1, -1, -1):
        val = load_at(builder, oldshape, index)
        factor = builder.mul(factor, val)
        if index < num:  #
            keyval = auto_const_intp(key[index])
            # Multiply by strides
            tmp = builder.mul(keyval, factor)
            # Add to location
            loc = builder.add(loc, tmp)
    ptr = builder.gep(old_data_ptr, [loc])
    builder.store(ptr, new_data_ptr)
    return new
Exemplo n.º 34
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.unsigned_domain:
            return Constant.int(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)
Exemplo n.º 35
0
 def visit_LitInt(self, node):
     ty = self.specialize(node)
     if ty is double_type:
         return Constant.real(double_type, node.n)
     elif ty == int_type:
         return Constant.int(int_type, node.n)
     elif ty == int64_type:
         return Constant.int(int64_type, node.n)
Exemplo n.º 36
0
def offsetof(struct_type, fieldnum, builder):
    nullval = Constant.null(Type.pointer(struct_type))
    if hasattr(fieldnum, '__index__'):
        fieldnum = fieldnum.__index__()
        fieldnum = Constant.int(int_type, fieldnum)
    offset = builder.gep(nullval, [zero_p, fieldnum])
    offsetI = builder.bitcast(offset, int_type)
    return offsetI
Exemplo n.º 37
0
    def op_UNARY_NEGATIVE(self, ty, source, target):

        if ty == btypes.int_type:
            self.stack[target] = self.builder.sub(Constant.int(int_type, 0),
                                                  self.stack[source], target)
        elif ty == btypes.float_type:
            self.stack[target] = self.builder.fsub(
                Constant.real(float_type, 0.0), self.stack[source], target)
Exemplo n.º 38
0
def offsetof(struct_type, fieldnum, builder):
    nullval = Constant.null(Type.pointer(struct_type))
    if hasattr(fieldnum, '__index__'):
        fieldnum = fieldnum.__index__()
        fieldnum = Constant.int(int_type, fieldnum)
    offset = builder.gep(nullval, [zero_p, fieldnum])
    offsetI = builder.bitcast(offset, int_type)
    return offsetI
Exemplo n.º 39
0
def get_item_pointer2(builder,
                      data,
                      shape,
                      strides,
                      layout,
                      inds,
                      wraparound=False):
    if wraparound:
        # Wraparound
        indices = []
        for ind, dimlen in zip(inds, shape):
            ZERO = Constant.null(ind.type)
            negative = builder.icmp(lc.ICMP_SLT, ind, ZERO)
            wrapped = builder.add(dimlen, ind)
            selected = builder.select(negative, wrapped, ind)
            indices.append(selected)
    else:
        indices = inds
    del inds
    intp = indices[0].type
    # Indexing code
    if layout in 'CF':
        steps = []
        # Compute steps for each dimension
        if layout == 'C':
            # C contiguous
            for i in range(len(shape)):
                last = Constant.int(intp, 1)
                for j in shape[i + 1:]:
                    last = builder.mul(last, j)
                steps.append(last)
        elif layout == 'F':
            # F contiguous
            for i in range(len(shape)):
                last = Constant.int(intp, 1)
                for j in shape[:i]:
                    last = builder.mul(last, j)
                steps.append(last)
        else:
            raise Exception("unreachable")

        # Compute index
        loc = Constant.int(intp, 0)
        for i, s in zip(indices, steps):
            tmp = builder.mul(i, s)
            loc = builder.add(loc, tmp)
        ptr = builder.gep(data, [loc])
        return ptr
    else:
        # Any layout
        dimoffs = [builder.mul(s, i) for s, i in zip(strides, indices)]
        offset = functools.reduce(builder.add, dimoffs)
        base = builder.ptrtoint(data, offset.type)
        where = builder.add(base, offset)
        ptr = builder.inttoptr(where, data.type)
        return ptr
Exemplo n.º 40
0
    def test_mysin(self):
        # 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
        ee = le.ExecutionEngine.new(mod)
        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)
Exemplo n.º 41
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)
        kwlist = cgutils.global_constant(self.module, ".kwlist", kwlist)
        return Constant.bitcast(kwlist, Type.pointer(stringtype))
Exemplo n.º 42
0
 def insert_const_string(self, mod, string):
     stringtype = GENERIC_POINTER
     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 = cgutils.global_constant(mod, name, text)
     return Constant.bitcast(gv, stringtype)
Exemplo n.º 43
0
 def insert_const_string(self, mod, string):
     stringtype = GENERIC_POINTER
     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 = cgutils.global_constant(mod, name, text)
     return Constant.bitcast(gv, stringtype)
Exemplo n.º 44
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)
        kwlist = cgutils.global_constant(self.module, ".kwlist", kwlist)
        return Constant.bitcast(kwlist, Type.pointer(stringtype))
Exemplo n.º 45
0
    def body(self, index):
        mod = self.function.module
        c_int32 = lambda val: Constant.int(Type.int(32), val)

        # global place holder for current mutant id
        id_var = mod.add_global_variable(Type.int(32), "P86.mutant_id")
        id_var.initializer = Constant.int(Type.int(32), 0)
        id_var.linkage = core.LINKAGE_EXTERNAL

        # global place holder module name containing the currently
        # selected mutant
        str_var = mod.add_global_variable(Type.pointer(Type.int(8)),
                                          "P86.mutant_mod")
        str_var.initializer = Constant.null(Type.pointer(Type.int(8)))
        str_var.linkage = core.LINKAGE_EXTERNAL

        # pointer to the tail of the mutant list (reverse order)
        lst_var = mod.add_global_variable(Type.pointer(mutant_t),
                                          "P86.mutant_list")
        lst_var.initializer = Constant.null(Type.pointer(mutant_t))
        lst_var.linkage = core.LINKAGE_EXTERNAL

        ptr = self.var(Type.pointer(mutant_t), self.builder.load(lst_var))
        zero = self.constant(Type.int(32), 0)
        one = self.constant(Type.int(32), 1)

        # index zero disables all mutants
        with self.ifelse(index == zero) as ifelse:
            with ifelse.then():
                self.builder.store(id_var.initializer, id_var)
                self.builder.store(str_var.initializer, str_var)
                self.ret()

        # iterate the list until we get to the Nth element
        with self.loop() as loop:
            with loop.condition() as setcond:
                setcond(index > one)

            with loop.body():
                nxt = self.builder.gep(ptr.value, [c_int32(0), c_int32(2)])
                ptr.assign(CVar(self, nxt))
                index -= one

        # assign mutant id
        handle = self.builder.gep(ptr.value, [c_int32(0), c_int32(0)])
        handle = self.builder.load(handle)
        self.builder.store(handle, id_var)

        # assign module name containing the mutant
        handle = self.builder.gep(ptr.value, [c_int32(0), c_int32(1)])
        handle = self.builder.load(handle)
        self.builder.store(handle, str_var)

        self.ret()
Exemplo n.º 46
0
 def const(self, val):
     if isinstance(val, (int, long)):
         return Constant.int(int_type, val)
     elif isinstance(val, float):
         return Constant.real(float_type, val)
     elif isinstance(val, bool):
         return Constant.int(bool_type, int(val))
     elif isinstance(val, str):
         return Constant.stringz(val)
     else:
         raise NotImplementedError
Exemplo n.º 47
0
 def const(self, val):
     if isinstance(val, (int, long)):
         return Constant.int(int_type, val)
     elif isinstance(val, float):
         return Constant.real(double_type, val)
     elif isinstance(val, bool):
         return Constant.int(bool_type, int(val))
     elif isinstance(val, str):
         return Constant.stringz(val)
     else:
         raise NotImplementedError
Exemplo n.º 48
0
 def code_gen(self):
     value = self.right.code_gen()
     if self.operator.word == '-':
         if value.type == Type.int(32) or value.type == Type.int(8):
             return Constant.int(value.type, '0').sub(value)
         elif value.type == Type.double():
             return Constant.real(value.type, '0').fsub(value)
     else:
         if value.type == Type.int(32) or value.type == Type.int(8) or Type.int(1):
             return Constant.int(value.type, '0').icmp(IPRED_EQ, value)
         elif value.type == Type.double():
             return Constant.real(value.type, '0').fcmp(RPRED_UEQ, value)
Exemplo n.º 49
0
 def test_struct_extract_value_2d(self):
     ta = Type.struct([Type.int(32), Type.float()])
     tb = Type.struct([ta, Type.float()])
     m = Module.new('')
     f = m.add_function(Type.function(Type.void(), []), "foo")
     b = Builder.new(f.append_basic_block(''))
     v = Constant.undef(tb)
     ins = b.insert_value(v, Constant.real(Type.float(), 1.234), [0, 1])
     ext = b.extract_value(ins, [0, 1])
     b.ret_void()
     m.verify()
     self.assertEqual(str(ext), 'float 0x3FF3BE76C0000000')
Exemplo n.º 50
0
 def is_true(self, builder, typ, val):
     if typ in types.integer_domain:
         return builder.icmp(lc.ICMP_NE, val, Constant.null(val.type))
     elif typ in types.real_domain:
         return builder.fcmp(lc.FCMP_ONE, val, Constant.real(val.type, 0))
     elif typ in types.complex_domain:
         cmplx = self.make_complex(typ)(self, builder, val)
         fty = types.float32 if typ == types.complex64 else types.float64
         real_istrue = self.is_true(builder, fty, cmplx.real)
         imag_istrue = self.is_true(builder, fty, cmplx.imag)
         return builder.or_(real_istrue, imag_istrue)
     raise NotImplementedError("is_true", val, typ)
Exemplo n.º 51
0
 def test_struct_extract_value_2d(self):
     ta = Type.struct([Type.int(32), Type.float()])
     tb = Type.struct([ta, Type.float()])
     m = Module.new('')
     f = m.add_function(Type.function(Type.void(), []), "foo")
     b = Builder.new(f.append_basic_block(''))
     v = Constant.undef(tb)
     ins = b.insert_value(v, Constant.real(Type.float(), 1.234), [0, 1])
     ext = b.extract_value(ins, [0, 1])
     b.ret_void()
     m.verify()
     self.assertEqual(str(ext), 'float 0x3FF3BE76C0000000')
Exemplo n.º 52
0
 def code_gen(self):
     value = self.right.code_gen()
     if self.operator.word == '-':
         if value.type == Type.int(32) or value.type == Type.int(8):
             return Constant.int(value.type, '0').sub(value)
         elif value.type == Type.double():
             return Constant.real(value.type, '0').fsub(value)
     else:
         if value.type == Type.int(32) or value.type == Type.int(
                 8) or Type.int(1):
             return Constant.int(value.type, '0').icmp(IPRED_EQ, value)
         elif value.type == Type.double():
             return Constant.real(value.type, '0').fcmp(RPRED_UEQ, value)
Exemplo n.º 53
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)
Exemplo n.º 54
0
 def atom(self, expr):
     if expr.assym in self.locl:
         return self.locl[expr.assym]
     if expr.assym in self.env.names:
         return self.env.names[expr.assym]
     if expr.isnum:
         return Constant.int(Type.int(), expr.value)
     if expr.isstring:
         s = Constant.stringz(expr.value.encode('utf-8'))
         mem = self.env.constant(s)
         return self.bb.gep(mem, [Constant.int(Type.int(), 0)]*2)
     sys.stderr.write("atom undefined {}\n".format(expr))
     sys.exit(1)
Exemplo n.º 55
0
def get_item_pointer2(builder, data, shape, strides, layout, inds,
                      wraparound=False):
    if wraparound:
        # Wraparound
        indices = []
        for ind, dimlen in zip(inds, shape):
            ZERO = Constant.null(ind.type)
            negative = builder.icmp(lc.ICMP_SLT, ind, ZERO)
            wrapped = builder.add(dimlen, ind)
            selected = builder.select(negative, wrapped, ind)
            indices.append(selected)
    else:
        indices = inds
    del inds
    intp = indices[0].type
    # Indexing code
    if layout in 'CF':
        steps = []
        # Compute steps for each dimension
        if layout == 'C':
            # C contiguous
            for i in range(len(shape)):
                last = Constant.int(intp, 1)
                for j in shape[i + 1:]:
                    last = builder.mul(last, j)
                steps.append(last)
        elif layout == 'F':
            # F contiguous
            for i in range(len(shape)):
                last = Constant.int(intp, 1)
                for j in shape[:i]:
                    last = builder.mul(last, j)
                steps.append(last)
        else:
            raise Exception("unreachable")

        # Compute index
        loc = Constant.int(intp, 0)
        for i, s in zip(indices, steps):
            tmp = builder.mul(i, s)
            loc = builder.add(loc, tmp)
        ptr = builder.gep(data, [loc])
        return ptr
    else:
        # Any layout
        dimoffs = [builder.mul(s, i) for s, i in zip(strides, indices)]
        offset = functools.reduce(builder.add, dimoffs)
        base = builder.ptrtoint(data, offset.type)
        where = builder.add(base, offset)
        ptr = builder.inttoptr(where, data.type)
        return ptr
Exemplo n.º 56
0
        def generate(self,*args):
            assert len(args) == 2 # numerator and denominator
            builder=self.builder
            context=self.context
            tyinputs = self.outer_sig.args
            tyout = self.outer_sig.return_type
            tyout_llvm = context.get_data_type(tyout)
            inner_sig = typing.signature(self.loop_out_types[0],
                                         *self.loop_in_types)
            fn = context.get_function(operator, inner_sig)
            num, den = args

            iszero = cgutils.is_scalar_zero(builder, den)
            with cgutils.ifelse(builder, iszero, expect=False) as (then, orelse):
                with then:
                    # Divide by zero
                    if ((tyinputs[0] in types.real_domain or
                         tyinputs[1] in types.real_domain) or
                        not numpy_support.int_divbyzero_returns_zero) or \
                        operator=='/':
                        # If num is float and is 0 also, return Nan; else
                        # return Inf
                        outltype = context.get_data_type(types.float64)
                        shouldretnan = cgutils.is_scalar_zero(builder, num)
                        nan = Constant.real(outltype, float("nan"))
                        inf = Constant.real(outltype, float("inf"))
                        tempres = builder.select(shouldretnan, nan, inf)
                        res_then = context.cast(builder, tempres, types.float64,
                                                tyout)
                    elif tyout in types.signed_domain and \
                            not numpy_support.int_divbyzero_returns_zero:
                        res_then = Constant.int(tyout_llvm,
                                                0x1 << (den.type.width-1))
                    else:
                        res_then = Constant.null(tyout_llvm)
                    bb_then = builder.basic_block
                with orelse:
                    # Normal
                    cast_args = [self.context.cast(self.builder, val, inty,
                                                   outty)
                                 for val, inty, outty
                                 in zip(args, self.outer_sig.args,
                                        self.loop_in_types)]
                    tempres = fn(builder, cast_args)
                    res_else = context.cast(builder, tempres,
                                            self.loop_out_types[0], tyout)
                    bb_else = builder.basic_block
            out = builder.phi(tyout_llvm)
            out.add_incoming(res_then, bb_then)
            out.add_incoming(res_else, bb_else)
            return out
Exemplo n.º 57
0
def is_leap_year(builder, year_val):
    """
    Return a predicate indicating whether *year_val* (offset by 1970) is a
    leap year.
    """
    actual_year = builder.add(year_val, Constant.int(DATETIME64, 1970))
    multiple_of_4 = cgutils.is_null(
        builder, builder.and_(actual_year, Constant.int(DATETIME64, 3)))
    not_multiple_of_100 = cgutils.is_not_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 100)))
    multiple_of_400 = cgutils.is_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 400)))
    return builder.and_(multiple_of_4,
                        builder.or_(not_multiple_of_100, multiple_of_400))
Exemplo n.º 58
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