示例#1
0
def f_fabs(mod):
    '''libc: absolute value of floating-point number'''
    ret = Type.double()
    args = [Type.double()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "fabs")
示例#2
0
def f_pow(mod):
    '''libc: power function'''
    ret = Type.double()
    args = [Type.double(), Type.double()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "pow")
 def CodeGen(self):
     # Make the function type, eg. double(double,double).
     funct_type = Type.function(Type.double(), [Type.double()] * len(self.args), False)
                                                 
     function = Function.new(g_llvm_module, funct_type, self.name)
                                                     
     # If the name conflicted, there was already something with the same name.
     # If it has a body, don't allow redefinition or reextern.
     if function.name != self.name:
         function.delete()
         function = g_llvm_module.get_function_named(self.name)
                                                                 
         # If the function already has a body, reject this.
         if not function.is_declaration:
             raise RuntimeError('Redefinition of function.')
                                                                         
         # If the function took a different number of args, reject.
         if len(function.args) != len(self.args):
             raise RuntimeError('Redeclaration of a function with different number of args.')
                                                                                 
     # Set names for all arguments and add them to the variables symbol table.
     for arg, arg_name in zip(function.args, self.args):
         arg.name = arg_name
                                                                                         
     return function
示例#4
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
示例#5
0
    def CodeGen(self):
        # Make the function type, ex: double(double, double).
        function_type = Type.function(Type.double(),
                                      [Type.double()] * len(self.args), False)

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

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

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

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

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

            return function
示例#6
0
def f_sqrt(mod):
    '''libc: square root function'''
    ret = Type.double()
    args = [Type.double()]

    type_ = Type.function(ret, args)
    return mod.get_or_insert_function(type_, "sqrt")
示例#7
0
def atan2_f64_impl(context, builder, sig, args):
    assert len(args) == 2
    mod = cgutils.get_module(builder)
    fnty = Type.function(Type.double(), [Type.double(), Type.double()])
    # Workaround atan2() issues under Windows
    fname = "atan2_fixed" if sys.platform == "win32" else "atan2"
    fn = mod.get_or_insert_function(fnty, name=fname)
    return builder.call(fn, args)
示例#8
0
def round_impl_f64(context, builder, sig, args):
    module = cgutils.get_module(builder)
    fnty = Type.function(Type.double(), [Type.double()])
    if utils.IS_PY3:
        fn = module.get_or_insert_function(fnty, name="numba.round")
    else:
        fn = module.get_or_insert_function(fnty, name="round")
    assert fn.is_declaration
    return builder.call(fn, args)
示例#9
0
    def _template(self, mattrs):
        mod, func = self._build_test_module()
        ee = self._build_engine(mod, mattrs=mattrs)
        arg = le.GenericValue.real(Type.double(), 1.234)
        retval = ee.run_function(func, [arg])

        golden = math.sin(1.234)
        answer = retval.as_real(Type.double())
        self.assertTrue(abs(answer - golden) / golden < 1e-5)
示例#10
0
 def implementer(context, builder, sig, args):
     [val] = args
     input_type = sig.args[0]
     if input_type.signed:
         fpval = builder.sitofp(val, Type.double())
     else:
         fpval = builder.uitofp(val, Type.double())
     sig = signature(types.float64, types.float64)
     return wrapped_impl(context, builder, sig, [fpval])
示例#11
0
    def _template(self, mattrs):
        mod, func = self._build_test_module()
        ee = self._build_engine(mod, mattrs=mattrs)
        arg = le.GenericValue.real(Type.double(), 1.234)
        retval = ee.run_function(func, [arg])

        golden = math.sin(1.234)
        answer = retval.as_real(Type.double())
        self.assertTrue(abs(answer - golden) / golden < 1e-5)
示例#12
0
文件: builtins.py 项目: genba/numba
def round_impl_f64(context, builder, sig, args):
    module = cgutils.get_module(builder)
    fnty = Type.function(Type.double(), [Type.double()])
    if utils.IS_PY3:
        fn = module.get_or_insert_function(fnty, name="numba.round")
    else:
        fn = module.get_or_insert_function(fnty, name="round")
    assert fn.is_declaration
    return builder.call(fn, args)
示例#13
0
文件: mathimpl.py 项目: genba/numba
 def implementer(context, builder, sig, args):
     [val] = args
     input_type = sig.args[0]
     if input_type.signed:
         fpval = builder.sitofp(val, Type.double())
     else:
         fpval = builder.uitofp(val, Type.double())
     sig = signature(types.float64, types.float64)
     return wrapped_impl(context, builder, sig, [fpval])
示例#14
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)
示例#15
0
    def body(self, x):
        mod = self.function.module

        ret = Type.double()
        args = [Type.double()]
        type_ = Type.function(ret, args)
        func = mod.get_or_insert_function(type_, "round")

        value = self.builder.call(func, [x.value])
        value = CTemp(self, value)

        self.ret(value.cast(Type.int(32)))
示例#16
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)
示例#17
0
文件: cgutils.py 项目: MJJoyce/numba
def is_scalar_zero(builder, value):
    nullval = Constant.null(value.type)
    if value.type in (Type.float(), Type.double()):
        isnull = builder.fcmp(lc.FCMP_OEQ, nullval, value)
    else:
        isnull = builder.icmp(lc.ICMP_EQ, nullval, value)
    return isnull
示例#18
0
    def code(self, context):
        if self.operator == '=':
            if not isinstance(self.left, Variable):
                raise SyntaxError("Destination of '=' must be a variable.")

            value = self.right.code(context)  # RHS code generation
            variable = context.scope[self.left.name]  # Look up the name
            context.builder.store(value, variable)  # Store value, return it
            return value

        left = self.left.code(context)
        right = self.right.code(context)

        if self.operator == '+':
            return context.builder.fadd(left, right, 'addtmp')

        elif self.operator == '-':
            return context.builder.fsub(left, right, 'subtmp')

        elif self.operator == '*':
            return context.builder.fmul(left, right, 'multmp')

        elif self.operator == '<':
            ret = context.builder.fcmp(FCMP_ULT, left, right, 'cmptmp')
            # Convert bool 0 or 1 to double 0.0 or 1.0.
            return context.builder.uitofp(ret, Type.double(), 'booltmp')
        else:
            func = context.module.get_function_named(self.name)
            return context.builder.call(func, [left, right], 'binop')
 def CodeGen(self):
     # A special case for '=' because we don't want to emit the LHS as an # expression.
     if self.operator == '=':
         # Assignment requires the LHS to be an identifier.
         if not isinstance(self.left, VariableExpressionNode):
             raise RuntimeError('Destination of "=" must be a variable.')
                                 
         # Codegen the RHS.
         value = self.right.CodeGen()
                                     
         # Look up the name.
         variable = g_named_values[self.left.name]
                                         
         # Store the value and return it.
         g_llvm_builder.store(value, variable)
                                             
         return value
                                                 
     left = self.left.CodeGen()
     right = self.right.CodeGen()
                                                         
     if self.operator == '+':
         return g_llvm_builder.fadd(left, right, 'addtmp')
     elif self.operator == '-':
         return g_llvm_builder.fsub(left, right, 'subtmp')
     elif self.operator == '*':
         return g_llvm_builder.fmul(left, right, 'multmp')
     elif self.operator == '<':
         result = g_llvm_builder.fcmp(FCMP_ULT, left, right, 'cmptmp')
         # Convert bool 0 or 1 to double 0.0 or 1.0.
         return g_llvm_builder.uitofp(result, Type.double(), 'booltmp')
     else:
         function = g_llvm_module.get_function_named('binary' + self.operator)
         return g_llvm_builder.call(function, [left, right], 'binop')
示例#20
0
文件: toy.py 项目: 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
示例#21
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)
示例#22
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)
示例#23
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
示例#24
0
文件: toy.py 项目: 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)
示例#25
0
    def testValueFromString(self):
        ty = Type.double()
        a = Value.const_real(ty, 1.0)
        b = Value.const_real(ty, "1.0")

        x, _ = a.get_double_value()
        y, _ = b.get_double_value()
        self.assertEqual(x, y)
示例#26
0
    def testValueFromString(self):
        ty = Type.double()
        a = Value.const_real(ty, 1.0)
        b = Value.const_real(ty, "1.0")

        x, _ = a.get_double_value()
        y, _ = b.get_double_value()
        self.assertEqual(x, y)
示例#27
0
文件: cgutils.py 项目: genba/numba
def is_scalar_neg(builder, value):
    """is _value_ negative?. Assumes _value_ is signed"""
    nullval = Constant.null(value.type)
    if value.type in (Type.float(), Type.double()):
        isneg = builder.fcmp(lc.FCMP_OLT, value, nullval)
    else:
        isneg = builder.icmp(lc.ICMP_SLT, value, nullval)
    return isneg
示例#28
0
文件: cgutils.py 项目: genba/numba
def is_scalar_neg(builder, value):
    """is _value_ negative?. Assumes _value_ is signed"""
    nullval = Constant.null(value.type)
    if value.type in (Type.float(), Type.double()):
        isneg = builder.fcmp(lc.FCMP_OLT, value, nullval)
    else:
        isneg = builder.icmp(lc.ICMP_SLT, value, nullval)
    return isneg
示例#29
0
    def code_gen(self):

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

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

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

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

        if method[0] == 'f':
            left = Helper.auto_cast(g_llvm_builder, left, d)
            right = Helper.auto_cast(g_llvm_builder, right, d)
        elif method == 'and_' or method == 'or_':
            if left.type == d or right.type == d:
                raise cmexception.InvalidOperandException(
                    self.operator, str(left.type), str(right.type))
            else:
                if left.type != right.type:
                    left = Helper.auto_cast(g_llvm_builder, left, i32)
                    right = Helper.auto_cast(g_llvm_builder, right, i32)
        else:
            if left.type != right.type:
                left = Helper.auto_cast(g_llvm_builder, left, i32)
                right = Helper.auto_cast(g_llvm_builder, right, i32)
        if op == '<' or op == '>' or op == '<=' or op == '>=' or op == '==' or op == '!=':
            flag = Helper.choose_flag(op, left)
            if g_llvm_builder is None:
                return getattr(left, method)(flag, right)
            else:
                return getattr(g_llvm_builder, method)(flag, left, right)
        else:
            if g_llvm_builder is None:
                return getattr(left, method)(right)
            else:
                return getattr(g_llvm_builder, method)(left, right)
示例#30
0
    def testFAdd(self):
        ty = Type.double()
        a = Value.const_real(ty, 1.0)
        b = Value.const_real(ty, 1.0)
        bldr = Builder.create()
        c = bldr.fadd(a, b, "tmp1")

        x, l = c.get_double_value()
        self.assertTrue(x - 2.0 < 0.01 and 2.0 - x > -0.01)
示例#31
0
    def code_gen(self):

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

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

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

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

        if method[0] == 'f':
            left = Helper.auto_cast(g_llvm_builder, left, d)
            right = Helper.auto_cast(g_llvm_builder, right, d)
        elif method == 'and_' or method == 'or_':
            if left.type == d or right.type == d:
                raise cmexception.InvalidOperandException(self.operator, str(left.type), str(right.type))
            else:
                if left.type != right.type:
                    left = Helper.auto_cast(g_llvm_builder, left, i32)
                    right = Helper.auto_cast(g_llvm_builder, right, i32)
        else:
            if left.type != right.type:
                left = Helper.auto_cast(g_llvm_builder, left, i32)
                right = Helper.auto_cast(g_llvm_builder, right, i32)
        if op == '<' or op == '>' or op == '<=' or op == '>=' or op == '==' or op == '!=':
            flag = Helper.choose_flag(op, left)
            if g_llvm_builder is None:
                return getattr(left, method)(flag, right)
            else:
                return getattr(g_llvm_builder, method)(flag, left, right)
        else:
            if g_llvm_builder is None:
                return getattr(left, method)(right)
            else:
                return getattr(g_llvm_builder, method)(left, right)
示例#32
0
文件: sfpl.py 项目: rigtorp/sfpl
    def gen_code(self, module, builder, variables):
        funct_type = Type.function(Type.double(), [Type.double()] * len(self.args), False)
        function = Function.new(module, funct_type, self.name)

        variables = {}
        for arg, arg_name in zip(function.args, self.args):
            arg.name = arg_name
            variables[arg_name] = arg

        block = function.append_basic_block('entry')

        builder = Builder.new(block)

        return_value = self.body.gen_code(module, builder, variables)
        builder.ret(return_value)

        function.verify()

        return function
示例#33
0
    def testFAdd(self):
        ty = Type.double()
        a = Value.const_real(ty, 1.0)
        b = Value.const_real(ty, 1.0)
        bldr = Builder.create()
        c = bldr.fadd(a, b, "tmp1")

        x, l = c.get_double_value()
        self.assertTrue(x - 2.0 < 0.01 and
                        2.0 - x > -0.01)
示例#34
0
 def get_array_type(typo, length):
     if typo == 'int':
         return Type.array(Type.int(32), length)
     elif typo == 'double':
         return Type.array(Type.double(), length)
     elif typo == 'String':
         ch = Type.int(8)
         return Type.array(Type.pointer(ch), length)
     elif typo == 'char':
         return Type.array(Type.int(8), length)
示例#35
0
    def template(self, iop, fop):
        inttys = [Type.int(32), Type.int(64)]
        flttys = [Type.float(), Type.double()]

        if iop:
            for ty in inttys:
                self.func_template(ty, iop)
        if fop:
            for ty in flttys:
                self.func_template(ty, fop)
示例#36
0
    def template(self, iop, fop):
        inttys = [Type.int(32), Type.int(64)]
        flttys = [Type.float(), Type.double()]

        if iop:
            for ty in inttys:
                self.func_template(ty, iop)
        if fop:
            for ty in flttys:
                self.func_template(ty, fop)
示例#37
0
 def get_array_type(typo, length):
     if typo == 'int':
         return Type.array(Type.int(32), length)
     elif typo == 'double':
         return Type.array(Type.double(), length)
     elif typo == 'String':
         ch = Type.int(8)
         return Type.array(Type.pointer(ch), length)
     elif typo == 'char':
         return Type.array(Type.int(8), length)
示例#38
0
 def choose_method(left, op, right):
     method_table = {
         'i': {'+': 'add', '-': 'sub', '*': 'mul', '/': 'sdiv',
               '%': 'srem', '<<': 'shl', '>>': 'lshr',
               '<': 'icmp', '>': 'icmp', '<=': 'icmp', '>=': 'icmp',
               '==': 'icmp', '!=': 'icmp'
         },
         'f': {'+': 'fadd', '-': 'fsub', '*': 'fmul', '/': 'fdiv',
               '%': 'frem', '<': 'fcmp', '>': 'fcmp', '<=': 'fcmp',
               '>=': 'fcmp', '==': 'fcmp', '!=': 'fcmp'
         }
     }
     if op == '|':
         return 'or_'
     if op == '&':
         return 'and_'
     if left.type == Type.double() or right.type == Type.double():
         return method_table['f'][op]
     return method_table['i'][op]
示例#39
0
文件: kalei.py 项目: NacimKACEL/misc
    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
示例#40
0
 def handle_top_level_expression(self):
     try:
         function = self.parse_top_level_expr().code_gen()
         result = ast.g_llvm_executor.run_function(function, [])
         print('Evaluated to:', result.as_real(Type.double()))
     except Exception, e:
         print('Error:', e)
         try:
             self.next()
         except:
             pass
 def HandleTopLevelExpression(self):
     try:
         function = self.ParseTopLevelExpr().CodeGen()
         result = g_llvm_executor.run_function(function, [])
         print 'Evaluated to:', result.as_real(Type.double())
     except Exception, e:
         raise#print 'Error:', e
         try:
             self.Next()  # Skip for error recovery.
         except:
             pass
示例#42
0
 def get_type(typo):
     if typo == 'int' or typo == LexmeType.Integer:
         return Type.int(32)
     elif typo == 'double' or typo == LexmeType.Double:
         return Type.double()
     elif typo == 'String' or typo == LexmeType.String:
         ch = Type.int(8)
         return Type.pointer(ch)
     elif typo == 'char' or typo == LexmeType.Char:
         return Type.int(8)
     elif typo == 'void':
         return Type.void()
示例#43
0
文件: cgutils.py 项目: genba/numba
def is_scalar_zero(builder, value):
    """
    Return a predicate representing whether *value* is equal to zero.
    """
    assert not is_pointer(value.type)
    assert not is_struct(value.type)
    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
示例#44
0
文件: sfpl.py 项目: 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
示例#45
0
文件: cgutils.py 项目: genba/numba
def is_scalar_zero(builder, value):
    """
    Return a predicate representing whether *value* is equal to zero.
    """
    assert not is_pointer(value.type)
    assert not is_struct(value.type)
    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
示例#46
0
文件: cgutils.py 项目: genba/numba
def is_not_scalar_zero(builder, value):
    """
    Return a predicate representin whether a *value* is not equal to zero.
    not exactly "not is_scalar_zero" because of nans
    """
    assert not is_pointer(value.type)
    assert not is_struct(value.type)
    nullval = Constant.null(value.type)
    if value.type in (Type.float(), Type.double()):
        isnull = builder.fcmp(lc.FCMP_UNE, nullval, value)
    else:
        isnull = builder.icmp(lc.ICMP_NE, nullval, value)
    return isnull
示例#47
0
 def get_type_string(ty):
     i8 = Type.int(8)
     i32 = Type.int(32)
     d = Type.double()
     string = Type.pointer(i8)
     if ty == i8:
         return 'char'
     elif ty == i32:
         return 'int'
     elif ty == d:
         return 'double'
     elif ty == string:
         return 'String'
示例#48
0
 def choose_method(left, op, right):
     method_table = {
         'i': {
             '+': 'add',
             '-': 'sub',
             '*': 'mul',
             '/': 'sdiv',
             '%': 'srem',
             '<<': 'shl',
             '>>': 'lshr',
             '<': 'icmp',
             '>': 'icmp',
             '<=': 'icmp',
             '>=': 'icmp',
             '==': 'icmp',
             '!=': 'icmp'
         },
         'f': {
             '+': 'fadd',
             '-': 'fsub',
             '*': 'fmul',
             '/': 'fdiv',
             '%': 'frem',
             '<': 'fcmp',
             '>': 'fcmp',
             '<=': 'fcmp',
             '>=': 'fcmp',
             '==': 'fcmp',
             '!=': 'fcmp'
         }
     }
     if op == '|':
         return 'or_'
     if op == '&':
         return 'and_'
     if left.type == Type.double() or right.type == Type.double():
         return method_table['f'][op]
     return method_table['i'][op]
示例#49
0
 def force_cast(builder, value, target_type):
     if value.type != target_type:
         d = Type.double()
         i32 = Type.int(32)
         i8 = Type.int(8)
         i1 = Type.int(1)
         if target_type == d:
             if value.type != d:
                 if builder:
                     value = builder.sitofp(value, d)
                 else:
                     value = value.sitofp(d)
         elif target_type == i32:
             if value.type == d:
                 if builder:
                     value = builder.fptosi(value, i32)
                 else:
                     value = value.fptosi(i32)
             elif value.type == i1:
                 if builder:
                     value = builder.zext(value, i32)
                 else:
                     value = value.zext(i32)
             else:
                 if builder:
                     value = builder.sext(value, i32)
                 else:
                     value = value.sext(i32)
         elif target_type == i8:
             if value.type == d:
                 if builder:
                     value = builder.fptrunc(value, i8)
                 else:
                     value = value.fptrunc(i8)
             elif value.type == i32:
                 if builder:
                     value = builder.trunc(value, i8)
                 else:
                     value = value.trunc(i8)
             elif value.type == i1:
                 if builder:
                     value = builder.zext(value, i8)
                 else:
                     value = value.zext(i8)
         elif target_type == Type.pointer(Type.int(8)):
             return None
     return value
示例#50
0
    def __init__(self, context, builder):
        """
        Note: Maybe called multiple times when lowering a function
        """
        fix_python_api()
        self.context = context
        self.builder = builder

        self.module = builder.basic_block.function.module
        # Initialize types
        self.pyobj = self.context.get_argument_type(types.pyobject)
        self.long = Type.int(ctypes.sizeof(ctypes.c_long) * 8)
        self.ulonglong = Type.int(ctypes.sizeof(ctypes.c_ulonglong) * 8)
        self.longlong = self.ulonglong
        self.double = Type.double()
        self.py_ssize_t = self.context.get_value_type(types.intp)
        self.cstring = Type.pointer(Type.int(8))
示例#51
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)
示例#52
0
    def CodeGen(self):
        left = self.left.CodeGen()
        right = self.right.CodeGen()

        # builder.f<operation> is llvm's builtin floating point operations
        # TODO: Lookup the string args at the end of each instruction below
        if self.operator == '+':
            return g_llvm_builder.fadd(left, right, 'addtmp')
        elif self.operator == '-':
            return g_llvm_builder.fsub(left, right, 'subtmp')
        elif self.operator == '*':
            return g_llvm_build.fmul(left, right, 'multmp')
        # This should be changed later on when ints are supported to return 0/1
        elif self.operator == '<':
            result = g_llvm_build.fcmpl(FCMP_ULT, left, right, 'cmptmp')
            # Convert bool 0/1 to 0.0/1.0
            return g_llvm_builder.uitofp(result, Type.double(), 'booltmp')
        else:
            raise RuntimeError('Unknown binary operator.')
示例#53
0
def llvm_type(type):
    ty = type.__class__
    if ty == Boolean:
        return Type.int(1)
    elif ty == Integral:
        return Type.int(type.bits)
    elif type == Float32:
        return Type.float()
    elif type == Float64:
        return Type.double()
    elif ty == Struct:
        return Type.struct([llvm_type(ftype) for ftype in type.types])
    elif ty == Pointer:
        return Type.pointer(llvm_type(type.base))
    elif ty == Function:
        return Type.function(llvm_type(type.restype),
                             [llvm_type(argtype) for argtype in type.argtypes])
    elif ty == Void:
        return Type.void()
    else:
        raise TypeError("Cannot convert type %s" % (type,))
示例#54
0
    def func_template(self, ty, op):
        m = Module.new('dofjaa')
        fnty = Type.function(ty, [ty, ty])
        fn = m.add_function(fnty, 'foo')
        bldr = Builder.new(fn.append_basic_block(''))
        bldr.ret(getattr(bldr, op)(*fn.args))

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

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

        maptypes = {
            Type.int(32): c_uint32,
            Type.int(64): c_uint64,
            Type.float(): c_float,
            Type.double(): c_double,
        }
        cty = maptypes[ty]
        prototype = CFUNCTYPE(*[cty] * 3)
        callee = prototype(ptr)
        callee(12, 23)
示例#55
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
示例#56
0
def llvm_type(type, memo=None):
    if memo is None:
        memo = {}
    if hashable(type) and type in memo:
        return memo[type]

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

    memo[type] = result
    return result
示例#57
0
 def ref_impl(context, builder, sig, args):
     [val] = args
     mod = cgutils.get_module(builder)
     fnty = Type.function(Type.double(), [Type.double()])
     fn = mod.get_or_insert_function(fnty, name=n)
     return builder.call(fn, (val,))
示例#58
0

def pformat_ast(node, include_attrs=False, **kws):
    return pprint.pformat(ast2tree(node, include_attrs), **kws)


def dump(node):
    return pformat_ast(node)


### == LLVM Codegen ==

pointer = Type.pointer
int_type = Type.int()
float_type = Type.float()
double_type = Type.double()
bool_type = Type.int(1)
void_type = Type.void()
void_ptr = pointer(Type.int(8))


def array_type(elt_type):
    return Type.struct(
        [
            pointer(elt_type),  # data
            int_type,  # dimensions
            pointer(int_type),  # shape
        ],
        name='ndarray_' + str(elt_type))

示例#59
0
    types.pyobject: Type.pointer(Type.int(8)),

    types.boolean: Type.int(8),

    types.uint8: Type.int(8),
    types.uint16: Type.int(16),
    types.uint32: Type.int(32),
    types.uint64: Type.int(64),

    types.int8: Type.int(8),
    types.int16: Type.int(16),
    types.int32: Type.int(32),
    types.int64: Type.int(64),

    types.float32: Type.float(),
    types.float64: Type.double(),
}

STRUCT_TYPES = {
    types.complex64: builtins.Complex64,
    types.complex128: builtins.Complex128,
    types.range_state32_type: builtins.RangeState32,
    types.range_iter32_type: builtins.RangeIter32,
    types.range_state64_type: builtins.RangeState64,
    types.range_iter64_type: builtins.RangeIter64,
    types.slice3_type: builtins.Slice,
}

Status = namedtuple("Status", ("code", "ok", "err", "exc", "none"))

RETCODE_OK = Constant.int_signextend(Type.int(), 0)
示例#60
0
# |   };                       |
# | };                         |
# +----------------------------+
#

#------------------------------------------------------------------------
# Definitions
#------------------------------------------------------------------------

void = Type.void()
char = Type.int(8)
short = Type.int(16)
int = Type.int(32)
int64 = Type.int(64)
float = Type.float()
double = Type.double()
int8 = Type.int(8)
int8p = Type.pointer(int8)

# fountain of free variables
free = lambda: iter(letters)


def const(n):
    return Constant.int(int, n)


spine = namedtuple('spine', 'name, params, values')
value = namedtuple('value', 'name, params')

#------------------------------------------------------------------------