Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
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
Ejemplo n.º 5
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()
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
Archivo: toy.py Proyecto: mabragor/ibcl
    def CodeGen(self):
        print >> stderr, "codegening let node"
        old_bindings = {}
        function = G_LLVM_BUILDER.basic_block.function

        for var_name, var_expression in self.variables.iteritems():
            if var_expression is not None:
                var_value = var_expression.CodeGen()
            else:
                var_value = Constant.real(Type.double(), 0)

            alloca = create_entry_block_alloca(function, var_name)
            G_LLVM_BUILDER.store(var_value, alloca)

            old_bindings[var_name] = G_NAMED_VALUES.get(var_name, None)

            G_NAMED_VALUES[var_name] = alloca

        body = self.body.CodeGen()

        for var_name in self.variables:
            if old_bindings[var_name] is not None:
                G_NAMED_VALUES[var_name] = old_bindings[var_name]
            else:
                del G_NAMED_VALUES[var_name]

        return body
Ejemplo n.º 8
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
Ejemplo n.º 9
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)
Ejemplo n.º 10
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
Ejemplo n.º 11
0
    def code_gen(self):
        condition = self.condition.code_gen()
        condition_bool = g_llvm_builder.fcmp(FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcmd')
        function = g_llvm_builder.basic_block.function

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

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

        then_block = g_llvm_builder.basic_block

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

        else_block = g_llvm_builder.basic_block

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

        return phi
Ejemplo n.º 12
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()
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)
Ejemplo 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)
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
Archivo: toy.py Proyecto: mabragor/ibcl
    def CodeGen(self):
        print >> stderr, "codegening for node"
        function = G_LLVM_BUILDER.basic_block.function

        alloca = create_entry_block_alloca(function, self.loop_variable)

        start_value = self.start.CodeGen()

        G_LLVM_BUILDER.store(start_value, alloca)

        loop_block = function.append_basic_block('loop')

        G_LLVM_BUILDER.branch(loop_block)

        G_LLVM_BUILDER.position_at_end(loop_block)

        old_value = G_NAMED_VALUES.get(self.loop_variable, None)
        G_NAMED_VALUES[self.loop_variable] = alloca

        self.body.CodeGen()

        if self.step:
            step_value = self.step.CodeGen()
        else:
            step_value = Constant.real(Type.double(), 1)

        end_condition = self.end.CodeGen()
        
        cur_value = G_LLVM_BUILDER.load(alloca, self.loop_variable)
        next_value = G_LLVM_BUILDER.fadd(cur_value, step_value, 'nextvar')
        G_LLVM_BUILDER.store(next_value, alloca)

        end_condition_bool = G_LLVM_BUILDER.fcmp(
            FCMP_ONE, end_condition, Constant.real(Type.double(), 0), 'loopcond')

        after_block = function.append_basic_block('afterloop')

        G_LLVM_BUILDER.cbranch(end_condition_bool, loop_block, after_block)

        G_LLVM_BUILDER.position_at_end(after_block)

        if old_value:
            G_NAMED_VALUES[self.loop_variable] = old_value
        else:
            del G_NAMED_VALUES[self.loop_variable]

        return Constant.real(Type.double(), 0)
Ejemplo n.º 18
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)
Ejemplo n.º 19
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)
Ejemplo n.º 20
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)
Ejemplo n.º 21
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
Ejemplo n.º 22
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
Ejemplo n.º 23
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')
Ejemplo n.º 24
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)
Ejemplo n.º 25
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')
Ejemplo n.º 26
0
def timedelta_over_timedelta(context, builder, sig, args):
    [va, vb] = args
    [ta, tb] = sig.args
    not_nan = are_not_nat(builder, [va, vb])
    ll_ret_type = context.get_value_type(sig.return_type)
    ret = cgutils.alloca_once(builder, ll_ret_type, name='ret')
    builder.store(Constant.real(ll_ret_type, float('nan')), ret)
    with cgutils.if_likely(builder, not_nan):
        va, vb = normalize_timedeltas(context, builder, va, vb, ta, tb)
        va = builder.sitofp(va, ll_ret_type)
        vb = builder.sitofp(vb, ll_ret_type)
        builder.store(builder.fdiv(va, vb), ret)
    return builder.load(ret)
Ejemplo n.º 27
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
            )
Ejemplo n.º 28
0
def real_sign_impl(context, builder, sig, args):
    [x] = args
    POS = Constant.real(x.type, 1)
    NEG = Constant.real(x.type, -1)
    ZERO = Constant.real(x.type, 0)

    presult = cgutils.alloca_once(builder, x.type)

    is_pos = builder.fcmp(lc.FCMP_OGT, x, ZERO)
    is_neg = builder.fcmp(lc.FCMP_OLT, x, ZERO)

    with cgutils.ifelse(builder, is_pos) as (gt_zero, not_gt_zero):
        with gt_zero:
            builder.store(POS, presult)
        with not_gt_zero:
            with cgutils.ifelse(builder, is_neg) as (lt_zero, not_lt_zero):
                with lt_zero:
                    builder.store(NEG, presult)
                with not_lt_zero:
                    # For both NaN and 0, the result of sign() is simply
                    # the input value.
                    builder.store(x, presult)

    return builder.load(presult)
Ejemplo n.º 29
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)
Ejemplo n.º 30
0
def real_sign_impl(context, builder, sig, args):
    [x] = args
    POS = Constant.real(x.type, 1)
    NEG = Constant.real(x.type, -1)
    ZERO = Constant.real(x.type, 0)

    cmp_zero = builder.fcmp(lc.FCMP_OEQ, x, ZERO)
    cmp_pos = builder.fcmp(lc.FCMP_OGT, x, ZERO)

    presult = builder.alloca(x.type)

    bb_zero = cgutils.append_basic_block(builder, ".zero")
    bb_postest = cgutils.append_basic_block(builder, ".postest")
    bb_pos = cgutils.append_basic_block(builder, ".pos")
    bb_neg = cgutils.append_basic_block(builder, ".neg")
    bb_exit = cgutils.append_basic_block(builder, ".exit")

    builder.cbranch(cmp_zero, bb_zero, bb_postest)

    with cgutils.goto_block(builder, bb_zero):
        builder.store(ZERO, presult)
        builder.branch(bb_exit)

    with cgutils.goto_block(builder, bb_postest):
        builder.cbranch(cmp_pos, bb_pos, bb_neg)

    with cgutils.goto_block(builder, bb_pos):
        builder.store(POS, presult)
        builder.branch(bb_exit)

    with cgutils.goto_block(builder, bb_neg):
        builder.store(NEG, presult)
        builder.branch(bb_exit)

    builder.position_at_end(bb_exit)
    return builder.load(presult)
Ejemplo n.º 31
0
def complex_negate_impl(context, builder, sig, args):
    [typ] = sig.args
    [val] = args
    cmplxcls = context.make_complex(typ)
    cmplx = cmplxcls(context, builder, val)

    real = cmplx.real
    imag = cmplx.imag

    zero = Constant.real(real.type, 0)

    res = cmplxcls(context, builder)
    res.real = builder.fsub(zero, real)
    res.imag = builder.fsub(zero, imag)
    return res._getvalue()
Ejemplo n.º 32
0
def complex_negate_impl(context, builder, sig, args):
    [typ] = sig.args
    [val] = args
    cmplxcls = context.make_complex(typ)
    cmplx = cmplxcls(context, builder, val)

    real = cmplx.real
    imag = cmplx.imag

    zero = Constant.real(real.type, 0)

    res = cmplxcls(context, builder)
    res.real = builder.fsub(zero, real)
    res.imag = builder.fsub(zero, imag)
    return res._getvalue()
Ejemplo n.º 33
0
def real_sign_impl(context, builder, sig, args):
    [x] = args
    POS = Constant.real(x.type, 1)
    NEG = Constant.real(x.type, -1)
    ZERO = Constant.real(x.type, 0)

    presult = cgutils.alloca_once(builder, x.type)

    is_pos = builder.fcmp(lc.FCMP_OGT, x, ZERO)
    is_neg = builder.fcmp(lc.FCMP_OLT, x, ZERO)

    with cgutils.ifelse(builder, is_pos) as (gt_zero, not_gt_zero):
        with gt_zero:
            builder.store(POS, presult)
        with not_gt_zero:
            with cgutils.ifelse(builder, is_neg) as (lt_zero, not_lt_zero):
                with lt_zero:
                    builder.store(NEG, presult)
                with not_lt_zero:
                    # For both NaN and 0, the result of sign() is simply
                    # the input value.
                    builder.store(x, presult)

    return builder.load(presult)
Ejemplo n.º 34
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)
Ejemplo n.º 35
0
Archivo: toy.py Proyecto: mabragor/ibcl
def codegen_for_data(expr):
    if isinstance(expr, int) or isinstance(expr, float):
        return Constant.real(Type.double(), expr)
    elif isinstance(expr, Symbol):
        return CallExpressionNode("intern",
                                  [StringExpressionNode(expr.name)]).CodeGen()
    elif expr is None:
        return CallExpressionNode("intern",
                                  [StringExpressionNode("nil")]).CodeGen()
    elif isinstance(expr, Cons):
        return CallExpressionNode("cons",
                                  [QuoteExpressionNode(expr.car),
                                   QuoteExpressionNode(expr.cdr)]).CodeGen()

    else:
        raise RuntimeError("Don't know how to codewalk following data type %s"
                           % type(expr))
Ejemplo n.º 36
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, int)):
            self.stack[target] = Constant.real(float_type, value)
        elif isinstance(value, str):
            content = Constant.stringz(value)
            name = CONSTANT_NAMING % self.string_count
            self.string_count += 1

            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
Ejemplo n.º 37
0
def printf(builder, format_string, *values):
    str_const = Constant.stringz(format_string)
    global_str_const = get_module(builder).add_global_variable(
        str_const.type, '')
    global_str_const.initializer = str_const

    idx = [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0)]
    str_addr = global_str_const.gep(idx)

    args = []
    for v in values:
        if isinstance(v, int):
            args.append(Constant.int(Type.int(), v))
        elif isinstance(v, float):
            args.append(Constant.real(Type.double(), v))

    functype = Type.function(Type.int(32), [Type.pointer(Type.int(8))], True)
    fn = get_module(builder).add_function(functype, 'printf')
    builder.call(fn, [str_addr] + args)
Ejemplo n.º 38
0
def printf(builder, format_string, *values):
    str_const = Constant.stringz(format_string)
    global_str_const = get_module(builder).add_global_variable(str_const.type,
                                                               '')
    global_str_const.initializer = str_const

    idx = [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0)]
    str_addr = global_str_const.gep(idx)

    args = []
    for v in values:
        if isinstance(v, int):
            args.append(Constant.int(Type.int(), v))
        elif isinstance(v, float):
            args.append(Constant.real(Type.double(), v))

    functype = Type.function(Type.int(32), [Type.pointer(Type.int(8))], True)
    fn = get_module(builder).add_function(functype, 'printf')
    builder.call(fn, [str_addr] + args)
Ejemplo n.º 39
0
    def CodeGen(self):
        condition = self.condition.CodeGen()

        # Convert condition to a bool by comparing equal to 0.0.
        condition_bool = g_llvm_builder.fcmp(
            FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcond')

        function = g_llvm_builder.basic_block.function

        # Create blocks for the then and else cases. Insert the 'then' block
        # at the end of the function.
        then_block = function.append_basic_block('then')
        else_block = function.append_basic_block('else')
        merge_block = function.append_basic_block('ifcond')

        g_llvm_builder.cbranch(condition_bool, then_block, else_block)

        # Emit then value.
        g_llvm_builder.position_at_end(then_block)
        then_value = self.then_branch.CodeGen()
        g_llvm_builder.branch(merge_block)

        # Codegen of 'Then' can change the current block; update then_block
        # for the PHI node.
        then_block = g_llvm_builder.basic_block

        # Emit else block.
        g_llvm_builder.position_at_end(else_block)
        else_value = self.else_branch.CodeGen()
        g_llvm_builder.branch(merge_block)

        # Codegen of 'Else' can change the current block, update else_block
        # for the PHI node.
        else_block = g_llvm_builder.basic_block

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

        return phi
Ejemplo n.º 40
0
Archivo: sfpl.py Proyecto: rigtorp/sfpl
 def gen_code(self, module, builder, variables):
     condition = self.condition.gen_code(module, builder, variables)
     condition_bool = builder.fcmp(FCMP_ONE, condition, Constant.real(Type.double(), 0), 'ifcond')
     function = builder.basic_block.function
     then_block = function.append_basic_block('then')
     else_block = function.append_basic_block('else')
     merge_block = function.append_basic_block('ifcond')
     builder.cbranch(condition_bool, then_block, else_block)
     builder.position_at_end(then_block)
     then_value = self.then_branch.gen_code(module, builder, variables)
     builder.branch(merge_block)
     then_block = builder.basic_block
     builder.position_at_end(else_block)
     else_value = self.else_branch.gen_code(module, builder, variables)
     builder.branch(merge_block)
     else_block = builder.basic_block
     builder.position_at_end(merge_block)
     phi = builder.phi(Type.double(), 'iftmp')
     phi.add_incoming(then_value, then_block)
     phi.add_incoming(else_value, else_block)
     return phi
Ejemplo n.º 41
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
Ejemplo n.º 42
0
def codegen_expr(builder, expr):
    kind = expr[0]
    if kind == 'number':
        number = expr[1]
        return Constant.real(double_type, number)
    elif kind == 'variable':
        name = expr[1]
        try:
            return named_values[name]
        except KeyError:
            raise CodegenError("unknown variable name")
    elif kind == 'binary':
        op, lhs, rhs = expr[1], expr[2], expr[3]
        lhs_val = codegen_expr(builder, lhs)
        rhs_val = codegen_expr(builder, rhs)
        if op == '+':
            return builder.add(lhs_val, rhs_val, 'addtmp')
        elif op == '-':
            return builder.sub(lhs_val, rhs_val, 'subtmp')
        elif op == '*':
            return builder.mul(lhs_val, rhs_val, 'multmp')
        elif op == '<':
            i = builder.fcmp(FCMP_ULT, lhs_val, rhs_val, 'cmptmp')
            return builder.uitofp(i, 'booltmp')
        else:
            raise CodegenError("invalid binary operator")
    elif kind == 'call':
        name, args = expr[1], expr[2]
        try:
            callee = Function.get(the_module, name)
        except LLVMException:
            raise CodegenError("unknown function referenced")
        if len(callee.args) != len(args):
            raise CodegenError("incorrect # arguments passed")
        arg_vals = []
        for arg in args:
            arg_val = codegen_expr(builder, arg)
            arg_vals.append(arg_val)
        return builder.call(callee, arg_vals, 'calltmp')
Ejemplo n.º 43
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
Ejemplo n.º 44
0
def codegen_expr(builder, expr):
    kind = expr[0]
    if kind == "number":
        number = expr[1]
        return Constant.real(double_type, number)
    elif kind == "variable":
        name = expr[1]
        try:
            return named_values[name]
        except KeyError:
            raise CodegenError("unknown variable name")
    elif kind == "binary":
        op, lhs, rhs = expr[1], expr[2], expr[3]
        lhs_val = codegen_expr(builder, lhs)
        rhs_val = codegen_expr(builder, rhs)
        if op == "+":
            return builder.add(lhs_val, rhs_val, "addtmp")
        elif op == "-":
            return builder.sub(lhs_val, rhs_val, "subtmp")
        elif op == "*":
            return builder.mul(lhs_val, rhs_val, "multmp")
        elif op == "<":
            i = builder.fcmp(FCMP_ULT, lhs_val, rhs_val, "cmptmp")
            return builder.uitofp(i, "booltmp")
        else:
            raise CodegenError("invalid binary operator")
    elif kind == "call":
        name, args = expr[1], expr[2]
        try:
            callee = Function.get(the_module, name)
        except LLVMException:
            raise CodegenError("unknown function referenced")
        if len(callee.args) != len(args):
            raise CodegenError("incorrect # arguments passed")
        arg_vals = []
        for arg in args:
            arg_val = codegen_expr(builder, arg)
            arg_vals.append(arg_val)
        return builder.call(callee, arg_vals, "calltmp")
Ejemplo n.º 45
0
    def code(self, context):
        condition = self.condition.code(context)
        zero = Constant.real(Type.double(), 0)
        boolean = context.builder.fcmp(FCMP_ONE, condition, zero, 'ifcond')

        func = context.builder.basic_block.function

        # Create blocks for the then and else cases. Insert the 'then' block
        # at the end of the function.
        then_block = func.append_basic_block('then')
        else_block = func.append_basic_block('else')
        merge_block = func.append_basic_block('ifcont')
        context.builder.cbranch(boolean, then_block, else_block)

        # Emit then value.
        context.builder.position_at_end(then_block)
        then_value = self.then_branch.code(context)
        context.builder.branch(merge_block)

        # code generation of 'Then' can change the current block; update
        # then_block or the PHI node.
        then_block = context.builder.basic_block

        # Emit else block.
        context.builder.position_at_end(else_block)
        else_value = self.else_branch.code(context)
        context.builder.branch(merge_block)

        # code generation of 'Else' can change the current block, update
        # else_block or the PHI node.
        else_block = context.builder.basic_block

        # Emit merge block.
        context.builder.position_at_end(merge_block)
        phi = context.builder.phi(Type.double(), 'iftmp')
        phi.add_incoming(then_value, then_block)
        phi.add_incoming(else_value, else_block)
        return phi
Ejemplo n.º 46
0
    def code(self, context):
        old_bindings = {}
        function = context.builder.basic_block.function

        # Register all variables and emit their initializer.
        for name, expression in self.variables.items():
            # Emit the initializer before adding the variable to scope, this
            # prevents the initializer from referencing the variable itself,
            # d permits stuff like this:
            #  var a = 1 in
            #    var a = a in ...   # refers to outer 'a'.
            if expression is not None:
                value = expression.code(context)
            else:
                value = Constant.real(Type.double(), 0)

            alloca = create_alloca_block(function, name)
            context.builder.store(value, alloca)

            # Remember the old variable binding so that we can restore the
            # binding when we unrecurse.
            old_bindings[name] = context.scope.get(name, None)

            # Remember this binding.
            context.scope[name] = alloca

        # Codegen the body, now that all vars are in scope.
        body = self.body.code(context)

        # Pop all our variables from scope.
        for name in self.variables:
            if old_bindings[name] is not None:
                context.scope[name] = old_bindings[name]
            else:
                del context.scope[name]

        # Return the body computation.
        return body
 def CodeGen(self):
     old_bindings = {}
     function = g_llvm_builder.basic_block.function
                         
     # Register all variables and emit their initializer.
     for var_name, var_expression in self.variables.iteritems():
     # Emit the initializer before adding the variable to scope, this prevents
     # the initializer from referencing the variable itself, and permits stuff
     # like this:
     #  var a = 1 in
     #    var a = a in ...   # refers to outer 'a'.
         if var_expression is not None:
             var_value = var_expression.CodeGen()
         else:
             var_value = Constant.real(Type.double(), 0)
                                             
         alloca = CreateEntryBlockAlloca(function, var_name)
         g_llvm_builder.store(var_value, alloca)
                                                     
         # Remember the old variable binding so that we can restore the binding
         # when we unrecurse.
         old_bindings[var_name] = g_named_values.get(var_name, None)
                                                         
         # Remember this binding.
         g_named_values[var_name] = alloca
                                                             
     # Codegen the body, now that all vars are in scope.
     body = self.body.CodeGen()
                                                                 
     # Pop all our variables from scope.
     for var_name in self.variables:
         if old_bindings[var_name] is not None:
             g_named_values[var_name] = old_bindings[var_name]
         else:
             del g_named_values[var_name]
                                                                                     
     # Return the body computation.
     return body
Ejemplo n.º 48
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)
Ejemplo n.º 49
0
def real_divmod_func_body(context, builder, vx, wx):
    # Reference Objects/floatobject.c
    #
    # float_divmod(PyObject *v, PyObject *w)
    # {
    #     double vx, wx;
    #     double div, mod, floordiv;
    #     CONVERT_TO_DOUBLE(v, vx);
    #     CONVERT_TO_DOUBLE(w, wx);
    #     mod = fmod(vx, wx);
    #     /* fmod is typically exact, so vx-mod is *mathematically* an
    #        exact multiple of wx.  But this is fp arithmetic, and fp
    #        vx - mod is an approximation; the result is that div may
    #        not be an exact integral value after the division, although
    #        it will always be very close to one.
    #     */
    #     div = (vx - mod) / wx;
    #     if (mod) {
    #         /* ensure the remainder has the same sign as the denominator */
    #         if ((wx < 0) != (mod < 0)) {
    #             mod += wx;
    #             div -= 1.0;
    #         }
    #     }
    #     else {
    #         /* the remainder is zero, and in the presence of signed zeroes
    #            fmod returns different results across platforms; ensure
    #            it has the same sign as the denominator; we'd like to do
    #            "mod = wx * 0.0", but that may get optimized away */
    #         mod *= mod;  /* hide "mod = +0" from optimizer */
    #         if (wx < 0.0)
    #             mod = -mod;
    #     }
    #     /* snap quotient to nearest integral value */
    #     if (div) {
    #         floordiv = floor(div);
    #         if (div - floordiv > 0.5)
    #             floordiv += 1.0;
    #     }
    #     else {
    #         /* div is zero - get the same sign as the true quotient */
    #         div *= div;             /* hide "div = +0" from optimizers */
    #         floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
    #     }
    #     return Py_BuildValue("(dd)", floordiv, mod);
    # }
    pmod = cgutils.alloca_once(builder, vx.type)
    pdiv = cgutils.alloca_once(builder, vx.type)
    pfloordiv = cgutils.alloca_once(builder, vx.type)

    mod = builder.frem(vx, wx)
    div = builder.fdiv(builder.fsub(vx, mod), wx)

    builder.store(mod, pmod)
    builder.store(div, pdiv)

    ZERO = Constant.real(vx.type, 0)
    ONE = Constant.real(vx.type, 1)
    mod_istrue = builder.fcmp(lc.FCMP_ONE, mod, ZERO)
    wx_ltz = builder.fcmp(lc.FCMP_OLT, wx, ZERO)
    mod_ltz = builder.fcmp(lc.FCMP_OLT, mod, ZERO)

    with cgutils.ifthen(builder, mod_istrue):
        wx_ltz_ne_mod_ltz = builder.icmp(lc.ICMP_NE, wx_ltz, mod_ltz)

        with cgutils.ifthen(builder, wx_ltz_ne_mod_ltz):
            mod = builder.fadd(mod, wx)
            div = builder.fsub(div, ONE)
            builder.store(mod, pmod)
            builder.store(div, pdiv)

    del mod
    del div

    with cgutils.ifnot(builder, mod_istrue):
        mod = builder.load(pmod)
        mod = builder.fmul(mod, mod)
        builder.store(mod, pmod)
        del mod

        with cgutils.ifthen(builder, wx_ltz):
            mod = builder.load(pmod)
            mod = builder.fsub(ZERO, mod)
            builder.store(mod, pmod)
            del mod

    div = builder.load(pdiv)
    div_istrue = builder.fcmp(lc.FCMP_ONE, div, ZERO)

    with cgutils.ifthen(builder, div_istrue):
        module = cgutils.get_module(builder)
        floorfn = lc.Function.intrinsic(module, lc.INTR_FLOOR, [wx.type])
        floordiv = builder.call(floorfn, [div])
        floordivdiff = builder.fsub(div, floordiv)
        floordivincr = builder.fadd(floordiv, ONE)
        HALF = Constant.real(wx.type, 0.5)
        pred = builder.fcmp(lc.FCMP_OGT, floordivdiff, HALF)
        floordiv = builder.select(pred, floordivincr, floordiv)
        builder.store(floordiv, pfloordiv)

    with cgutils.ifnot(builder, div_istrue):
        div = builder.fmul(div, div)
        builder.store(div, pdiv)
        floordiv = builder.fdiv(builder.fmul(div, vx), wx)
        builder.store(floordiv, pfloordiv)

    return builder.load(pfloordiv), builder.load(pmod)
Ejemplo n.º 50
0
    def impl(context, builder, sig, args):
        [tyvx, tywy, tyout] = sig.args
        [vx, wy, out] = args
        assert tyvx.dtype == tywy.dtype
        ndim = tyvx.ndim

        xary = context.make_array(tyvx)(context, builder, vx)
        yary = context.make_array(tywy)(context, builder, wy)
        oary = context.make_array(tyout)(context, builder, out)

        intpty = context.get_value_type(types.intp)

        # TODO handle differing shape by mimicking broadcasting
        loopshape = cgutils.unpack_tuple(builder, xary.shape, ndim)

        xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
                     for ary in (xary, yary, oary)]
        xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
                       for ary in (xary, yary, oary)]
        xyo_data = [ary.data for ary in (xary, yary, oary)]
        xyo_layout = [ty.layout for ty in (tyvx, tywy, tyout)]

        with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:
            [px, py, po] = [cgutils.get_item_pointer2(builder,
                                                      data=data, shape=shape,
                                                      strides=strides,
                                                      layout=layout,
                                                      inds=indices)
                            for data, shape, strides, layout
                            in zip(xyo_data, xyo_shape, xyo_strides,
                                   xyo_layout)]

            x = builder.load(px)
            y = builder.load(py)
            if divbyzero:
                # Handle division
                iszero = cgutils.is_scalar_zero(builder, y)
                with cgutils.ifelse(builder, iszero, expect=False) as (then,
                                                                       orelse):
                    with then:
                        # Divide by zero
                        if tyout.dtype in types.real_domain:
                            # If x is float and is 0 also, return Nan; else
                            # return Inf
                            outltype = context.get_data_type(tyout.dtype)
                            shouldretnan = cgutils.is_scalar_zero(builder, x)
                            nan = Constant.real(outltype, float("nan"))
                            inf = Constant.real(outltype, float("inf"))
                            res = builder.select(shouldretnan, nan, inf)
                        elif (tyout.dtype in types.signed_domain and
                                not numpy_support.int_divbyzero_returns_zero):
                            res = Constant.int(y.type, 0x1 << (y.type.width-1))
                        else:
                            res = Constant.null(y.type)

                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
                    with orelse:
                        # Normal
                        res = core(builder, (x, y))
                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
            else:
                # Handle other operations
                res = core(builder, (x, y))
                assert res.type == po.type.pointee, (res.type,
                                                     po.type.pointee)
                builder.store(res, po)

        return out
Ejemplo n.º 51
0
 def CodeGen(self):
     # Here is where things can be changed for types other than double
     # This returns a 'ConstantFloatingPoint' number from the
     # llvm.core.Constant class
     return Constant.real(Type.double(), self.value)
Ejemplo n.º 52
0
def float_usub(builder, val):
    return builder.fsub(Constant.real(val.type, 0), val)
Ejemplo n.º 53
0
def float_not(builder, val):
    return builder.fcmp(lc.FCMP_OEQ, val, Constant.real(val.type, 0))
Ejemplo n.º 54
0
    def impl(context, builder, sig, args):
        [tyinp1, tyinp2, tyout] = sig.args
        [inp1, inp2, out] = args

        if isinstance(tyinp1, types.Array):
            scalar_inp1 = False
            scalar_tyinp1 = tyinp1.dtype
            inp1_ndim = tyinp1.ndim
        elif tyinp1 in types.number_domain:
            scalar_inp1 = True
            scalar_tyinp1 = tyinp1
            inp1_ndim = 1
        else:
            raise TypeError('unknown type for first input operand')

        if isinstance(tyinp2, types.Array):
            scalar_inp2 = False
            scalar_tyinp2 = tyinp2.dtype
            inp2_ndim = tyinp2.ndim
        elif tyinp2 in types.number_domain:
            scalar_inp2 = True
            scalar_tyinp2 = tyinp2
            inp2_ndim = 1
        else:
            raise TypeError('unknown type for second input operand')

        out_ndim = tyout.ndim

        if asfloat:
            promote_type = types.float64
        elif scalar_tyinp1 in types.real_domain or \
                scalar_tyinp2 in types.real_domain:
            promote_type = types.float64
        elif scalar_tyinp1 in types.signed_domain or \
                scalar_tyinp2 in types.signed_domain:
            promote_type = types.int64
        else:
            promote_type = types.uint64

        result_type = promote_type

        # Temporary hack for __ftol2 llvm bug. Don't allow storing
        # float results in uint64 array on windows.
        if result_type in types.real_domain and \
                tyout.dtype is types.uint64 and \
                sys.platform.startswith('win32'):
            raise TypeError('Cannot store result in uint64 array')

        sig = typing.signature(result_type, promote_type, promote_type)

        if not scalar_inp1:
            i1ary = context.make_array(tyinp1)(context, builder, inp1)
        if not scalar_inp2:
            i2ary = context.make_array(tyinp2)(context, builder, inp2)
        oary = context.make_array(tyout)(context, builder, out)

        fnwork = context.get_function(funckey, sig)
        intpty = context.get_value_type(types.intp)

        if not scalar_inp1:
            inp1_shape = cgutils.unpack_tuple(builder, i1ary.shape, inp1_ndim)
            inp1_strides = cgutils.unpack_tuple(builder, i1ary.strides, inp1_ndim)
            inp1_data = i1ary.data
            inp1_layout = tyinp1.layout
        if not scalar_inp2:
            inp2_shape = cgutils.unpack_tuple(builder, i2ary.shape, inp2_ndim)
            inp2_strides = cgutils.unpack_tuple(builder, i2ary.strides, inp2_ndim)
            inp2_data = i2ary.data
            inp2_layout = tyinp2.layout
        out_shape = cgutils.unpack_tuple(builder, oary.shape, out_ndim)
        out_strides = cgutils.unpack_tuple(builder, oary.strides, out_ndim)
        out_data = oary.data
        out_layout = tyout.layout

        ZERO = Constant.int(Type.int(intpty.width), 0)
        ONE = Constant.int(Type.int(intpty.width), 1)

        inp1_indices = None
        if not scalar_inp1:
            inp1_indices = []
            for i in range(inp1_ndim):
                x = builder.alloca(Type.int(intpty.width))
                builder.store(ZERO, x)
                inp1_indices.append(x)

        inp2_indices = None
        if not scalar_inp2:
            inp2_indices = []
            for i in range(inp2_ndim):
                x = builder.alloca(Type.int(intpty.width))
                builder.store(ZERO, x)
                inp2_indices.append(x)

        loopshape = cgutils.unpack_tuple(builder, oary.shape, out_ndim)

        with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:

            # Increment input indices.
            # Since the output dimensions are already being incremented,
            # we'll use that to set the input indices. In order to
            # handle broadcasting, any input dimension of size 1 won't be
            # incremented.
            def build_increment_blocks(inp_indices, inp_shape, inp_ndim, inp_num):
                bb_inc_inp_index = [cgutils.append_basic_block(builder,
                    '.inc_inp{0}_index{1}'.format(inp_num, str(i))) for i in range(inp_ndim)]
                bb_end_inc_index = cgutils.append_basic_block(builder,
                                       '.end_inc{0}_index'.format(inp_num))

                builder.branch(bb_inc_inp_index[0])
                for i in range(inp_ndim):
                    with cgutils.goto_block(builder, bb_inc_inp_index[i]):
                        # If the shape of this dimension is 1, then leave the
                        # index at 0 so that this dimension is broadcasted over
                        # the corresponding input and output dimensions.
                        cond = builder.icmp(ICMP_UGT, inp_shape[i], ONE)
                        with cgutils.ifthen(builder, cond):
                            builder.store(indices[out_ndim-inp_ndim+i], inp_indices[i])
                        if i + 1 == inp_ndim:
                            builder.branch(bb_end_inc_index)
                        else:
                            builder.branch(bb_inc_inp_index[i+1])

                builder.position_at_end(bb_end_inc_index)

            if not scalar_inp1:
                build_increment_blocks(inp1_indices, inp1_shape, inp1_ndim, '1')
            if not scalar_inp2:
                build_increment_blocks(inp2_indices, inp2_shape, inp2_ndim, '2')

            if scalar_inp1:
                x = inp1
            else:
                inds = [builder.load(index) for index in inp1_indices]
                px = cgutils.get_item_pointer2(builder,
                                               data=inp1_data,
                                               shape=inp1_shape,
                                               strides=inp1_strides,
                                               layout=inp1_layout,
                                               inds=inds)
                x = builder.load(px)

            if scalar_inp2:
                y = inp2
            else:
                inds = [builder.load(index) for index in inp2_indices]
                py = cgutils.get_item_pointer2(builder,
                                               data=inp2_data,
                                               shape=inp2_shape,
                                               strides=inp2_strides,
                                               layout=inp2_layout,
                                               inds=inds)
                y = builder.load(py)

            po = cgutils.get_item_pointer2(builder,
                                           data=out_data,
                                           shape=out_shape,
                                           strides=out_strides,
                                           layout=out_layout,
                                           inds=indices)

            if divbyzero:
                # Handle division
                iszero = cgutils.is_scalar_zero(builder, y)
                with cgutils.ifelse(builder, iszero, expect=False) as (then,
                                                                       orelse):
                    with then:
                        # Divide by zero
                        if (scalar_tyinp1 in types.real_domain or
                                scalar_tyinp2 in types.real_domain) or \
                                not numpy_support.int_divbyzero_returns_zero:
                            # If y is float and is 0 also, return Nan; else
                            # return Inf
                            outltype = context.get_data_type(result_type)
                            shouldretnan = cgutils.is_scalar_zero(builder, x)
                            nan = Constant.real(outltype, float("nan"))
                            inf = Constant.real(outltype, float("inf"))
                            tempres = builder.select(shouldretnan, nan, inf)
                            res = context.cast(builder, tempres, result_type,
                                               tyout.dtype)
                        elif tyout.dtype in types.signed_domain and \
                                not numpy_support.int_divbyzero_returns_zero:
                            res = Constant.int(context.get_data_type(tyout.dtype),
                                               0x1 << (y.type.width-1))
                        else:
                            res = Constant.null(context.get_data_type(tyout.dtype))

                        assert res.type == po.type.pointee, \
                                        (str(res.type), str(po.type.pointee))
                        builder.store(res, po)
                    with orelse:
                        # Normal
                        d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
                        d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
                        tempres = fnwork(builder, [d_x, d_y])
                        res = context.cast(builder, tempres, result_type, tyout.dtype)

                        assert res.type == po.type.pointee, (res.type,
                                                             po.type.pointee)
                        builder.store(res, po)
            else:
                # Handle non-division operations
                d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
                d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
                tempres = fnwork(builder, [d_x, d_y])
                res = context.cast(builder, tempres, result_type, tyout.dtype)

                assert res.type == po.type.pointee, (res.type,
                                                     po.type.pointee)
                builder.store(res, po)

        return out