Author: David Malcolm <[email protected]> Branch: libgccjit-backend Changeset: r74973:2ae9fa4283cd Date: 2014-12-15 09:57 -0500 http://bitbucket.org/pypy/pypy/changeset/2ae9fa4283cd/
Log: WIP, sent as https://mail.python.org/pipermail/pypy- dev/2014-December/012947.html diff --git a/rpython/jit/backend/detect_cpu.py b/rpython/jit/backend/detect_cpu.py --- a/rpython/jit/backend/detect_cpu.py +++ b/rpython/jit/backend/detect_cpu.py @@ -99,6 +99,9 @@ def getcpuclassname(backend_name="auto"): + # FIXME: + return 'rpython.jit.backend.libgccjit.runner', 'CPU' + if backend_name == "auto": backend_name = autodetect() backend_name = backend_name.replace('_', '-') diff --git a/rpython/jit/backend/libgccjit/__init__.py b/rpython/jit/backend/libgccjit/__init__.py new file mode 100644 diff --git a/rpython/jit/backend/libgccjit/cffi_bindings.py b/rpython/jit/backend/libgccjit/cffi_bindings.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/cffi_bindings.py @@ -0,0 +1,149 @@ +import os +import re +from collections import namedtuple + +# Hacks: +INSTALL_PATH = '/home/david/coding-3/gcc-git-jit-pypy/install' +INCLUDE_DIR = os.path.join(INSTALL_PATH, 'include') +LIB_DIR = os.path.join(INSTALL_PATH, 'lib') +BIN_DIR = os.path.join(INSTALL_PATH, 'bin') + +def append_to_envvar_path(envvar, path): + if envvar in os.environ: + os.environ[envvar] = path + ':' + os.environ[envvar] + else: + os.environ[envvar] = path + print('%s=%s' % (envvar, os.environ[envvar])) + +# It appears that we need to override os.environ['LD_LIBRARY_PATH'] +# before importing cffi for it to take account of this. +append_to_envvar_path('LD_LIBRARY_PATH', LIB_DIR) +# actually, for some reason I get: +# File "/usr/lib64/python2.7/site-packages/cffi/vengine_cpy.py", line 124, in load_library +# raise ffiplatform.VerificationError(error) +# cffi.ffiplatform.VerificationError: importing '/home/david/coding-3/pypy-libgccjit/rpython/jit/backend/libgccjit/__pycache__/_cffi__x5c2f8978xf4274cdc.so': libgccjit.so.0: cannot open shared object file: No such file or directory +# if LD_LIBRARY_PATH isn't set up before python starts up; issue with imp.load_dynamic ? + +# The library requires the correct driver to be in the PATH: +append_to_envvar_path('PATH', BIN_DIR) + +os.system('env') + +import cffi + +ffi = cffi.FFI() + +with open(os.path.join(INCLUDE_DIR, 'libgccjit.h')) as f: + libgccjit_h_content = f.read() + +def toy_preprocessor(content): + """ + ffi.cdef can't handle preprocessor directives. + We only have the idempotency guards and ifdef __cplusplus; + strip them out. + """ + State = namedtuple('State', ('line', 'accepting_text')) + macros = {} + result = [] # list of lines + states = [State('default', accepting_text=True)] + for line in content.splitlines(): + if 0: + print(repr(line)) + + m = re.match('#ifndef\s+(\S+)', line) + if m: + states.append(State(line, + accepting_text=(m.group(1) not in macros)) ) + continue + m = re.match('#ifdef\s+(\S+)', line) + + if m: + states.append(State(line, + accepting_text=(m.group(1) in macros)) ) + continue + + m = re.match('#define\s+(\S+)', line) + if m: + macros[m.group(1)] = '' + continue + + m = re.match('#endif\s*', line) + if m: + states.pop() + continue + + if states[-1].accepting_text: + result.append(line) + + return '\n'.join(result) + +libgccjit_h_content = toy_preprocessor(libgccjit_h_content) + +# print(libgccjit_h_content) + +ffi.cdef(libgccjit_h_content) + +lib = ffi.verify('#include "libgccjit.h"', + libraries=['gccjit'], + library_dirs=[LIB_DIR], + include_dirs=[INCLUDE_DIR]) + +ctxt = lib.gcc_jit_context_acquire() +print ctxt + +lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + 1) +lib.gcc_jit_context_set_int_option(ctxt, + lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + 3) +lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + 1) +lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + 1) +lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 1) + +int_type = lib.gcc_jit_context_get_type(ctxt, lib.GCC_JIT_TYPE_INT) +param = lib.gcc_jit_context_new_param(ctxt, ffi.NULL, int_type, "input") +fn = lib.gcc_jit_context_new_function(ctxt, + ffi.NULL, + lib.GCC_JIT_FUNCTION_EXPORTED, + int_type, + "add_one_to", + 1, [param], 0) +v_res = lib.gcc_jit_function_new_local(fn, ffi.NULL, int_type, "v_res") + +b_initial = lib.gcc_jit_function_new_block(fn, "initial") + +c_one = lib.gcc_jit_context_new_rvalue_from_int(ctxt, int_type, 1) + +op_add = lib.gcc_jit_context_new_binary_op(ctxt, ffi.NULL, + lib.GCC_JIT_BINARY_OP_PLUS, + int_type, + lib.gcc_jit_param_as_rvalue(param), + c_one) +lib.gcc_jit_block_add_assignment(b_initial, ffi.NULL, + v_res, + op_add) + +lib.gcc_jit_block_end_with_return(b_initial, ffi.NULL, + lib.gcc_jit_lvalue_as_rvalue(v_res)) + +jit_result = lib.gcc_jit_context_compile(ctxt) + +lib.gcc_jit_context_release(ctxt) + +fn_ptr = lib.gcc_jit_result_get_code(jit_result, "add_one_to") +if not fn_ptr: + raise Exception("fn_ptr is NULL") +print('fn_ptr: %r' % fn_ptr) + +fn_result = ffi.cast("int(*)(int)", fn_ptr)(41) +print('fn_result: %r' % fn_result) +assert fn_result == 42 + +lib.gcc_jit_result_release(jit_result) diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -0,0 +1,249 @@ +import os + +# Hacks: +INSTALL_PATH = '/home/david/coding-3/gcc-git-jit-pypy/install' +INCLUDE_DIR = os.path.join(INSTALL_PATH, 'include') +LIB_DIR = os.path.join(INSTALL_PATH, 'lib') +BIN_DIR = os.path.join(INSTALL_PATH, 'bin') + +def append_to_envvar_path(envvar, path): + if envvar in os.environ: + os.environ[envvar] = path + ':' + os.environ[envvar] + else: + os.environ[envvar] = path + print('%s=%s' % (envvar, os.environ[envvar])) + +# It appears that we need to override os.environ['LD_LIBRARY_PATH'] +# before importing cffi for it to take account of this. +append_to_envvar_path('LD_LIBRARY_PATH', LIB_DIR) +# actually, for some reason I get: +# File "/usr/lib64/python2.7/site-packages/cffi/vengine_cpy.py", line 124, in load_library +# raise ffiplatform.VerificationError(error) +# cffi.ffiplatform.VerificationError: importing '/home/david/coding-3/pypy-libgccjit/rpython/jit/backend/libgccjit/__pycache__/_cffi__x5c2f8978xf4274cdc.so': libgccjit.so.0: cannot open shared object file: No such file or directory +# if LD_LIBRARY_PATH isn't set up before python starts up; issue with imp.load_dynamic ? + +# The library requires the correct driver to be in the PATH: +append_to_envvar_path('PATH', BIN_DIR) + +from rpython.rtyper.lltypesystem import rffi +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.lltypesystem.rffi import * +from rpython.rtyper.lltypesystem import lltype + +def make_eci(): + eci = ExternalCompilationInfo(includes=['libgccjit.h'], + include_dirs=[INCLUDE_DIR], + libraries=['gccjit'], + library_dirs=[LIB_DIR]) + return eci + +class Library: + def __init__(self, eci): + self.eci = eci + + # Opaque types: + self.GCC_JIT_CONTEXT_P = lltype.Ptr(COpaque(name='gcc_jit_context', + compilation_info=eci)) + self.GCC_JIT_RESULT_P = lltype.Ptr(COpaque(name='gcc_jit_result', + compilation_info=eci)) + self.GCC_JIT_TYPE_P = lltype.Ptr(COpaque(name='gcc_jit_type', + compilation_info=eci)) + self.GCC_JIT_LOCATION_P = lltype.Ptr(COpaque(name='gcc_jit_location', + compilation_info=eci)) + self.GCC_JIT_PARAM_P = lltype.Ptr(COpaque(name='gcc_jit_param', + compilation_info=eci)) + self.GCC_JIT_LVALUE_P = lltype.Ptr(COpaque(name='gcc_jit_lvalue', + compilation_info=eci)) + self.GCC_JIT_RVALUE_P = lltype.Ptr(COpaque(name='gcc_jit_rvalue', + compilation_info=eci)) + self.GCC_JIT_FUNCTION_P = lltype.Ptr(COpaque(name='gcc_jit_function', + compilation_info=eci)) + self.GCC_JIT_BLOCK_P = lltype.Ptr(COpaque(name='gcc_jit_block', + compilation_info=eci)) + + self.PARAM_P_P = lltype.Ptr(lltype.Array(self.GCC_JIT_PARAM_P, + hints={'nolength': True})) + + # Entrypoints: + for returntype, name, paramtypes in [ + (self.GCC_JIT_CONTEXT_P, + 'gcc_jit_context_acquire', []), + + (lltype.Void, + 'gcc_jit_context_release', [self.GCC_JIT_CONTEXT_P]), + + (lltype.Void, + 'gcc_jit_context_set_int_option', [self.GCC_JIT_CONTEXT_P, + INT, # FIXME: enum gcc_jit_int_option opt, + INT]), + (lltype.Void, + 'gcc_jit_context_set_bool_option', [self.GCC_JIT_CONTEXT_P, + INT, # FIXME: enum gcc_jit_bool_option opt, + INT]), + + (self.GCC_JIT_RESULT_P, + 'gcc_jit_context_compile', [self.GCC_JIT_CONTEXT_P]), + + + (VOIDP, + 'gcc_jit_result_get_code', [self.GCC_JIT_RESULT_P, + CCHARP]), + + (lltype.Void, + 'gcc_jit_result_release', [self.GCC_JIT_RESULT_P]), + + ############################################################ + # Types + ############################################################ + (self.GCC_JIT_TYPE_P, + 'gcc_jit_context_get_type', [self.GCC_JIT_CONTEXT_P, + INT]), + + ############################################################ + # Constructing functions. + ############################################################ + (self.GCC_JIT_PARAM_P, + 'gcc_jit_context_new_param', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_TYPE_P, + CCHARP]), + (self.GCC_JIT_LVALUE_P, + 'gcc_jit_param_as_lvalue', [self.GCC_JIT_PARAM_P]), + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_param_as_rvalue', [self.GCC_JIT_PARAM_P]), + + (self.GCC_JIT_FUNCTION_P, + 'gcc_jit_context_new_function', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + INT, # enum gcc_jit_function_kind kind, + self.GCC_JIT_TYPE_P, + CCHARP, + INT, + self.PARAM_P_P, + INT]), + (self.GCC_JIT_LVALUE_P, + 'gcc_jit_function_new_local', [self.GCC_JIT_FUNCTION_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_TYPE_P, + CCHARP]), + + (self.GCC_JIT_BLOCK_P, + 'gcc_jit_function_new_block', [self.GCC_JIT_FUNCTION_P, + CCHARP]), + + ############################################################ + # lvalues, rvalues and expressions. + ############################################################ + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_lvalue_as_rvalue', [self.GCC_JIT_LVALUE_P]), + + # Integer constants. + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_new_rvalue_from_int', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P, + INT]), + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_zero', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P]), + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_one', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P]), + + (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_new_binary_op', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + INT, # enum gcc_jit_binary_op op, + self.GCC_JIT_TYPE_P, + self.GCC_JIT_RVALUE_P, + self.GCC_JIT_RVALUE_P]), + + ############################################################ + # Statement-creation. + ############################################################ + (lltype.Void, + 'gcc_jit_block_add_assignment', [self.GCC_JIT_BLOCK_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_LVALUE_P, + self.GCC_JIT_RVALUE_P]), + (lltype.Void, + 'gcc_jit_block_end_with_return', [self.GCC_JIT_BLOCK_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_RVALUE_P]), + ]: + self.add_entrypoint(returntype, name, paramtypes) + + # Enum values: + self.make_enum_values("""GCC_JIT_STR_OPTION_PROGNAME""") + + self.make_enum_values("""GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL""") + + self.make_enum_values("""GCC_JIT_BOOL_OPTION_DEBUGINFO, + GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, + GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, + GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + GCC_JIT_BOOL_OPTION_SELFCHECK_GC, + GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + """) + + self.make_enum_values("""GCC_JIT_TYPE_VOID, + GCC_JIT_TYPE_VOID_PTR, + GCC_JIT_TYPE_BOOL, + GCC_JIT_TYPE_CHAR, + GCC_JIT_TYPE_SIGNED_CHAR, + GCC_JIT_TYPE_UNSIGNED_CHAR, + GCC_JIT_TYPE_SHORT, + GCC_JIT_TYPE_UNSIGNED_SHORT, + GCC_JIT_TYPE_INT, + GCC_JIT_TYPE_UNSIGNED_INT, + GCC_JIT_TYPE_LONG, + GCC_JIT_TYPE_UNSIGNED_LONG, + GCC_JIT_TYPE_LONG_LONG, + GCC_JIT_TYPE_UNSIGNED_LONG_LONG, + GCC_JIT_TYPE_FLOAT, + GCC_JIT_TYPE_DOUBLE, + GCC_JIT_TYPE_LONG_DOUBLE, + GCC_JIT_TYPE_CONST_CHAR_PTR, + GCC_JIT_TYPE_SIZE_T, + GCC_JIT_TYPE_FILE_PTR, + GCC_JIT_TYPE_COMPLEX_FLOAT, + GCC_JIT_TYPE_COMPLEX_DOUBLE, + GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE""") + + self.make_enum_values("""GCC_JIT_FUNCTION_EXPORTED, + GCC_JIT_FUNCTION_INTERNAL, + GCC_JIT_FUNCTION_IMPORTED, + GCC_JIT_FUNCTION_ALWAYS_INLINE""") + + self.make_enum_values( + """ + GCC_JIT_BINARY_OP_PLUS, + GCC_JIT_BINARY_OP_MINUS, + GCC_JIT_BINARY_OP_MULT, + GCC_JIT_BINARY_OP_DIVIDE, + GCC_JIT_BINARY_OP_MODULO, + GCC_JIT_BINARY_OP_BITWISE_AND, + GCC_JIT_BINARY_OP_BITWISE_XOR, + GCC_JIT_BINARY_OP_BITWISE_OR, + GCC_JIT_BINARY_OP_LOGICAL_AND, + GCC_JIT_BINARY_OP_LOGICAL_OR, + GCC_JIT_BINARY_OP_LSHIFT, + GCC_JIT_BINARY_OP_RSHIFT + """) + + self.null_location_ptr = lltype.nullptr(self.GCC_JIT_LOCATION_P.TO) + + + def add_entrypoint(self, returntype, name, paramtypes): + setattr(self, name, + llexternal(name, paramtypes, returntype, + compilation_info=self.eci)) + + def make_enum_values(self, lines): + for value, name in enumerate(lines.split(',')): + name = name.strip() + if name: + setattr(self, name, value) + + diff --git a/rpython/jit/backend/libgccjit/runner.py b/rpython/jit/backend/libgccjit/runner.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/runner.py @@ -0,0 +1,32 @@ +#from rpython.jit.backend import model +from rpython.jit.backend.libgccjit.assembler import AssemblerLibgccjit +from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU + +#class CPU(model.AbstractCPU): +class CPU(AbstractLLCPU): + def __init__(self, rtyper, stats, opts=None, translate_support_code=False, + gcdescr=None): + AbstractLLCPU.__init__(self, rtyper, stats, opts, + translate_support_code, gcdescr) + + def setup(self): + self.assembler = AssemblerLibgccjit(self) + + def compile_loop(self, inputargs, operations, looptoken, + log=True, name='', logger=None): + import sys + sys.stderr.write('compile_loop:\n') + for i, arg in enumerate(inputargs): + sys.stderr.write(' arg[%i] = %r\n' % (i, arg)) + sys.stderr.write(' type(arg[%i]) = %r\n' % (i, type(arg))) + for i, op in enumerate(operations): + sys.stderr.write(' op[%i] = %r\n' % (i, op)) + sys.stderr.write(' type(op[%i]) = %r\n' % (i, type(op))) + sys.stderr.write(' looptoken: %r\n' % (looptoken, )) + sys.stderr.write(' log: %r\n' % (log, )) + sys.stderr.write(' name: %r\n' % (name, )) + sys.stderr.write(' logger: %r\n' % (logger, )) + sys.stderr.write('compile_loop: %r\n' % locals ()) + #raise NotImplementedError + return self.assembler.assemble_loop(inputargs, operations, looptoken, log, + name, logger) diff --git a/rpython/jit/backend/libgccjit/test/__init__.py b/rpython/jit/backend/libgccjit/test/__init__.py new file mode 100644 diff --git a/rpython/jit/backend/libgccjit/test/test_basic.py b/rpython/jit/backend/libgccjit/test/test_basic.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/test/test_basic.py @@ -0,0 +1,15 @@ +import py +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.metainterp.test import support, test_ajit + +class JitLibgccjitMixin(support.LLJitMixin): + type_system = 'lltype' + CPUClass = getcpuclass() + + def check_jumps(self, maxcount): + pass + +class TestBasic(JitLibgccjitMixin, test_ajit.BaseLLtypeTests): + # for the individual tests see + # ====> ../../../metainterp/test/test_basic.py + pass diff --git a/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py b/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py @@ -0,0 +1,160 @@ + +import py +import sys +from rpython.rtyper.lltypesystem.rffi import * +from rpython.rtyper.lltypesystem.rffi import _keeper_for_type # crap +from rpython.rlib.rposix import get_errno, set_errno +from rpython.translator.c.test.test_genc import compile as compile_c +from rpython.rtyper.lltypesystem.lltype import Signed, Ptr, Char, malloc +from rpython.rtyper.lltypesystem import lltype +from rpython.translator import cdir +from rpython.tool.udir import udir +from rpython.rtyper.test.test_llinterp import interpret +from rpython.annotator.annrpython import RPythonAnnotator +from rpython.rtyper.rtyper import RPythonTyper +from rpython.translator.backendopt.all import backend_optimizations +from rpython.translator.translator import graphof +from rpython.conftest import option +from rpython.flowspace.model import summary +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rlib.rarithmetic import r_singlefloat + +""" +def test_string(): + eci = ExternalCompilationInfo(includes=['string.h']) + z = llexternal('strlen', [CCHARP], Signed, compilation_info=eci) + + def f(): + s = str2charp("xxx") + res = z(s) + free_charp(s) + return res + + xf = compile_c(f, [], backendopt=False) + assert xf() == 3 +""" + +from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library + +def test_compile_empty_context(): + eci = make_eci() + + lib = Library(eci) + + def f(): + ctxt = lib.gcc_jit_context_acquire() + result = lib.gcc_jit_context_compile(ctxt) + lib.gcc_jit_context_release(ctxt) + lib.gcc_jit_result_release(result) + + f1 = compile_c(f, [], backendopt=False) + f1 () + #assert False # to see stderr + +def make_param_array(lib, l): + array = lltype.malloc(lib.PARAM_P_P.TO, + len(l), + flavor='raw') # of maybe gc? + for i in range(len(l)): + array[i] = l[i] + return array + # FIXME: don't leak! + +def test_compile_add_one_to(): + eci = make_eci() + + lib = Library(eci) + + ft = lltype.FuncType([INT], INT)#, abi="C") + ftp = lltype.Ptr(ft) + + def f(): + ctxt = lib.gcc_jit_context_acquire() + + lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + 1) + lib.gcc_jit_context_set_int_option(ctxt, + lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + 3) + lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + 1) + lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + 1) + lib.gcc_jit_context_set_bool_option(ctxt, + lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + 1) + t_int = lib.gcc_jit_context_get_type(ctxt, lib.GCC_JIT_TYPE_INT) + param = lib.gcc_jit_context_new_param(ctxt, + lib.null_location_ptr, + t_int, + "input") + # FIXME: how to build an array of params at this level? + # see liststr2charpp in rffi.py + + param_array = make_param_array(lib, [param]) + fn = lib.gcc_jit_context_new_function(ctxt, + lib.null_location_ptr, + lib.GCC_JIT_FUNCTION_EXPORTED, + t_int, + "add_one_to", + 1, param_array, 0) + lltype.free(param_array, flavor='raw') + + v_res = lib.gcc_jit_function_new_local(fn, + lib.null_location_ptr, + t_int, + "v_res") + b_initial = lib.gcc_jit_function_new_block(fn, "initial") + c_one = lib.gcc_jit_context_new_rvalue_from_int(ctxt, t_int, 1) + op_add = lib.gcc_jit_context_new_binary_op(ctxt, + lib.null_location_ptr, + lib.GCC_JIT_BINARY_OP_PLUS, + t_int, + lib.gcc_jit_param_as_rvalue(param), + c_one) + lib.gcc_jit_block_add_assignment(b_initial, lib.null_location_ptr, + v_res, + op_add) + lib.gcc_jit_block_end_with_return(b_initial, lib.null_location_ptr, + lib.gcc_jit_lvalue_as_rvalue(v_res)) + + jit_result = lib.gcc_jit_context_compile(ctxt) + lib.gcc_jit_context_release(ctxt) + if not jit_result: + # FIXME: get error from context + raise Exception("jit_result is NULL") + + fn_ptr = lib.gcc_jit_result_get_code(jit_result, "add_one_to") + if not fn_ptr: + raise Exception("fn_ptr is NULL") + print('fn_ptr: %s' % fn_ptr) + + #ft = lltype.FuncType([INT], INT)#, abi="C") + # looks like we can't build a FuncType inside RPython + # but we can use one built outside: + print(ft) + print(ftp) + + typed_fn_ptr = cast(ftp, fn_ptr) + print(typed_fn_ptr) + fn_result = typed_fn_ptr (r_int(41)) + #print('fn_result: %d' % fn_result) + #assert fn_result == r_int(42) + + # and it looks like we can't create a functionptr from this + # FuncType: + #funcptr = lltype.functionptr(ft) + + lib.gcc_jit_result_release(jit_result) + + return int(fn_result) + + f1 = compile_c(f, [], backendopt=False) + assert f1() == 42 + #assert False # to see stderr + +# TODO: test of an error +# should turn it into an exception, and capture the error _______________________________________________ pypy-commit mailing list [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
