def _gen_Abs(self, args, ret_type): if len(args) != 1: raise CompileError() arg = args[0] if ret_type == int_type: # FIXME better way to do this? neg_arg = self.builder.mul(arg, int_type(-1)) cond = self.builder.icmp_signed('<', arg, int_type(0)) return self.builder.select(cond, neg_arg, arg) elif ret_type == real_type: return self.call_fp_intr('llvm.fabs', args)
def _gen_ir(self, expr): ''' walks an expression tree and constructs the ir block ''' if isinstance(expr, Symbol): try: arg = self.lookup_args[expr.get_name()] except KeyError: raise CompileError() return arg elif isinstance(expr, Integer): return int_type(expr.get_int_value()) elif isinstance(expr, Real): return real_type(expr.round_to_float()) elif not isinstance(expr, Expression): raise CompileError() head_name = expr.get_head_name() if head_name.startswith('System`'): head_name = head_name[7:] method = getattr(self, '_gen_' + head_name, None) else: method = None if method is None: raise CompileError() return method(expr)
def add_caller(self, py_f, ret_type, args): ''' Inserts a caller to a python function ''' # see http://eli.thegreenplace.net/2015/calling-back-into-python-from-llvmlite-jited-code/ c_func_type = ctypes.CFUNCTYPE( llvm_to_ctype(ret_type), *(llvm_to_ctype(arg.type) for arg in args)) c_func = c_func_type(py_f) c_func_addr = ctypes.cast(c_func, ctypes.c_void_p).value addrcaller_func_type = ir.FunctionType(ret_type, [arg.type for arg in args]) cb_func_ptr_type = addrcaller_func_type.as_pointer() f = self.builder.inttoptr(int_type(c_func_addr), cb_func_ptr_type, name='f') call = self.builder.call(f, args) if call.type == void_type: return self.builder.ret_void() return call
def int_to_bool(self, arg): assert arg.type == int_type # any non-zero int is true return self.builder.icmp_signed('!=', arg, int_type(0))