[pypy-commit] pypy libgccjit-backend: Work-in-progress
Author: David Malcolm Branch: libgccjit-backend Changeset: r74979:cf027885030b Date: 2014-12-16 10:12 -0500 http://bitbucket.org/pypy/pypy/changeset/cf027885030b/ Log:Work-in-progress diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -1,8 +1,14 @@ +from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.llsupport.assembler import BaseAssembler +from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.llsupport.regalloc import FrameManager from rpython.jit.backend.model import CompiledLoopToken -from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array +from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type from rpython.jit.metainterp.history import BoxInt, ConstInt +from rpython.jit.metainterp.resoperation import * +from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr from rpython.rtyper.lltypesystem.rffi import * +from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory class AssemblerLibgccjit(BaseAssembler): _regalloc = None @@ -30,29 +36,36 @@ self.num_anon_loops = 0 self.make_context() -print(self.ctxt) -self.t_int = self.lib.gcc_jit_context_get_type(self.ctxt, - self.lib.GCC_JIT_TYPE_INT) +self.t_int = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_INT) +self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) def make_context(self): eci = make_eci() self.lib = Library(eci) -self.ctxt = self.lib.gcc_jit_context_acquire() -self.lib.gcc_jit_context_set_bool_option(self.ctxt, - self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, -r_int(1)) -self.lib.gcc_jit_context_set_int_option(self.ctxt, - self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - r_int(3)) -self.lib.gcc_jit_context_set_bool_option(self.ctxt, - self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, -r_int(1)) -self.lib.gcc_jit_context_set_bool_option(self.ctxt, - self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, -r_int(1)) -self.lib.gcc_jit_context_set_bool_option(self.ctxt, - self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, -r_int(1)) +self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + r_int(1)) +self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, + r_int(1)) + self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + r_int(3)) + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + r_int(1)) +self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + r_int(1)) + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + r_int(1)) + +def setup(self, looptoken): +allblocks = self.get_asmmemmgr_blocks(looptoken) +self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, +allblocks) + +def get_asmmemmgr_blocks(self, looptoken): +clt = looptoken.compiled_loop_token +if clt.asmmemmgr_blocks is None: +clt.asmmemmgr_blocks = [] +return clt.asmmemmgr_blocks def assemble_loop(self, inputargs, operations, looptoken, log, loopname, logger): @@ -62,10 +75,94 @@ looptoken.compiled_loop_token = clt clt._debug_nbargs = len(inputargs) +self.setup(looptoken) + +frame_info = self.datablockwrapper.malloc_aligned( +jitframe.JITFRAMEINFO_SIZE, alignment=64) #WORD) +clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) +clt.allgcrefs = [] +clt.frame_info.clear() # for now + +self.lvalue_for_box = {} + +print(jitframe.JITFRAME) +print(dir(jitframe.JITFRAME)) +print('jitframe.JITFRAME._flds: %r' % jitframe.JITFRAME._flds) + +# For now, build a "struct jit_frame
[pypy-commit] pypy libgccjit-backend: WIP, sent as https://mail.python.org/pipermail/pypy-dev/2014-December/012947.html
Author: David Malcolm 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, +
[pypy-commit] pypy libgccjit-backend: Get test_compile_linear_loop working
Author: David Malcolm Branch: libgccjit-backend Changeset: r74980:0b696e11a782 Date: 2014-12-16 11:39 -0500 http://bitbucket.org/pypy/pypy/changeset/0b696e11a782/ Log:Get test_compile_linear_loop working I see occasional glibc reports about corrupt heap on exit diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -36,25 +36,28 @@ self.num_anon_loops = 0 self.make_context() -self.t_int = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_INT) +self.t_long = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_LONG) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) def make_context(self): eci = make_eci() self.lib = Library(eci) self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, - r_int(1)) +if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, + r_int(1)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, r_int(1)) - self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - r_int(3)) +if 1: + self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + r_int(3)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, r_int(1)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, r_int(1)) - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, - r_int(1)) +if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, + r_int(1)) def setup(self, looptoken): allblocks = self.get_asmmemmgr_blocks(looptoken) @@ -90,25 +93,17 @@ print('jitframe.JITFRAME._flds: %r' % jitframe.JITFRAME._flds) # For now, build a "struct jit_frame". -# This will have the fields of jitframe, but instead of -# jf_frame, we'll have any input and output boxes: -visible_boxes = [] -for arg in inputargs: -visible_boxes.append(arg) -for op in operations: -if op.getopname() == 'finish': -for arg in op._args: -if arg not in visible_boxes: -visible_boxes.append(arg) -print('visible_boxes: %r' % visible_boxes) +# This will have the fields of jitframe, +# We'll construct numbered arg0..argN for use +# for inputargs and the outputs fields = [] def make_field(name, jit_type): field = self.ctxt.new_field(jit_type,name) fields.append(field) return field -make_field('jfi_frame_depth', self.t_int) -make_field('jfi_frame_size', self.t_int) +make_field('jfi_frame_depth', self.t_long) +make_field('jfi_frame_size', self.t_long) t_JITFRAMEINFO = ( self.ctxt.new_struct_type ("JITFRAMEINFO", @@ -122,25 +117,36 @@ fields = [] # FIXME: Does the GCStruct implicitly add any fields? -# If I put this here, then the arguments appear to be written to the -# place where I expect: -make_field('hack_rtti', self.t_void_ptr) +# If I omit this, then the jf_* fields appears in the same +# place in llmodel.py's get_latest_descr deadframe as +# in my generated code as seen in gdb. +#make_field('hack_rtti', self.t_void_ptr) make_field('jf_frame_info', t_JITFRAMEINFOPTR) self.field_jf_descr = make_field('jf_descr', self.t_void_ptr) make_field('jf_force_descr', self.t_void_ptr) make_field('jf_gcmap', self.t_void_ptr) -make_field('jf_extra_stack_depth', self.t_int) +make_field('jf_extra_stack_depth', self.t_long) make_field('jf_savedata', self.t_void_ptr) make_field('jf_guard_exc', self.t_void_ptr) make_field('jf_forward', t_jit_frame_ptr) -# jf_frame: -self.field_for_box = {} +# FIXME: for some reason there's an implicit word here; +# create it +make_field('jf_frame', self.t_long) + locs = [] #loc = jitframe.getofs('jf_frame') -for loc, box in enumerate(visible_boxes): -field = make_field(str(box), self.t_int) -locs.append(loc) # hack! -self.field_for_box[box] = field + +max_args = len(inputargs) +
[pypy-commit] pypy libgccjit-backend: Experimental libgccjit backend
Author: David Malcolm Branch: libgccjit-backend Changeset: r74972:3096e72141bd Date: 2014-12-17 11:37 -0500 http://bitbucket.org/pypy/pypy/changeset/3096e72141bd/ Log:Experimental libgccjit backend ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Set _nowrapper=True when creating rffi bindings for libgccjit
Author: David Malcolm Branch: libgccjit-backend Changeset: r74974:52abcc39fd47 Date: 2014-12-15 11:10 -0500 http://bitbucket.org/pypy/pypy/changeset/52abcc39fd47/ Log:Set _nowrapper=True when creating rffi bindings for libgccjit diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -238,12 +238,13 @@ def add_entrypoint(self, returntype, name, paramtypes): setattr(self, name, llexternal(name, paramtypes, returntype, - compilation_info=self.eci)) + compilation_info=self.eci, + _nowrapper=True)) def make_enum_values(self, lines): for value, name in enumerate(lines.split(',')): name = name.strip() if name: -setattr(self, name, value) +setattr(self, name, r_int(value)) diff --git a/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py b/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py --- a/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/test/test_rffi_bindings.py @@ -73,42 +73,50 @@ lib.gcc_jit_context_set_bool_option(ctxt, lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, -1) +r_int(1)) lib.gcc_jit_context_set_int_option(ctxt, lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - 3) + r_int(3)) lib.gcc_jit_context_set_bool_option(ctxt, lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, -1) +r_int(1)) lib.gcc_jit_context_set_bool_option(ctxt, lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, -1) +r_int(1)) lib.gcc_jit_context_set_bool_option(ctxt, lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, -1) +r_int(1)) t_int = lib.gcc_jit_context_get_type(ctxt, lib.GCC_JIT_TYPE_INT) +param_name = str2charp("input") param = lib.gcc_jit_context_new_param(ctxt, lib.null_location_ptr, t_int, - "input") + param_name) +free_charp(param_name) # FIXME: how to build an array of params at this level? # see liststr2charpp in rffi.py +fn_name = str2charp("add_one_to") 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) + fn_name, + r_int(1), param_array, r_int(0)) lltype.free(param_array, flavor='raw') +free_charp(fn_name) +local_name = str2charp("v_res") 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) + local_name) +free_charp(local_name) +block_name = str2charp("initial") +b_initial = lib.gcc_jit_function_new_block(fn, block_name) +free_charp(block_name) +c_one = lib.gcc_jit_context_new_rvalue_from_int(ctxt, t_int, r_int(1)) op_add = lib.gcc_jit_context_new_binary_op(ctxt, lib.null_location_ptr, lib.GCC_JIT_BINARY_OP_PLUS, @@ -127,7 +135,9 @@ # FIXME: get error from context raise Exception("jit_result is NULL") -fn_ptr = lib.gcc_jit_result_get_code(jit_result, "add_one_to") +fn_name = str2charp("add_one_to") +fn_ptr = lib.gcc_jit_result_get_
[pypy-commit] pypy libgccjit-backend: Implement an OO-style rffi wrapper to libgccjit
Author: David Malcolm Branch: libgccjit-backend Changeset: r74978:947cc4471f74 Date: 2014-12-16 06:46 -0500 http://bitbucket.org/pypy/pypy/changeset/947cc4471f74/ Log:Implement an OO-style rffi wrapper to libgccjit diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -46,6 +46,15 @@ return array # FIXME: don't leak! +def make_field_array(lib, l): +array = lltype.malloc(lib.FIELD_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! + class Library: def __init__(self, eci): self.eci = eci @@ -57,6 +66,10 @@ compilation_info=eci)) self.GCC_JIT_TYPE_P = lltype.Ptr(COpaque(name='gcc_jit_type', compilation_info=eci)) +self.GCC_JIT_FIELD_P = lltype.Ptr(COpaque(name='gcc_jit_field', + compilation_info=eci)) +self.GCC_JIT_STRUCT_P = lltype.Ptr(COpaque(name='gcc_jit_struct', + 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', @@ -70,6 +83,8 @@ self.GCC_JIT_BLOCK_P = lltype.Ptr(COpaque(name='gcc_jit_block', compilation_info=eci)) +self.FIELD_P_P = lltype.Ptr(lltype.Array(self.GCC_JIT_FIELD_P, + hints={'nolength': True})) self.PARAM_P_P = lltype.Ptr(lltype.Array(self.GCC_JIT_PARAM_P, hints={'nolength': True})) @@ -94,6 +109,11 @@ 'gcc_jit_context_compile', [self.GCC_JIT_CONTEXT_P]), +(lltype.Void, + 'gcc_jit_context_dump_to_file', [self.GCC_JIT_CONTEXT_P, + CCHARP, + INT]), + (VOIDP, 'gcc_jit_result_get_code', [self.GCC_JIT_RESULT_P, CCHARP]), @@ -108,6 +128,34 @@ 'gcc_jit_context_get_type', [self.GCC_JIT_CONTEXT_P, INT]), +(self.GCC_JIT_TYPE_P, + 'gcc_jit_type_get_pointer', [self.GCC_JIT_TYPE_P]), + +(self.GCC_JIT_FIELD_P, + 'gcc_jit_context_new_field', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_TYPE_P, + CCHARP]), +(self.GCC_JIT_STRUCT_P, + 'gcc_jit_context_new_struct_type', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + CCHARP, + INT, + self.FIELD_P_P]), + +(self.GCC_JIT_STRUCT_P, + 'gcc_jit_context_new_opaque_struct', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_LOCATION_P, + CCHARP]), +(self.GCC_JIT_TYPE_P, + 'gcc_jit_struct_as_type', [self.GCC_JIT_STRUCT_P]), + +(lltype.Void, + 'gcc_jit_struct_set_fields', [self.GCC_JIT_STRUCT_P, + self.GCC_JIT_LOCATION_P, + INT, + self.FIELD_P_P]), + # Constructing functions. @@ -159,6 +207,11 @@ self.GCC_JIT_TYPE_P]), (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_new_rvalue_from_ptr', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P, + VOIDP]), + +(self.GCC_JIT_RVALUE_P, 'gcc_jit_context_new_binary_op', [self.GCC_JIT_CONTEXT_P, self.GCC_JIT_LOCATION_P, INT, # enu
[pypy-commit] pypy libgccjit-backend: Add initial comment to IR. WIP on emit methods
Author: David Malcolm Branch: libgccjit-backend Changeset: r74981:f58bfe1daf4d Date: 2014-12-16 11:49 -0500 http://bitbucket.org/pypy/pypy/changeset/f58bfe1daf4d/ Log:Add initial comment to IR. WIP on emit methods diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -173,6 +173,16 @@ self.b_current = self.fn.new_block() +# Add an initial comment summarizing the loop +text = '\n\tinputargs: %s\n\n' % inputargs +for op in operations: +print(op) +print(type(op)) +print(dir(op)) +print(repr(op.getopname())) +text += '\t%s\n' % op +self.b_current.add_comment(str(text)) + # Get initial values from input args: for idx, arg in enumerate(inputargs): self.b_current.add_comment("inputargs[%i]: %s" % (idx, arg)) @@ -189,7 +199,7 @@ self.b_current.add_comment(str(op)) # Compile the operation itself... -methname = '_emit_%s' % op.getopname() +methname = 'emit_%s' % op.getopname() getattr(self, methname) (op) @@ -250,7 +260,7 @@ # Handling of specific ResOperation subclasses -def _emit_int_add(self, op): +def emit_int_add(self, op): """ print(op._arg0) print(op._arg1) @@ -267,7 +277,25 @@ rval0, rval1)) self.b_current.add_assignment(lvalres, op_add) -def _emit_finish(self, op): +""" +def emit_label(self, op): +print(op) +print(op.__dict__) + +def emit_int_le(self, op): +print(op) +print(op.__dict__) + +def emit_int_ge(self, op): +print(op) +print(op.__dict__) + +def emit_guard_true(self, op): +print(op) +print(op.__dict__) +""" + +def emit_finish(self, op): # Write outputs back: for idx, arg in enumerate(op._args): #self.b_current.add_comment(" op._args[%i]: %s" % (idx, arg)) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Reduce debug spew
Author: David Malcolm Branch: libgccjit-backend Changeset: r74977:4838a68bebba Date: 2014-12-15 13:28 -0500 http://bitbucket.org/pypy/pypy/changeset/4838a68bebba/ Log:Reduce debug spew diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -59,6 +59,8 @@ print('assemble_loop') clt = CompiledLoopToken(self.cpu, looptoken.number) print(clt) +looptoken.compiled_loop_token = clt +clt._debug_nbargs = len(inputargs) # Make function: self.lvalue_for_box = {} @@ -93,11 +95,13 @@ self.b_current = self.lib.gcc_jit_function_new_block(self.fn, NULL) -for op in operations: +for op in operations: +""" print(op) print(type(op)) print(dir(op)) print(repr(op.getopname())) +""" # Add a comment describing this ResOperation comment_text = str2charp(str(op)) self.lib.gcc_jit_block_add_comment(self.b_current, @@ -114,15 +118,24 @@ if not jit_result: # FIXME: get error from context raise Exception("jit_result is NULL") -raise foo + +fn_name = str2charp(loopname) +fn_ptr = self.lib.gcc_jit_result_get_code(jit_result, fn_name) +free_charp(fn_name) + +looptoken._ll_function_addr = fn_ptr + +# FIXME: this leaks the gcc_jit_result def expr_to_rvalue(self, expr): +""" print('expr_to_rvalue') print(' %s' % expr) print(' %r' % expr) print(' %s' % type(expr)) print(' %s' % dir(expr)) print(' %s' % expr.__dict__) +""" if isinstance(expr, BoxInt): return self.lib.gcc_jit_lvalue_as_rvalue(self.get_box_as_lvalue(expr)) @@ -132,6 +145,7 @@ return self.lib.gcc_jit_context_new_rvalue_from_int(self.ctxt, self.t_int, r_int(expr.value)) +raise ValueError('unhandled expr: %s' % expr) def get_box_as_lvalue(self, box): if box not in self.lvalue_for_box: @@ -145,24 +159,27 @@ return self.lvalue_for_box[box] def expr_to_lvalue(self, expr): +""" print('expr_to_lvalue') print(' %s' % expr) print(' %r' % expr) print(' %s' % type(expr)) print(' %s' % dir(expr)) print(' %s' % expr.__dict__) +""" if isinstance(expr, BoxInt): return self.get_box_as_lvalue(expr) -raise foo +raise ValueError('unhandled expr: %s' % expr) # Handling of specific ResOperation subclasses def _on_int_add(self, op): +""" print(op._arg0) print(op._arg1) print(op.result) print(op.__dict__) - +""" rval0 = self.expr_to_rvalue(op._arg0) rval1 = self.expr_to_rvalue(op._arg1) lvalres = self.expr_to_lvalue(op.result) @@ -180,7 +197,9 @@ op_add) def _on_finish(self, op): +""" print(op.__dict__) +""" # FIXME: assume just 1-ary FINISH for now assert len(op._args) == 1 result = op._args[0] diff --git a/rpython/jit/backend/libgccjit/runner.py b/rpython/jit/backend/libgccjit/runner.py --- a/rpython/jit/backend/libgccjit/runner.py +++ b/rpython/jit/backend/libgccjit/runner.py @@ -14,6 +14,7 @@ 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): @@ -27,6 +28,6 @@ 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) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get parts of test_int_operations to work
Author: David Malcolm Branch: libgccjit-backend Changeset: r74983:c46f9a7b13de Date: 2014-12-17 00:39 -0500 http://bitbucket.org/pypy/pypy/changeset/c46f9a7b13de/ Log:Get parts of test_int_operations to work diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -35,16 +35,15 @@ self.num_anon_loops = 0 -self.make_context() -self.t_long = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_LONG) -self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) -self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) +self.sizeof_signed = rffi.sizeof(lltype.Signed) def make_context(self): eci = make_eci() self.lib = Library(eci) self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, r_int(1)) +if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, + r_int(1)) if 1: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, r_int(1)) @@ -52,7 +51,7 @@ r_int(1)) if 1: self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - r_int(3)) + r_int(2)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, r_int(1)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, @@ -88,6 +87,11 @@ clt.allgcrefs = [] clt.frame_info.clear() # for now +self.make_context() +self.t_long = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_LONG) +self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) +self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) + self.lvalue_for_box = {} print(jitframe.JITFRAME) @@ -135,20 +139,22 @@ # create it make_field('jf_frame', self.t_long) -locs = [] +initial_locs = [] #loc = jitframe.getofs('jf_frame') max_args = len(inputargs) for op in operations: if op.getopname() == 'finish': max_args = max(max_args, len(op._args)) +if op.getopname() == 'guard_true': +max_args = max(max_args, len(op._fail_args)) # FIXME: other ops self.field_for_arg_idx = {} for idx in range(max_args): self.field_for_arg_idx[idx] = make_field("arg%i" % idx, self.t_long) -locs.append(idx) # hack! +initial_locs.append(idx * self.sizeof_signed) # hack! struct_jit_frame.set_fields (fields) @@ -206,6 +212,10 @@ methname = 'emit_%s' % op.getopname() getattr(self, methname) (op) +# Ensure that the frame is large enough +baseofs = self.cpu.get_baseofs_of_frame_field() +clt.frame_info.update_frame_depth(baseofs, + max_args) self.ctxt.dump_to_file("/tmp/foo.c", r_int(1)) @@ -218,7 +228,7 @@ looptoken._ll_function_addr = fn_ptr -looptoken.compiled_loop_token._ll_initial_locs = locs +looptoken.compiled_loop_token._ll_initial_locs = initial_locs # FIXME: this leaks the gcc_jit_result @@ -266,32 +276,37 @@ # Handling of specific ResOperation subclasses -def emit_int_add(self, op): -""" -print(op._arg0) -print(op._arg1) -print(op.result) -print(op.__dict__) -""" -rval0 = self.expr_to_rvalue(op._arg0) -rval1 = self.expr_to_rvalue(op._arg1) -lvalres = self.expr_to_lvalue(op.result) +def impl_int_binop(self, resop, gcc_jit_binary_op): +rval0 = self.expr_to_rvalue(resop._arg0) +rval1 = self.expr_to_rvalue(resop._arg1) +lvalres = self.expr_to_lvalue(resop.result) -op_add = ( -self.ctxt.new_binary_op(self.lib.GCC_JIT_BINARY_OP_PLUS, -self.t_long, -rval0, rval1)) -self.b_current.add_assignment(lvalres, op_add) +binop_expr = self.ctxt.new_binary_op(gcc_jit_binary_op, + self.t_long, + rval0, rval1) +self.b_current.add_assignment(lvalres, binop_expr) -def emit_label(self, op): -print(op) -print(op.__dict__) -#print('op.getdescr(): %r' % op.getdescr()) -#print('op.getdescr().__dic
[pypy-commit] pypy libgccjit-backend: Support more of test_int_operations (requires gcc_jit_context_new_rvalue_from_long)
Author: David Malcolm Branch: libgccjit-backend Changeset: r74985:478e510f4673 Date: 2014-12-17 01:36 -0500 http://bitbucket.org/pypy/pypy/changeset/478e510f4673/ Log:Support more of test_int_operations (requires gcc_jit_context_new_rvalue_from_long) diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -248,8 +248,8 @@ elif isinstance(expr, ConstInt): #print('value: %r' % expr.value) #print('type(value): %r' % type(expr.value)) -return self.ctxt.new_rvalue_from_int(self.t_Signed, - r_int(expr.value)) +return self.ctxt.new_rvalue_from_long(self.t_Signed, + r_long(expr.value)) raise ValueError('unhandled expr: %s' % expr) def get_box_as_lvalue(self, box): @@ -299,6 +299,24 @@ def emit_int_floordiv(self, resop): self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_DIVIDE) +def emit_int_mod(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_MODULO) + +def emit_int_and(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_BITWISE_AND) + +def emit_int_or(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_BITWISE_OR) + +def emit_int_xor(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_BITWISE_XOR) + +def emit_int_rshift(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_RSHIFT) + +def emit_int_lshift(self, resop): +self.impl_int_binop(resop, self.lib.GCC_JIT_BINARY_OP_LSHIFT) + def emit_label(self, resop): print(resop) print(resop.__dict__) diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -129,6 +129,11 @@ INT]), (self.GCC_JIT_TYPE_P, + 'gcc_jit_context_get_int_type', [self.GCC_JIT_CONTEXT_P, + INT, + INT]), + +(self.GCC_JIT_TYPE_P, 'gcc_jit_type_get_pointer', [self.GCC_JIT_TYPE_P]), (self.GCC_JIT_FIELD_P, @@ -200,6 +205,10 @@ self.GCC_JIT_TYPE_P, INT]), (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_new_rvalue_from_long', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P, + LONG]), +(self.GCC_JIT_RVALUE_P, 'gcc_jit_context_zero', [self.GCC_JIT_CONTEXT_P, self.GCC_JIT_TYPE_P]), (self.GCC_JIT_RVALUE_P, @@ -396,6 +405,12 @@ self.lib.gcc_jit_context_get_type(self.inner_ctxt, r_enum)) +def get_int_type(self, num_bytes, is_signed): +return Type(self.lib, +self.lib.gcc_jit_context_get_int_type(self.inner_ctxt, + num_bytes, + is_signed)) + def new_field(self, type_, name): name_charp = str2charp(name) field = self.lib.gcc_jit_context_new_field(self.inner_ctxt, @@ -437,6 +452,12 @@ type_.inner_type, llvalue)) +def new_rvalue_from_long(self, type_, llvalue): +return RValue(self.lib, + self.lib.gcc_jit_context_new_rvalue_from_long(self.inner_ctxt, + type_.inner_type, +llvalue)) + def new_rvalue_from_ptr(self, type_, llvalue): return RValue(self.lib, self.lib.gcc_jit_context_new_rvalue_from_ptr(self.inner_ctxt, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: t_long -> t_Signed, and get the appropriately sized type
Author: David Malcolm Branch: libgccjit-backend Changeset: r74984:b74f1446a2c7 Date: 2014-12-17 00:45 -0500 http://bitbucket.org/pypy/pypy/changeset/b74f1446a2c7/ Log:t_long -> t_Signed, and get the appropriately sized type diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -88,7 +88,8 @@ clt.frame_info.clear() # for now self.make_context() -self.t_long = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_LONG) +self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), + r_int(1)) self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) @@ -108,8 +109,8 @@ field = self.ctxt.new_field(jit_type,name) fields.append(field) return field -make_field('jfi_frame_depth', self.t_long) -make_field('jfi_frame_size', self.t_long) +make_field('jfi_frame_depth', self.t_Signed) +make_field('jfi_frame_size', self.t_Signed) t_JITFRAMEINFO = ( self.ctxt.new_struct_type ("JITFRAMEINFO", @@ -131,13 +132,13 @@ self.field_jf_descr = make_field('jf_descr', self.t_void_ptr) make_field('jf_force_descr', self.t_void_ptr) make_field('jf_gcmap', self.t_void_ptr) -make_field('jf_extra_stack_depth', self.t_long) +make_field('jf_extra_stack_depth', self.t_Signed) make_field('jf_savedata', self.t_void_ptr) make_field('jf_guard_exc', self.t_void_ptr) make_field('jf_forward', t_jit_frame_ptr) # FIXME: for some reason there's an implicit word here; # create it -make_field('jf_frame', self.t_long) +make_field('jf_frame', self.t_Signed) initial_locs = [] #loc = jitframe.getofs('jf_frame') @@ -153,7 +154,7 @@ self.field_for_arg_idx = {} for idx in range(max_args): self.field_for_arg_idx[idx] = make_field("arg%i" % idx, - self.t_long) + self.t_Signed) initial_locs.append(idx * self.sizeof_signed) # hack! struct_jit_frame.set_fields (fields) @@ -174,7 +175,7 @@ loopname = 'anonloop_%i' % self.num_anon_loops self.num_anon_loops += 1 self.fn = self.ctxt.new_function(self.lib.GCC_JIT_FUNCTION_EXPORTED, - t_jit_frame_ptr, # self.t_long, + t_jit_frame_ptr, loopname, params, r_int(0)) @@ -247,13 +248,13 @@ elif isinstance(expr, ConstInt): #print('value: %r' % expr.value) #print('type(value): %r' % type(expr.value)) -return self.ctxt.new_rvalue_from_int(self.t_long, +return self.ctxt.new_rvalue_from_int(self.t_Signed, r_int(expr.value)) raise ValueError('unhandled expr: %s' % expr) def get_box_as_lvalue(self, box): if box not in self.lvalue_for_box: -self.lvalue_for_box[box] = self.fn.new_local(self.t_long, +self.lvalue_for_box[box] = self.fn.new_local(self.t_Signed, str(box)) return self.lvalue_for_box[box] @@ -282,7 +283,7 @@ lvalres = self.expr_to_lvalue(resop.result) binop_expr = self.ctxt.new_binary_op(gcc_jit_binary_op, - self.t_long, + self.t_Signed, rval0, rval1) self.b_current.add_assignment(lvalres, binop_expr) @@ -327,7 +328,7 @@ # First pass: capture the value of relevant boxes at the JUMP: tmps = [] for i in range(len(jumpop._args)): -tmps.append(self.fn.new_local(self.t_long, "tmp%i" % i)) +tmps.append(self.fn.new_local(self.t_Signed, "tmp%i" % i)) self.b_current.add_assignment( tmps[i], self.get_box_as_lvalue(jumpop._args[i]).as_rvalue()) @@ -347,7 +348,7 @@ self.ctxt.new_cast( self.ctxt.new_comparison(gcc_jit_comparison, rval0, rval1), -self.t_long) +self.t_Signed) ) self.b_current.add_assignment(lvalres, resop_cmp) @@ -407,7 +408,7 @@ """ self.b_current.add_assignment( self.get_arg_as_lvalue(idx), -
[pypy-commit] pypy libgccjit-backend: Get test_float_operations to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r74987:f2406d6b5d16 Date: 2014-12-17 11:26 -0500 http://bitbucket.org/pypy/pypy/changeset/f2406d6b5d16/ Log:Get test_float_operations to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -105,10 +105,13 @@ print(dir(jitframe.JITFRAME)) print('jitframe.JITFRAME._flds: %r' % jitframe.JITFRAME._flds) -# For now, build a "struct jit_frame". +# For now, build a "struct JITFRAME". # This will have the fields of jitframe, -# We'll construct numbered arg0..argN for use +# plus additional numbered arg0..argN for use # for inputargs and the outputs +# +# They'll each be of type "union any", so that we can freely read/write +# to them as any of the fundamental types. fields = [] def make_field(name, jit_type): @@ -382,6 +385,20 @@ def emit_float_abs(self, resop): self._impl_float_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_ABS) +# "CAST_" operations: +def emit_cast_float_to_int(self, resop): +rvalue = self.expr_to_rvalue(resop._arg0) +lvalres = self.expr_to_lvalue(resop.result) +cast_expr = self.ctxt.new_cast(rvalue, self.t_Signed) +self.b_current.add_assignment(lvalres, cast_expr) +def emit_cast_int_to_float(self, resop): +rvalue = self.expr_to_rvalue(resop._arg0) +lvalres = self.expr_to_lvalue(resop.result) +cast_expr = self.ctxt.new_cast(rvalue, self.t_float) +self.b_current.add_assignment(lvalres, cast_expr) + +# These are out-of-order compared to the list in resoperation.py: + def emit_label(self, resop): print(resop) print(resop.__dict__) @@ -449,9 +466,7 @@ def emit_int_ge(self, resop): self.impl_int_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) -# "UINT" comparisons: - -# (TODO) +# "UINT" comparisons: TODO # "FLOAT" comparisons: def impl_float_cmp(self, resop, gcc_jit_comparison): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Start supporting floats (requires GCC_JIT_UNARY_OP_ABS)
Author: David Malcolm Branch: libgccjit-backend Changeset: r74986:6ed15f284d0e Date: 2014-12-17 10:46 -0500 http://bitbucket.org/pypy/pypy/changeset/6ed15f284d0e/ Log:Start supporting floats (requires GCC_JIT_UNARY_OP_ABS) Convert arg-handling to use a union. Implement some float operations. Requires new GCC_JIT_UNARY_OP_ABS (not yet in upstream gcc repo) diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -4,7 +4,7 @@ from rpython.jit.backend.llsupport.regalloc import FrameManager from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type -from rpython.jit.metainterp.history import BoxInt, ConstInt +from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat from rpython.jit.metainterp.resoperation import * from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr from rpython.rtyper.lltypesystem.rffi import * @@ -90,9 +90,15 @@ self.make_context() self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), r_int(1)) +self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) +self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") +self.u_float = self.ctxt.new_field(self.t_float, "u_float") +self.t_any = self.ctxt.new_union_type ("any", + [self.u_signed, +self.u_float]) self.lvalue_for_box = {} print(jitframe.JITFRAME) @@ -154,7 +160,7 @@ self.field_for_arg_idx = {} for idx in range(max_args): self.field_for_arg_idx[idx] = make_field("arg%i" % idx, - self.t_Signed) + self.t_any) initial_locs.append(idx * self.sizeof_signed) # hack! struct_jit_frame.set_fields (fields) @@ -197,9 +203,21 @@ # Get initial values from input args: for idx, arg in enumerate(inputargs): self.b_current.add_comment("inputargs[%i]: %s" % (idx, arg)) +# (gdb) p *(double*)&jitframe->arg0 +# $7 = 10.5 +# (gdb) p *(double*)&jitframe->arg1 +# $8 = -2.25 +#src_ptr_rvalue = self.get_arg_as_lvalue(idx).get_address() +#src_ptr_rvalue = self.ctxt.new_cast(src_ptr_rvalue, self.t_float.get_pointer()) +#src_rvalue = self.ctxt.new_dereference(src_ptr_rvalue) +# or do it as a union +field = self.get_union_field_for_box(arg) +src_rvalue = self.get_arg_as_lvalue(idx).access_field(field).as_rvalue() +# FIXME: this may need a cast: +#src_rvalue = self.ctxt.new_cast(src_rvalue, self.t_float) self.b_current.add_assignment( self.get_box_as_lvalue(arg), -self.get_arg_as_lvalue(idx).as_rvalue()) +src_rvalue) for op in operations: print(op) @@ -243,19 +261,25 @@ print(' %s' % expr.__dict__) """ -if isinstance(expr, BoxInt): +if isinstance(expr, (BoxInt, BoxFloat)): return self.get_box_as_lvalue(expr).as_rvalue() elif isinstance(expr, ConstInt): #print('value: %r' % expr.value) #print('type(value): %r' % type(expr.value)) return self.ctxt.new_rvalue_from_long(self.t_Signed, r_long(expr.value)) -raise ValueError('unhandled expr: %s' % expr) +elif isinstance(expr, ConstFloat): +#print('value: %r' % expr.value) +#print('type(value): %r' % type(expr.value)) +return self.ctxt.new_rvalue_from_double(self.t_float, + expr.value)#r_double(expr.value)) +raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) def get_box_as_lvalue(self, box): if box not in self.lvalue_for_box: -self.lvalue_for_box[box] = self.fn.new_local(self.t_Signed, - str(box)) +self.lvalue_for_box[box] = ( +self.fn.new_local(self.get_type_for_box(box), + str(box))) return self.lvalue_for_box[box] def get_arg_as_lvalue(self, idx): @@ -271,17 +295,34 @@ print(' %s' % d
[pypy-commit] pypy libgccjit-backend: WIP: Initial compilation of test_compile_linear_loop
Author: David Malcolm Branch: libgccjit-backend Changeset: r74975:5a904ca20a80 Date: 2014-12-15 12:51 -0500 http://bitbucket.org/pypy/pypy/changeset/5a904ca20a80/ Log:WIP: Initial compilation of test_compile_linear_loop Tested via: ./pytest.py rpython/jit/backend/libgccjit/test/test_runner.py -k test_compile_linear_loop Doesn't yet run the compiled code diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -0,0 +1,181 @@ +from rpython.jit.backend.llsupport.assembler import BaseAssembler +from rpython.jit.backend.model import CompiledLoopToken +from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array +from rpython.jit.metainterp.history import BoxInt, ConstInt +from rpython.rtyper.lltypesystem.rffi import * + +class AssemblerLibgccjit(BaseAssembler): +_regalloc = None +#_output_loop_log = None +#_second_tmp_reg = ecx + +DEBUG_FRAME_DEPTH = False + +def __init__(self, cpu, translate_support_code=False): +BaseAssembler.__init__(self, cpu, translate_support_code) +#self.verbose = False +self.verbose = True +self.loop_run_counters = [] +self.float_const_neg_addr = 0 +self.float_const_abs_addr = 0 +self.malloc_slowpath = 0 +self.malloc_slowpath_varsize = 0 +self.wb_slowpath = [0, 0, 0, 0, 0] +#self.setup_failure_recovery() +self.datablockwrapper = None +self.stack_check_slowpath = 0 +self.propagate_exception_path = 0 +#self.teardown() + +self.num_anon_loops = 0 + +self.make_context() +print(self.ctxt) +self.t_int = self.lib.gcc_jit_context_get_type(self.ctxt, + self.lib.GCC_JIT_TYPE_INT) + +def make_context(self): +eci = make_eci() +self.lib = Library(eci) +self.ctxt = self.lib.gcc_jit_context_acquire() +self.lib.gcc_jit_context_set_bool_option(self.ctxt, + self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, +r_int(1)) +self.lib.gcc_jit_context_set_int_option(self.ctxt, + self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + r_int(3)) +self.lib.gcc_jit_context_set_bool_option(self.ctxt, + self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, +r_int(1)) +self.lib.gcc_jit_context_set_bool_option(self.ctxt, + self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, +r_int(1)) +self.lib.gcc_jit_context_set_bool_option(self.ctxt, + self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, +r_int(1)) + +def assemble_loop(self, inputargs, operations, looptoken, log, + loopname, logger): +print('assemble_loop') +clt = CompiledLoopToken(self.cpu, looptoken.number) +print(clt) + +# Make function: +self.lvalue_for_box = {} +print(' inputargs: %r' % (inputargs, )) +params = [] +for arg in inputargs: +param_name = str2charp(str(arg)) +param = self.lib.gcc_jit_context_new_param(self.ctxt, + self.lib.null_location_ptr, + self.t_int, # FIXME: use correct type + param_name) +self.lvalue_for_box[arg] = self.lib.gcc_jit_param_as_lvalue(param) +free_charp(param_name) +params.append(param) + +print("loopname: %r" % loopname) +if not loopname: +loopname = 'anonloop_%i' % self.num_anon_loops +self.num_anon_loops += 1 +fn_name = str2charp(loopname) +param_array = make_param_array(self.lib, params) +self.fn = self.lib.gcc_jit_context_new_function(self.ctxt, + self.lib.null_location_ptr, + self.lib.GCC_JIT_FUNCTION_EXPORTED, +self.t_int, +fn_name, +r_int(len(params)), +param_array, +r_int(0)) +lltype.free(param_array, flavor='raw') +free_charp(fn_name) + +self.b_
[pypy-commit] pypy libgccjit-backend: WIP: Add comments describing each ResOperation into the libgccjit IR
Author: David Malcolm Branch: libgccjit-backend Changeset: r74976:f6a3bd3f6dbb Date: 2014-12-15 12:56 -0500 http://bitbucket.org/pypy/pypy/changeset/f6a3bd3f6dbb/ Log:WIP: Add comments describing each ResOperation into the libgccjit IR diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -93,11 +93,19 @@ self.b_current = self.lib.gcc_jit_function_new_block(self.fn, NULL) -for op in operations: +for op in operations: print(op) print(type(op)) print(dir(op)) print(repr(op.getopname())) +# Add a comment describing this ResOperation +comment_text = str2charp(str(op)) +self.lib.gcc_jit_block_add_comment(self.b_current, + self.lib.null_location_ptr, + comment_text) +free_charp(comment_text) + +# Compile the operation itself... methname = '_on_%s' % op.getopname() getattr(self, methname) (op) diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -175,6 +175,10 @@ self.GCC_JIT_LVALUE_P, self.GCC_JIT_RVALUE_P]), (lltype.Void, + 'gcc_jit_block_add_comment', [self.GCC_JIT_BLOCK_P, + self.GCC_JIT_LOCATION_P, + CCHARP]), +(lltype.Void, 'gcc_jit_block_end_with_return', [self.GCC_JIT_BLOCK_P, self.GCC_JIT_LOCATION_P, self.GCC_JIT_RVALUE_P]), ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_compile_loop to work
Author: David Malcolm Branch: libgccjit-backend Changeset: r74982:e540b044a92d Date: 2014-12-16 14:33 -0500 http://bitbucket.org/pypy/pypy/changeset/e540b044a92d/ Log:Get test_compile_loop to work diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -37,13 +37,15 @@ self.make_context() self.t_long = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_LONG) +self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) def make_context(self): eci = make_eci() self.lib = Library(eci) self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() -if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, r_int(1)) +if 1: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, r_int(1)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, @@ -55,7 +57,7 @@ r_int(1)) self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, r_int(1)) -if 0: +if 1: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, r_int(1)) @@ -171,7 +173,9 @@ params, r_int(0)) -self.b_current = self.fn.new_block() +self.b_current = self.fn.new_block("initial") +self.label_for_descr = {} +self.block_for_label_descr = {} # Add an initial comment summarizing the loop text = '\n\tinputargs: %s\n\n' % inputargs @@ -205,6 +209,8 @@ self.ctxt.dump_to_file("/tmp/foo.c", r_int(1)) +#raise foo + jit_result = self.ctxt.compile() self.ctxt.release() @@ -213,7 +219,7 @@ looptoken._ll_function_addr = fn_ptr looptoken.compiled_loop_token._ll_initial_locs = locs - + # FIXME: this leaks the gcc_jit_result def expr_to_rvalue(self, expr): @@ -277,32 +283,95 @@ rval0, rval1)) self.b_current.add_assignment(lvalres, op_add) -""" def emit_label(self, op): print(op) print(op.__dict__) +#print('op.getdescr(): %r' % op.getdescr()) +#print('op.getdescr().__dict__: %r' % op.getdescr().__dict__) + +b_new = self.fn.new_block(str(op)) +self.block_for_label_descr[op.getdescr()] = b_new +self.label_for_descr[op.getdescr()] = op +self.b_current.end_with_jump(b_new) +self.b_current = b_new + +def emit_jump(self, jumpop): +print(jumpop) +print(jumpop.__dict__) +label = self.label_for_descr[jumpop.getdescr()] +print(jumpop.getdescr()) +print('label: %r' % label) + +assert len(jumpop._args) == len(label._args) + +# We need to write to the boxes listed in the label's args +# with the values from those listed in the jump's args. +# However, there are potential cases like JUMP(i0, i1) going to LABEL(i1, i0) +# where all such assignments happen "simultaneously". +# Hence we need to set up temporaries. +# First pass: capture the value of relevant boxes at the JUMP: +tmps = [] +for i in range(len(jumpop._args)): +tmps.append(self.fn.new_local(self.t_long, "tmp%i" % i)) +self.b_current.add_assignment( +tmps[i], +self.get_box_as_lvalue(jumpop._args[i]).as_rvalue()) +# Second pass: write the values to the boxes at the LABEL: +for i in range(len(jumpop._args)): +self.b_current.add_assignment( +self.get_box_as_lvalue(label._args[i]), +tmps[i].as_rvalue()) + + self.b_current.end_with_jump(self.block_for_label_descr[jumpop.getdescr()]) + +def impl_int_cmp(self, op, gcc_jit_comparison): +rval0 = self.expr_to_rvalue(op._arg0) +rval1 = self.expr_to_rvalue(op._arg1) +lvalres = self.expr_to_lvalue(op.result) +op_cmp = ( +self.ctxt.new_cast( +self.ctxt.new_comparison(gcc_jit_comparison, + rval0, rval1), +self.t_long) +) +self.b_current.add_assignment(lvalres, + op_cmp) def emit_int_le(self, op): -print(op) -print(op.__dict__) +self.impl_int_cmp(op, self.lib.GCC_JIT_COMPARISON_LE) def emit_int_ge(self, op): -print(op) -print(op.__dict__) +
[pypy-commit] pypy libgccjit-backend: Reorder emit_ methods to match the ordering within resoperation.py
Author: David Malcolm Branch: libgccjit-backend Changeset: r74988:c5989b35a619 Date: 2014-12-17 12:11 -0500 http://bitbucket.org/pypy/pypy/changeset/c5989b35a619/ Log:Reorder emit_ methods to match the ordering within resoperation.py diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -319,7 +319,124 @@ else: raise ValueError('unhandled box: %s %s' % (box, type(box))) -# Handling of specific ResOperation subclasses +# Handling of specific ResOperation subclasses: each one is +# a method named "emit_foo", where "foo" is the str() of the resop. +# +# Keep these in the same order as _oplist within +# rpython/jit/metainterp/resoperation.py. + +# JUMP and FINISH: + +def emit_jump(self, jumpop): +print(jumpop) +print(jumpop.__dict__) +label = self.label_for_descr[jumpop.getdescr()] +print(jumpop.getdescr()) +print('label: %r' % label) + +assert len(jumpop._args) == len(label._args) + +# We need to write to the boxes listed in the label's args +# with the values from those listed in the jump's args. +# However, there are potential cases like JUMP(i0, i1) going to LABEL(i1, i0) +# where all such assignments happen "simultaneously". +# Hence we need to set up temporaries. +# First pass: capture the value of relevant boxes at the JUMP: +tmps = [] +for i in range(len(jumpop._args)): +tmps.append(self.fn.new_local(self.t_Signed, "tmp%i" % i)) +self.b_current.add_assignment( +tmps[i], +self.get_box_as_lvalue(jumpop._args[i]).as_rvalue()) +# Second pass: write the values to the boxes at the LABEL: +for i in range(len(jumpop._args)): +self.b_current.add_assignment( +self.get_box_as_lvalue(label._args[i]), +tmps[i].as_rvalue()) + + self.b_current.end_with_jump(self.block_for_label_descr[jumpop.getdescr()]) + +def emit_finish(self, resop): +self._impl_write_output_args(resop._args) +self._impl_write_jf_descr(resop) +self.b_current.end_with_return(self.param_frame.as_rvalue ()) + +def emit_label(self, resop): +print(resop) +print(resop.__dict__) +#print('resop.getdescr(): %r' % resop.getdescr()) +#print('resop.getdescr().__dict__: %r' % resop.getdescr().__dict__) + +b_new = self.fn.new_block(str(resop)) +self.block_for_label_descr[resop.getdescr()] = b_new +self.label_for_descr[resop.getdescr()] = resop +self.b_current.end_with_jump(b_new) +self.b_current = b_new + +# GUARD_* + +def _impl_guard(self, resop, istrue): +print(resop) +print(resop.__dict__) +b_true = self.fn.new_block("on_true_at_%s" % resop) +b_false = self.fn.new_block("on_false_at_%s" % resop) +boolval = self.ctxt.new_cast(self.expr_to_rvalue(resop._arg0), + self.t_bool) +self.b_current.end_with_conditional(boolval, +b_true, b_false) + +if istrue: +self.b_current = b_false +else: +self.b_current = b_true +self._impl_write_output_args(resop._fail_args) +self._impl_write_jf_descr(resop) +self.b_current.end_with_return(self.param_frame.as_rvalue ()) +rd_locs = [] +for idx, arg in enumerate(resop._fail_args): +rd_locs.append(idx * self.sizeof_signed) +resop.getdescr().rd_locs = rd_locs + +if istrue: +self.b_current = b_true +else: +self.b_current = b_false + +def emit_guard_true(self, resop): +self._impl_guard(resop, r_int(1)) + +def emit_guard_false(self, resop): +self._impl_guard(resop, r_int(0)) + +def _impl_write_output_args(self, args): +# Write outputs back: +for idx, arg in enumerate(args): +if arg is not None: +src_rvalue = self.get_box_as_lvalue(arg).as_rvalue() +field = self.get_union_field_for_box(arg) +dst_lvalue = self.get_arg_as_lvalue(idx).access_field(field) +self.b_current.add_assignment(dst_lvalue, src_rvalue) +else: +# FIXME: see test_compile_with_holes_in_fail_args +raise ValueError("how to handle holes in fail args?") +""" +self.b_current.add_assignment( +self.get_arg_as_lvalue(idx), +self.ctxt.new_rvalue_from_int (self.t_Signed, + r_int(0))) +""" + +def _impl_write_jf_descr(self, resop): +#
[pypy-commit] pypy libgccjit-backend: Clarify _impl_guard; start adding boilerplate for bridges
Author: David Malcolm Branch: libgccjit-backend Changeset: r75017:a1db64631c41 Date: 2014-12-17 13:20 -0500 http://bitbucket.org/pypy/pypy/changeset/a1db64631c41/ Log:Clarify _impl_guard; start adding boilerplate for bridges diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -259,6 +259,15 @@ # FIXME: this leaks the gcc_jit_result +def assemble_bridge(self, logger, faildescr, inputargs, operations, +original_loop_token, log): +print('assemble_bridge(%r)' % locals()) +if not we_are_translated(): +# Arguments should be unique +assert len(set(inputargs)) == len(inputargs) + +raise foo + def expr_to_rvalue(self, expr): """ print('expr_to_rvalue') @@ -391,9 +400,14 @@ b_true, b_false) if istrue: -self.b_current = b_false +b_guard_failure = b_false +b_guard_success = b_true else: -self.b_current = b_true +b_guard_failure = b_true +b_guard_success = b_false + +# Write out guard failure impl: +self.b_current = b_guard_failure self._impl_write_output_args(resop._fail_args) self._impl_write_jf_descr(resop) self.b_current.end_with_return(self.param_frame.as_rvalue ()) @@ -402,10 +416,8 @@ rd_locs.append(idx * self.sizeof_signed) resop.getdescr().rd_locs = rd_locs -if istrue: -self.b_current = b_true -else: -self.b_current = b_false +# Further operations go into the guard success block: +self.b_current = b_guard_success def emit_guard_true(self, resop): self._impl_guard(resop, r_int(1)) diff --git a/rpython/jit/backend/libgccjit/runner.py b/rpython/jit/backend/libgccjit/runner.py --- a/rpython/jit/backend/libgccjit/runner.py +++ b/rpython/jit/backend/libgccjit/runner.py @@ -17,20 +17,13 @@ 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 ()) -""" return self.assembler.assemble_loop(inputargs, operations, looptoken, log, name, logger) + +def compile_bridge(self, faildescr, inputargs, operations, + original_loop_token, log=True, logger=None): +clt = original_loop_token.compiled_loop_token +clt.compiling_a_bridge() +return self.assembler.assemble_bridge(logger, faildescr, inputargs, + operations, + original_loop_token, log=log) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Document the changes to libgccjit that I need to merge
Author: David Malcolm Branch: libgccjit-backend Changeset: r75020:5d890f2ddecd Date: 2014-12-18 12:17 -0500 http://bitbucket.org/pypy/pypy/changeset/5d890f2ddecd/ Log:Document the changes to libgccjit that I need to merge diff --git a/rpython/jit/backend/libgccjit/notes.rst b/rpython/jit/backend/libgccjit/notes.rst new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/libgccjit/notes.rst @@ -0,0 +1,16 @@ +This is an experiment, and merely a work-in-progress. + +In particular, this needs some changes to libgccjit that are currently +only in my local repo: + + * new API entrypoints: + + * :c:func:`gcc_jit_result_get_global` + + * :c:func:`gcc_jit_context_new_rvalue_from_long` + + * a new value :c:macro:`GCC_JIT_UNARY_OP_ABS` within + :c:type:`enum gcc_jit_unary_op`. + + * an extra param to :c:func:`gcc_jit_context_new_global` + (enum gcc_jit_global_kind). ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Begin implementing code patching
Author: David Malcolm Branch: libgccjit-backend Changeset: r75019:ee6c48dc603d Date: 2014-12-18 12:10 -0500 http://bitbucket.org/pypy/pypy/changeset/ee6c48dc603d/ Log:Begin implementing code patching When generating guard failure handling, replace direct call to default handler with a jump through a function pointer, so that (in theory) we can write to this function pointer to use a different handler. This requires a couple of extra changes to libgccjit that are currently only in my local repo: * a new API entrypoint "gcc_jit_result_get_global" * an extra param to gcc_jit_context_new_global (enum gcc_jit_global_kind) diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -20,6 +20,93 @@ self.param_addr = assembler.ctxt.new_param(assembler.t_void_ptr, "addr") self.paramlist.append(self.param_addr) +self.paramtypes = [assembler.t_jit_frame_ptr, + assembler.t_void_ptr] + +class Patchpoint: +""" +We need to be able to patch out the generated code that runs when a +guard fails; this class handles that. + +We handle guard failure with a tail-call through a function pointer, +equivalent to this C code: + + struct JITFRAME * (*guard_failure_fn_ptr_0) (struct JITFRAME *, void *); + + extern struct JITFRAME * + anonloop_0 (struct JITFRAME * jitframe, void * addr) + { +...various operations... + +if (!guard) + goto on_guard_failure; + +...various operations... + + on_guard_failure: + return guard_failure_fn_ptr_0 (frame, ); + } + +This can hopefully be optimized to a jump through a ptr, since it's +a tail call: + + 0x7fffeb7086d0 <+16>: jle0x7fffeb7086c8 + 0x7fffeb7086d2 <+18>: mov%rax,0x48(%rdi) + 0x7fffeb7086d6 <+22>: mov0x2008fb(%rip),%rax# 0x7fffeb908fd8 + 0x7fffeb7086dd <+29>: mov(%rax),%rax + 0x7fffeb7086e0 <+32>: jmpq *%rax +""" +def __init__(self, assembler): +self.failure_params = Params(assembler) +self.serial = assembler.num_guard_failure_fns +assembler.num_guard_failure_fns += 1 +self.t_fn_ptr_type = ( +assembler.ctxt.new_function_ptr_type (assembler.t_jit_frame_ptr, + self.failure_params.paramtypes, + r_int(0))) +# Create the function ptr +# Globals are zero-initialized, so we'll need to +# write in the ptr to the initial handler before the loop is called, +# or we'll have a jump-through-NULL segfault. +self.fn_ptr_name = "guard_failure_fn_ptr_%i" % self.serial +self.failure_fn_ptr = ( +assembler.ctxt.new_global(assembler.lib.GCC_JIT_GLOBAL_EXPORTED, + self.t_fn_ptr_type, + self.fn_ptr_name)) +self.handler_name = "on_guard_failure_%i" % self.serial +self.failure_fn = ( + assembler.ctxt.new_function(assembler.lib.GCC_JIT_FUNCTION_EXPORTED, +assembler.t_jit_frame_ptr, +self.handler_name, +self.failure_params.paramlist, +r_int(0))) + +def write_initial_handler(self, result): +# Get the address of the machine code for the handler; +# this is a: +# struct JITFRAME * (*guard_failure_fn) (struct JITFRAME *, void *) +handler = result.get_code(self.handler_name) + +# Get the address of the function ptr to be written to; +# this is a: +# struct JITFRAME * (**guard_failure_fn) (struct JITFRAME *, void *) +# i.e. one extra level of indirection. +fn_ptr_ptr = result.get_global(self.fn_ptr_name) + +# We want to write the equivalent of: +#(*fn_ptr_ptr) = handler; +# +# "fn_ptr_ptr" and "handler" are both currently (void *). +# so we need to cast them to a form where we can express +# the above. + +# We can't directly express the function ptr ptr in lltype, +# so instead pretend we have a (const char **) and a (const char *): +fn_ptr_ptr = rffi.cast(rffi.CCHARPP, fn_ptr_ptr) +handler = rffi.cast(rffi.CCHARP, handler) + +# ...and write through the ptr: +fn_ptr_ptr[0] = handler class AssemblerLibgccjit(BaseAssembler): _regalloc = None @@ -48,6 +135,7 @@ self.num_guard_failure_fns = 0 self.sizeof_signed = rffi.sizeof(lltype.Signed) +self.pat
[pypy-commit] pypy libgccjit-backend: Split out guard failure into a tail call to another function
Author: David Malcolm Branch: libgccjit-backend Changeset: r75018:eb3ba1b9910e Date: 2014-12-17 15:43 -0500 http://bitbucket.org/pypy/pypy/changeset/eb3ba1b9910e/ Log:Split out guard failure into a tail call to another function Eventually this could be a jump through a function pointer. Right now it's simply a call to a internal function. The call gets inlined away, back into the code we had before. diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -10,6 +10,17 @@ from rpython.rtyper.lltypesystem.rffi import * from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory +class Params: +def __init__(self, assembler): +self.paramlist = [] +self.param_frame = assembler.ctxt.new_param(assembler.t_jit_frame_ptr, +"jitframe") +self.paramlist.append(self.param_frame) + +self.param_addr = assembler.ctxt.new_param(assembler.t_void_ptr, + "addr") +self.paramlist.append(self.param_addr) + class AssemblerLibgccjit(BaseAssembler): _regalloc = None #_output_loop_log = None @@ -34,6 +45,7 @@ #self.teardown() self.num_anon_loops = 0 +self.num_guard_failure_fns = 0 self.sizeof_signed = rffi.sizeof(lltype.Signed) @@ -98,6 +110,7 @@ self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) +self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") self.u_float = self.ctxt.new_field(self.t_float, "u_float") @@ -134,7 +147,7 @@ struct_jit_frame = self.ctxt.new_opaque_struct ("JITFRAME") -t_jit_frame_ptr = struct_jit_frame.as_type().get_pointer() +self.t_jit_frame_ptr = struct_jit_frame.as_type().get_pointer() fields = [] # FIXME: Does the GCStruct implicitly add any fields? @@ -149,7 +162,7 @@ make_field('jf_extra_stack_depth', self.t_Signed) make_field('jf_savedata', self.t_void_ptr) make_field('jf_guard_exc', self.t_void_ptr) -make_field('jf_forward', t_jit_frame_ptr) +make_field('jf_forward', self.t_jit_frame_ptr) # FIXME: for some reason there's an implicit word here; # create it make_field('jf_frame', self.t_Signed) @@ -176,22 +189,16 @@ # Make function: #print(' inputargs: %r' % (inputargs, )) #jitframe.JITFRAMEINFOPTR -params = [] - -self.param_frame = self.ctxt.new_param(t_jit_frame_ptr, "jitframe") -params.append(self.param_frame) - -self.param_addr = self.ctxt.new_param(self.t_void_ptr, "addr") -params.append(self.param_addr) +self.loop_params = Params(self) if not loopname: loopname = 'anonloop_%i' % self.num_anon_loops self.num_anon_loops += 1 print(" loopname: %r" % loopname) self.fn = self.ctxt.new_function(self.lib.GCC_JIT_FUNCTION_EXPORTED, - t_jit_frame_ptr, + self.t_jit_frame_ptr, loopname, - params, + self.loop_params.paramlist, r_int(0)) self.b_current = self.fn.new_block("initial") @@ -300,7 +307,7 @@ return self.lvalue_for_box[box] def get_arg_as_lvalue(self, idx): -return self.param_frame.as_rvalue ().dereference_field ( +return self.loop_params.param_frame.as_rvalue ().dereference_field ( self.field_for_arg_idx[idx]) def expr_to_lvalue(self, expr): @@ -371,9 +378,9 @@ self.b_current.end_with_jump(self.block_for_label_descr[jumpop.getdescr()]) def emit_finish(self, resop): -self._impl_write_output_args(resop._args) -self._impl_write_jf_descr(resop) -self.b_current.end_with_return(self.param_frame.as_rvalue ()) +self._impl_write_output_args(self.loop_params, resop._args) +self._impl_write_jf_descr(self.loop_params, resop) +self.b_current.end_with_return(self.loop_params.param_frame.as_rvalue ()) def emit_label(self, resop): print(resop) @@ -408,15 +415,34 @@ # Write out guard failure impl: self.b_current = b_guard_failure -self._impl_write_output_args(resop._fail_args) -self._impl_write_jf_descr(resop) -self.b_current.end_with_return(self.param
[pypy-commit] pypy libgccjit-backend: Implement uint_floordiv and uint_rshift; reduce debug spew
Author: David Malcolm Branch: libgccjit-backend Changeset: r75016:3e8180a52286 Date: 2014-12-17 12:47 -0500 http://bitbucket.org/pypy/pypy/changeset/3e8180a52286/ Log:Implement uint_floordiv and uint_rshift; reduce debug spew diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -44,19 +44,22 @@ if 0: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, r_int(1)) -if 1: +if 0: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, r_int(1)) -self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, - r_int(1)) +if 1: +self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, + r_int(1)) if 1: self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, r_int(2)) - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, - r_int(1)) -self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, - r_int(1)) -if 1: +if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, + r_int(1)) +if 0: + self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, + r_int(1)) +if 0: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, r_int(1)) @@ -75,7 +78,7 @@ loopname, logger): print('assemble_loop') clt = CompiledLoopToken(self.cpu, looptoken.number) -print(clt) +#print(clt) looptoken.compiled_loop_token = clt clt._debug_nbargs = len(inputargs) @@ -90,6 +93,8 @@ self.make_context() self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), r_int(1)) +self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed), + r_int(0)) self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) @@ -101,9 +106,9 @@ self.u_float]) self.lvalue_for_box = {} -print(jitframe.JITFRAME) -print(dir(jitframe.JITFRAME)) -print('jitframe.JITFRAME._flds: %r' % jitframe.JITFRAME._flds) +#print(jitframe.JITFRAME) +#print(dir(jitframe.JITFRAME)) +#print('jitframe.JITFRAME._flds: %r' % jitframe.JITFRAME._flds) # For now, build a "struct JITFRAME". # This will have the fields of jitframe, @@ -169,7 +174,7 @@ struct_jit_frame.set_fields (fields) # Make function: -print(' inputargs: %r' % (inputargs, )) +#print(' inputargs: %r' % (inputargs, )) #jitframe.JITFRAMEINFOPTR params = [] @@ -179,10 +184,10 @@ self.param_addr = self.ctxt.new_param(self.t_void_ptr, "addr") params.append(self.param_addr) -print("loopname: %r" % loopname) if not loopname: loopname = 'anonloop_%i' % self.num_anon_loops self.num_anon_loops += 1 +print(" loopname: %r" % loopname) self.fn = self.ctxt.new_function(self.lib.GCC_JIT_FUNCTION_EXPORTED, t_jit_frame_ptr, loopname, @@ -196,10 +201,10 @@ # Add an initial comment summarizing the loop text = '\n\tinputargs: %s\n\n' % inputargs for op in operations: -print(op) -print(type(op)) -print(dir(op)) -print(repr(op.getopname())) +#print(op) +#print(type(op)) +#print(dir(op)) +#print(repr(op.getopname())) text += '\t%s\n' % op self.b_current.add_comment(str(text)) @@ -223,10 +228,10 @@ src_rvalue) for op in operations: -print(op) -print(type(op)) -print(dir(op)) -print(repr(op.getopname())) +#print(op) +#print(type(op)) +#print(dir(op)) +#print(repr(op.getopname())) # Add a comment describing this ResOperation self.b_curren
[pypy-commit] pypy libgccjit-backend: Raise an exception when an error occurs on a gcc_jit_context
Author: David Malcolm Branch: libgccjit-backend Changeset: r75067:6b48e7ef126a Date: 2014-12-22 15:03 -0500 http://bitbucket.org/pypy/pypy/changeset/6b48e7ef126a/ Log:Raise an exception when an error occurs on a gcc_jit_context This makes it much easier to track down issues. Requires not-yet-in-trunk API entrypoint: gcc_jit_context_get_last_error diff --git a/rpython/jit/backend/libgccjit/notes.rst b/rpython/jit/backend/libgccjit/notes.rst --- a/rpython/jit/backend/libgccjit/notes.rst +++ b/rpython/jit/backend/libgccjit/notes.rst @@ -9,6 +9,8 @@ * :c:func:`gcc_jit_context_new_rvalue_from_long` + * :c:func:`gcc_jit_context_get_last_error` + * a new value :c:macro:`GCC_JIT_UNARY_OP_ABS` within :c:type:`enum gcc_jit_unary_op`. diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -120,6 +120,9 @@ CCHARP, INT]), +(CCHARP, + 'gcc_jit_context_get_last_error', [self.GCC_JIT_CONTEXT_P]), + (VOIDP, 'gcc_jit_result_get_code', [self.GCC_JIT_RESULT_P, CCHARP]), @@ -485,11 +488,13 @@ def get_type(self, r_enum): return Type(self.lib, +self, self.lib.gcc_jit_context_get_type(self.inner_ctxt, r_enum)) def get_int_type(self, num_bytes, is_signed): return Type(self.lib, +self, self.lib.gcc_jit_context_get_int_type(self.inner_ctxt, num_bytes, is_signed)) @@ -501,7 +506,7 @@ type_.inner_type, name_charp) free_charp(name_charp) -return Field(self.lib, field) +return Field(self.lib, self, field) def new_struct_type(self, name, fields): name_charp = str2charp(name) @@ -518,7 +523,7 @@ field_array)) lltype.free(field_array, flavor='raw') free_charp(name_charp) -return Struct(self.lib, inner_struct) +return Struct(self.lib, self, inner_struct) def new_opaque_struct(self, name): name_charp = str2charp(name) @@ -527,7 +532,7 @@ self.lib.null_location_ptr, name_charp)) free_charp(name_charp) -return Struct(self.lib, inner_struct) +return Struct(self.lib, self, inner_struct) def new_union_type(self, name, fields): name_charp = str2charp(name) @@ -544,7 +549,7 @@ field_array)) lltype.free(field_array, flavor='raw') free_charp(name_charp) -return Type(self.lib, inner_type) +return Type(self.lib, self, inner_type) def new_function_ptr_type(self, returntype, param_types, is_variadic): raw_type_array = lltype.malloc(self.lib.TYPE_P_P.TO, @@ -561,34 +566,39 @@ is_variadic) lltype.free(raw_type_array, flavor='raw') -return Type(self.lib, type_) +return Type(self.lib, self, type_) def new_rvalue_from_int(self, type_, llvalue): return RValue(self.lib, + self, self.lib.gcc_jit_context_new_rvalue_from_int(self.inner_ctxt, type_.inner_type, llvalue)) def new_rvalue_from_long(self, type_, llvalue): return RValue(self.lib, + self, self.lib.gcc_jit_context_new_rvalue_from_long(self.inner_ctxt, type_.inner_type, llvalue)) def new_rvalue_from_double(self, type_, llvalue): return RValue(self.lib, + self, self.lib.gcc_jit_context_new_rvalue_from_double(self.inner_ctxt, type_.inner_type, llvalue)) def new_rvalue_from_ptr(self, type_, llvalue): return RValue(self.lib, + self, self.lib.gcc_jit_context_
[pypy-commit] pypy libgccjit-backend: Bind gcc_jit_object_get_debug_string
Author: David Malcolm Branch: libgccjit-backend Changeset: r75066:8b2b47726e8a Date: 2014-12-22 14:35 -0500 http://bitbucket.org/pypy/pypy/changeset/8b2b47726e8a/ Log:Bind gcc_jit_object_get_debug_string diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -64,6 +64,8 @@ compilation_info=eci)) self.GCC_JIT_RESULT_P = lltype.Ptr(COpaque(name='gcc_jit_result', compilation_info=eci)) +self.GCC_JIT_OBJECT_P = lltype.Ptr(COpaque(name='gcc_jit_object', + compilation_info=eci)) self.GCC_JIT_TYPE_P = lltype.Ptr(COpaque(name='gcc_jit_type', compilation_info=eci)) self.GCC_JIT_FIELD_P = lltype.Ptr(COpaque(name='gcc_jit_field', @@ -129,6 +131,9 @@ (lltype.Void, 'gcc_jit_result_release', [self.GCC_JIT_RESULT_P]), +(CCHARP, + 'gcc_jit_object_get_debug_string', [self.GCC_JIT_OBJECT_P]), + # Types @@ -206,6 +211,10 @@ INT, self.PARAM_P_P, INT]), + +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_function_as_object', [self.GCC_JIT_FUNCTION_P]), + (self.GCC_JIT_LVALUE_P, 'gcc_jit_function_new_local', [self.GCC_JIT_FUNCTION_P, self.GCC_JIT_LOCATION_P, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_compile_bridge to work
Author: David Malcolm Branch: libgccjit-backend Changeset: r75071:c77c1f9355fd Date: 2014-12-22 16:42 -0500 http://bitbucket.org/pypy/pypy/changeset/c77c1f9355fd/ Log:Get test_compile_bridge to work diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -23,6 +23,21 @@ self.paramtypes = [assembler.t_jit_frame_ptr, assembler.t_void_ptr] +class Function: +""" +Wrapper around a rffi_bindings.Function, for a loop or bridge +""" +def __init__(self, name, rffi_fn): +self.name = name +self.rffi_fn = rffi_fn +self.patchpoints = [] + +def new_block(self, name): + return self.rffi_fn.new_block(name) + +def new_local(self, type_, name): + return self.rffi_fn.new_local(type_, name) + class Patchpoint: """ We need to be able to patch out the generated code that runs when a @@ -91,7 +106,12 @@ # this is a: # struct JITFRAME * (**guard_failure_fn) (struct JITFRAME *, void *) # i.e. one extra level of indirection. -fn_ptr_ptr = result.get_global(self.fn_ptr_name) +self.fn_ptr_ptr = result.get_global(self.fn_ptr_name) + +self.set_handler(handler) + +def set_handler(self, handler): +print('set_handler(%r)' % handler) # We want to write the equivalent of: #(*fn_ptr_ptr) = handler; @@ -102,7 +122,7 @@ # We can't directly express the function ptr ptr in lltype, # so instead pretend we have a (const char **) and a (const char *): -fn_ptr_ptr = rffi.cast(rffi.CCHARPP, fn_ptr_ptr) +fn_ptr_ptr = rffi.cast(rffi.CCHARPP, self.fn_ptr_ptr) handler = rffi.cast(rffi.CCHARP, handler) # ...and write through the ptr: @@ -133,13 +153,18 @@ self.num_anon_loops = 0 self.num_guard_failure_fns = 0 +self.num_bridges = 0 self.sizeof_signed = rffi.sizeof(lltype.Signed) -self.patchpoints = [] +self.label_for_descr = {} +self.block_for_label_descr = {} +self.function_for_label_descr = {} +self.patchpoint_for_descr = {} + +eci = make_eci() +self.lib = Library(eci) def make_context(self): -eci = make_eci() -self.lib = Library(eci) self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() if 0: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, @@ -162,7 +187,22 @@ if 0: self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, r_int(1)) - + +self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), + r_int(1)) +self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed), + r_int(0)) +self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME +self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) +self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) +self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) + +self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") +self.u_float = self.ctxt.new_field(self.t_float, "u_float") +self.t_any = self.ctxt.new_union_type ("any", + [self.u_signed, +self.u_float]) + def setup(self, looptoken): allblocks = self.get_asmmemmgr_blocks(looptoken) self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, @@ -191,22 +231,69 @@ clt.frame_info.clear() # for now self.make_context() -self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), - r_int(1)) -self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed), - r_int(0)) -self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME -self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) -self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) -self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) - -self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") -self.u_float = self.ctxt.new_field(self.t_float, "u_float") -self.t_any = self.ctxt.new_union_type ("any", - [self.u_signed, -self.u_float]) +max_args, initial_locs = self.make_JITFRAME
[pypy-commit] pypy libgccjit-backend: Fix test_finish
Author: David Malcolm Branch: libgccjit-backend Changeset: r75072:946fdf6ef9d7 Date: 2014-12-22 16:57 -0500 http://bitbucket.org/pypy/pypy/changeset/946fdf6ef9d7/ Log:Fix test_finish diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -399,7 +399,7 @@ #src_ptr_rvalue = self.ctxt.new_cast(src_ptr_rvalue, self.t_float.get_pointer()) #src_rvalue = self.ctxt.new_dereference(src_ptr_rvalue) # or do it as a union -field = self.get_union_field_for_box(arg) +field = self.get_union_field_for_expr(arg) src_rvalue = self.get_arg_as_lvalue(idx).access_field(field).as_rvalue() # FIXME: this may need a cast: #src_rvalue = self.ctxt.new_cast(src_rvalue, self.t_float) @@ -476,13 +476,13 @@ else: raise ValueError('unhandled box: %s %s' % (box, type(box))) -def get_union_field_for_box(self, box): -if isinstance(box, BoxInt): +def get_union_field_for_expr(self, expr): +if isinstance(expr, (BoxInt, ConstInt)): return self.u_signed; -elif isinstance(box, BoxFloat): +elif isinstance(expr, (BoxFloat, ConstFloat)): return self.u_float; else: -raise ValueError('unhandled box: %s %s' % (box, type(box))) +raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) # Handling of specific ResOperation subclasses: each one is # a method named "emit_foo", where "foo" is the str() of the resop. @@ -614,8 +614,8 @@ # Write outputs back: for idx, arg in enumerate(args): if arg is not None: -src_rvalue = self.get_box_as_lvalue(arg).as_rvalue() -field = self.get_union_field_for_box(arg) +src_rvalue = self.expr_to_rvalue(arg) +field = self.get_union_field_for_expr(arg) dst_lvalue = self.get_arg_as_lvalue(idx).access_field(field) self.b_current.add_assignment(dst_lvalue, src_rvalue) else: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_field_basic to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75081:7842cdbb5db6 Date: 2014-12-23 09:21 -0500 http://bitbucket.org/pypy/pypy/changeset/7842cdbb5db6/ Log:Get test_field_basic to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -4,7 +4,7 @@ from rpython.jit.backend.llsupport.regalloc import FrameManager from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type -from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat +from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr from rpython.jit.metainterp.resoperation import * from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr from rpython.rtyper.lltypesystem.rffi import * @@ -196,12 +196,15 @@ self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) +self.t_char_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_CHAR).get_pointer() self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") self.u_float = self.ctxt.new_field(self.t_float, "u_float") +self.u_ptr = self.ctxt.new_field(self.t_void_ptr, "u_ptr") self.t_any = self.ctxt.new_union_type ("any", [self.u_signed, -self.u_float]) +self.u_float, +self.u_ptr]) def setup(self, looptoken): allblocks = self.get_asmmemmgr_blocks(looptoken) @@ -429,7 +432,7 @@ print(' %s' % expr.__dict__) """ -if isinstance(expr, (BoxInt, BoxFloat)): +if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)): return self.get_box_as_lvalue(expr).as_rvalue() elif isinstance(expr, ConstInt): #print('value: %r' % expr.value) @@ -441,6 +444,11 @@ #print('type(value): %r' % type(expr.value)) return self.ctxt.new_rvalue_from_double(self.t_float, expr.value)#r_double(expr.value)) +elif isinstance(expr, ConstPtr): +#print('value: %r' % expr.value) +#print('type(value): %r' % type(expr.value)) +return self.ctxt.new_rvalue_from_ptr(self.t_void_ptr, + expr.value) raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) def get_box_as_lvalue(self, box): @@ -463,7 +471,7 @@ print(' %s' % dir(expr)) print(' %s' % expr.__dict__) """ -if isinstance(expr, (BoxInt, BoxFloat)): +if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)): return self.get_box_as_lvalue(expr) raise ValueError('unhandled expr: %s' % expr) @@ -473,6 +481,8 @@ return self.t_Signed; elif isinstance(box, BoxFloat): return self.t_float; +elif isinstance(box, BoxPtr): +return self.t_void_ptr; else: raise ValueError('unhandled box: %s %s' % (box, type(box))) @@ -481,6 +491,8 @@ return self.u_signed; elif isinstance(expr, (BoxFloat, ConstFloat)): return self.u_float; +elif isinstance(expr, (BoxPtr, ConstPtr)): +return self.u_ptr; else: raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) @@ -788,3 +800,72 @@ self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GT) def emit_float_ge(self, resop): self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) + +def impl_get_lvalue_for_field(self, ptr_expr, fielddescr): +assert isinstance(ptr_expr, (BoxPtr, ConstPtr)) +#print(fielddescr) +#print(dir(fielddescr)) +#print('fielddescr.field_size: %r' % fielddescr.field_size) + +ptr = self.expr_to_rvalue(ptr_expr) + +# Cast to (char *) so we can use offset: +# ((char *)ARG0) +ptr = self.ctxt.new_cast(ptr, self.t_char_ptr) + +# ((char *)ARG0)[offset] +ptr = self.ctxt.new_array_access( +ptr, +self.ctxt.new_rvalue_from_int(self.t_Signed, + r_int(fielddescr.offset))) + +# (char **)(((char *)ARG0)[offset]) +field_ptr_address = ptr.get_address () + +# ...and cast back to the correct type: +if fielddescr.is_pointer_field(): +t_field = self.t_void_ptr +elif fieldd
[pypy-commit] pypy libgccjit-backend: Get test_passing_guards to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75082:cf9335135432 Date: 2014-12-23 09:49 -0500 http://bitbucket.org/pypy/pypy/changeset/cf9335135432/ Log:Get test_passing_guards to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -3,7 +3,9 @@ from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.regalloc import FrameManager from rpython.jit.backend.model import CompiledLoopToken -from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type +from rpython.jit.backend.libgccjit.rffi_bindings import ( +make_eci, Library, make_param_array, make_field_array, Context, Type, +RValue) from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr from rpython.jit.metainterp.resoperation import * from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr @@ -572,13 +574,10 @@ # GUARD_* -def _impl_guard(self, resop, istrue): -print(resop) -print(resop.__dict__) +def _impl_guard(self, resop, istrue, boolval): +assert isinstance(boolval, RValue) b_true = self.fn.new_block("on_true_at_%s" % resop) b_false = self.fn.new_block("on_false_at_%s" % resop) -boolval = self.ctxt.new_cast(self.expr_to_rvalue(resop._arg0), - self.t_bool) self.b_current.end_with_conditional(boolval, b_true, b_false) @@ -616,11 +615,39 @@ # Further operations go into the guard success block in the original fn: self.b_current = b_guard_success +def _impl_bool_guard(self, resop, istrue): +boolval = self.ctxt.new_cast(self.expr_to_rvalue(resop._arg0), + self.t_bool) +self._impl_guard(resop, istrue, boolval) + def emit_guard_true(self, resop): -self._impl_guard(resop, r_int(1)) +self._impl_bool_guard(resop, r_int(1)) def emit_guard_false(self, resop): -self._impl_guard(resop, r_int(0)) +self._impl_bool_guard(resop, r_int(0)) + +def emit_guard_value(self, resop): +boolval = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_EQ, +self.expr_to_rvalue(resop._arg0), +self.expr_to_rvalue(resop._arg1)) +self._impl_guard(resop, r_int(1), boolval) + +def emit_guard_nonnull(self, resop): +ptr_rvalue = self.expr_to_rvalue(resop._arg0) +boolval = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_NE, +ptr_rvalue, +self.ctxt.null(ptr_rvalue.get_type())) +self._impl_guard(resop, r_int(1), boolval) + +def emit_guard_isnull(self, resop): +ptr_rvalue = self.expr_to_rvalue(resop._arg0) +boolval = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_EQ, +ptr_rvalue, +self.ctxt.null(ptr_rvalue.get_type())) +self._impl_guard(resop, r_int(1), boolval) def _impl_write_output_args(self, params, args): # Write outputs back: diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -241,6 +241,9 @@ (self.GCC_JIT_RVALUE_P, 'gcc_jit_lvalue_as_rvalue', [self.GCC_JIT_LVALUE_P]), +(self.GCC_JIT_TYPE_P, + 'gcc_jit_rvalue_get_type', [self.GCC_JIT_RVALUE_P]), + # Integer constants. (self.GCC_JIT_RVALUE_P, 'gcc_jit_context_new_rvalue_from_int', [self.GCC_JIT_CONTEXT_P, @@ -266,6 +269,10 @@ VOIDP]), (self.GCC_JIT_RVALUE_P, + 'gcc_jit_context_null', [self.GCC_JIT_CONTEXT_P, + self.GCC_JIT_TYPE_P]), + +(self.GCC_JIT_RVALUE_P, 'gcc_jit_context_new_unary_op', [self.GCC_JIT_CONTEXT_P, self.GCC_JIT_LOCATION_P, INT, # enum gcc_jit_unary_op op, @@ -610,6 +617,13 @@ type_.inner_type, llvalue)) + +def null(self, pointer_type): +return RValue(self.lib, + self, + self.lib.gcc_jit_context_null(self.inner_ctxt, +pointer_type.inner_type)) + def n
[pypy-commit] pypy libgccjit-backend: Work towards implementing GUARD_CLASS and GUARD_NONNULL_CLASS
Author: David Malcolm Branch: libgccjit-backend Changeset: r75084:45e9e4b77db5 Date: 2014-12-23 10:51 -0500 http://bitbucket.org/pypy/pypy/changeset/45e9e4b77db5/ Log:Work towards implementing GUARD_CLASS and GUARD_NONNULL_CLASS diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -422,6 +422,8 @@ # Compile the operation itself... methname = 'emit_%s' % op.getopname() +if not hasattr(self, methname): +raise NotImplementedError('resop not yet implemented: %s' % op) getattr(self, methname) (op) def expr_to_rvalue(self, expr): @@ -439,6 +441,11 @@ elif isinstance(expr, ConstInt): #print('value: %r' % expr.value) #print('type(value): %r' % type(expr.value)) +if isinstance(expr.value, llmemory.AddressAsInt): +assert isinstance(expr.value.adr, llmemory.fakeaddress) +assert isinstance(expr.value.adr.ptr, lltype._ptr) +return self.ctxt.new_rvalue_from_ptr(self.t_void_ptr, + expr.value.adr.ptr) return self.ctxt.new_rvalue_from_long(self.t_Signed, r_long(expr.value)) elif isinstance(expr, ConstFloat): @@ -451,7 +458,7 @@ #print('type(value): %r' % type(expr.value)) return self.ctxt.new_rvalue_from_ptr(self.t_void_ptr, expr.value) -raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) +raise NotImplementedError('unhandled expr: %s %s' % (expr, type(expr))) def get_box_as_lvalue(self, box): if box not in self.lvalue_for_box: @@ -476,7 +483,7 @@ if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)): return self.get_box_as_lvalue(expr) -raise ValueError('unhandled expr: %s' % expr) +raise NotImplementedError('unhandled expr: %s' % expr) def get_type_for_box(self, box): if isinstance(box, BoxInt): @@ -486,7 +493,7 @@ elif isinstance(box, BoxPtr): return self.t_void_ptr; else: -raise ValueError('unhandled box: %s %s' % (box, type(box))) +raise NotImplementedError('unhandled box: %s %s' % (box, type(box))) def get_union_field_for_expr(self, expr): if isinstance(expr, (BoxInt, ConstInt)): @@ -496,7 +503,7 @@ elif isinstance(expr, (BoxPtr, ConstPtr)): return self.u_ptr; else: -raise ValueError('unhandled expr: %s %s' % (expr, type(expr))) +raise NotImplementedError('unhandled expr: %s %s' % (expr, type(expr))) # Handling of specific ResOperation subclasses: each one is # a method named "emit_foo", where "foo" is the str() of the resop. @@ -633,6 +640,21 @@ self.expr_to_rvalue(resop._arg1)) self._impl_guard(resop, r_int(1), boolval) +def emit_guard_class(self, resop): +print(resop) +print(dir(resop)) +vtable_offset = self.cpu.vtable_offset +print('vtable_offset: %r' % vtable_offset) +assert vtable_offset is not None +lvalue_obj_vtable = self.impl_get_lvalue_at_offset_from_ptr( +resop._arg0, r_int(vtable_offset), self.t_void_ptr) +print('resop._arg1: %r' % resop._arg1) +boolval = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_EQ, +lvalue_obj_vtable.as_rvalue(), +self.expr_to_rvalue(resop._arg1)) +self._impl_guard(resop, r_int(1), boolval) + def emit_guard_nonnull(self, resop): ptr_rvalue = self.expr_to_rvalue(resop._arg0) boolval = self.ctxt.new_comparison( @@ -828,12 +850,7 @@ def emit_float_ge(self, resop): self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) -def impl_get_lvalue_for_field(self, ptr_expr, fielddescr): -assert isinstance(ptr_expr, (BoxPtr, ConstPtr)) -#print(fielddescr) -#print(dir(fielddescr)) -#print('fielddescr.field_size: %r' % fielddescr.field_size) - +def impl_get_lvalue_at_offset_from_ptr(self, ptr_expr, ll_offset, t_field): ptr = self.expr_to_rvalue(ptr_expr) # Cast to (char *) so we can use offset: @@ -843,22 +860,11 @@ # ((char *)ARG0)[offset] ptr = self.ctxt.new_array_access( ptr, -self.ctxt.new_rvalue_from_int(self.t_Signed, - r_int(fielddescr.offset))) +self.ctxt.new_rvalue_from_int(self.t_Signed, ll_offset)) # (char **)(((char *)ARG0)[offset]) field_ptr_address = ptr.get_address () -# ...and cast back to the correct type: -if fielddescr.is_po
[pypy-commit] pypy libgccjit-backend: Fix test_rffi_bindings.py
Author: David Malcolm Branch: libgccjit-backend Changeset: r75086:988365232237 Date: 2014-12-23 11:38 -0500 http://bitbucket.org/pypy/pypy/changeset/988365232237/ Log:Fix test_rffi_bindings.py diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -31,7 +31,7 @@ from rpython.rtyper.lltypesystem import lltype def make_eci(): -eci = ExternalCompilationInfo(includes=['libgccjit.h'], +eci = ExternalCompilationInfo(includes=['stdio.h', 'libgccjit.h'], include_dirs=[INCLUDE_DIR], libraries=['gccjit'], library_dirs=[LIB_DIR]) @@ -144,6 +144,9 @@ # Types +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_type_as_object', [self.GCC_JIT_TYPE_P]), + (self.GCC_JIT_TYPE_P, 'gcc_jit_context_get_type', [self.GCC_JIT_CONTEXT_P, INT]), @@ -161,7 +164,11 @@ self.GCC_JIT_LOCATION_P, self.GCC_JIT_TYPE_P, CCHARP]), -(self.GCC_JIT_STRUCT_P, + +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_field_as_object', [self.GCC_JIT_FIELD_P]), + + (self.GCC_JIT_STRUCT_P, 'gcc_jit_context_new_struct_type', [self.GCC_JIT_CONTEXT_P, self.GCC_JIT_LOCATION_P, CCHARP, @@ -204,6 +211,8 @@ self.GCC_JIT_LOCATION_P, self.GCC_JIT_TYPE_P, CCHARP]), +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_param_as_object', [self.GCC_JIT_PARAM_P]), (self.GCC_JIT_LVALUE_P, 'gcc_jit_param_as_lvalue', [self.GCC_JIT_PARAM_P]), (self.GCC_JIT_RVALUE_P, @@ -233,6 +242,8 @@ (self.GCC_JIT_BLOCK_P, 'gcc_jit_function_new_block', [self.GCC_JIT_FUNCTION_P, CCHARP]), +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_block_as_object', [self.GCC_JIT_BLOCK_P]), # lvalues, rvalues and expressions. @@ -245,9 +256,15 @@ self.GCC_JIT_TYPE_P, CCHARP]), +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_lvalue_as_object', [self.GCC_JIT_LVALUE_P]), + (self.GCC_JIT_RVALUE_P, 'gcc_jit_lvalue_as_rvalue', [self.GCC_JIT_LVALUE_P]), +(self.GCC_JIT_OBJECT_P, + 'gcc_jit_rvalue_as_object', [self.GCC_JIT_RVALUE_P]), + (self.GCC_JIT_TYPE_P, 'gcc_jit_rvalue_get_type', [self.GCC_JIT_RVALUE_P]), @@ -773,7 +790,8 @@ class Type(Object): def __init__(self, lib, ctxt, inner_type): -Object.__init__(self, lib, ctxt, inner_type) +Object.__init__(self, lib, ctxt, +lib.gcc_jit_type_as_object(inner_type)) self.inner_type = inner_type def get_pointer(self): @@ -783,12 +801,15 @@ class Field(Object): def __init__(self, lib, ctxt, inner_field): -Object.__init__(self, lib, ctxt, inner_field) +Object.__init__(self, lib, ctxt, +lib.gcc_jit_field_as_object(inner_field)) self.inner_field = inner_field class Struct(Object): def __init__(self, lib, ctxt, inner_struct): -Object.__init__(self, lib, ctxt, inner_struct) +Object.__init__(self, lib, ctxt, +lib.gcc_jit_type_as_object( +lib.gcc_jit_struct_as_type(inner_struct))) self.inner_struct = inner_struct def as_type(self): @@ -811,7 +832,8 @@ class RValue(Object): def __init__(self, lib, ctxt, inner_rvalue): -Object.__init__(self, lib, ctxt, inner_rvalue) +Object.__init__(self, lib, ctxt, +lib.gcc_jit_rvalue_as_object(inner_rvalue)) self.inner_rvalue = inner_rvalue def get_type(self): @@ -836,7 +858,8 @@ class LValue(Object): def __init__(self, lib, ctxt, inner_lvalue): -Object.__init__(self, lib, ctxt, inner_lvalue) +Object.__init__(self, lib, ctxt, +lib.gcc_jit_lvalue_as_object(inner_lvalue)) self.inner_lvalue = inner_lvalue def as_rvalue(self): @@ -861,7 +884,8 @@ class Param(Object): def __init__(sel
[pypy-commit] pypy libgccjit-backend: Whitespace cleanups
Author: David Malcolm Branch: libgccjit-backend Changeset: r75085:a2a235719797 Date: 2014-12-23 11:07 -0500 http://bitbucket.org/pypy/pypy/changeset/a2a235719797/ Log:Whitespace cleanups diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -6,9 +6,11 @@ from rpython.jit.backend.libgccjit.rffi_bindings import ( make_eci, Library, make_param_array, make_field_array, Context, Type, RValue) -from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr +from rpython.jit.metainterp.history import ( +BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr) from rpython.jit.metainterp.resoperation import * -from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr +from rpython.rtyper.annlowlevel import ( +llhelper, cast_instance_to_gcref, cast_object_to_ptr) from rpython.rtyper.lltypesystem.rffi import * from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory @@ -34,10 +36,10 @@ self.rffi_fn = rffi_fn self.patchpoints = [] -def new_block(self, name): +def new_block(self, name): return self.rffi_fn.new_block(name) -def new_local(self, type_, name): +def new_local(self, type_, name): return self.rffi_fn.new_local(type_, name) class Patchpoint: @@ -69,7 +71,7 @@ 0x7fffeb7086d0 <+16>: jle0x7fffeb7086c8 0x7fffeb7086d2 <+18>: mov%rax,0x48(%rdi) - 0x7fffeb7086d6 <+22>: mov0x2008fb(%rip),%rax# 0x7fffeb908fd8 + 0x7fffeb7086d6 <+22>: mov0x2008fb(%rip),%rax # 0x7fffeb908fd8 0x7fffeb7086dd <+29>: mov(%rax),%rax 0x7fffeb7086e0 <+32>: jmpq *%rax """ @@ -77,10 +79,10 @@ self.failure_params = Params(assembler) self.serial = assembler.num_guard_failure_fns assembler.num_guard_failure_fns += 1 -self.t_fn_ptr_type = ( -assembler.ctxt.new_function_ptr_type (assembler.t_jit_frame_ptr, - self.failure_params.paramtypes, - r_int(0))) +self.t_fn_ptr_type = assembler.ctxt.new_function_ptr_type ( +assembler.t_jit_frame_ptr, +self.failure_params.paramtypes, +r_int(0)) # Create the function ptr # Globals are zero-initialized, so we'll need to # write in the ptr to the initial handler before the loop is called, @@ -169,36 +171,44 @@ def make_context(self): self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() if 0: - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, +r_int(1)) if 0: - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, +r_int(1)) if 1: -self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, +r_int(1)) if 1: - self.ctxt.set_int_option(self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, - r_int(2)) +self.ctxt.set_int_option( +self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, +r_int(2)) if 1: - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, +r_int(1)) if 1: - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, +r_int(1)) if 0: - self.ctxt.set_bool_option(self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, - r_int(1)) +self.ctxt.set_bool_option( +self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, +r_int(1)) self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), r_int(1)) self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed),
[pypy-commit] pypy libgccjit-backend: Get test_passing_guard_class and test_failing_guard_class to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75087:8b245e7f33c1 Date: 2014-12-23 11:54 -0500 http://bitbucket.org/pypy/pypy/changeset/8b245e7f33c1/ Log:Get test_passing_guard_class and test_failing_guard_class to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -659,14 +659,10 @@ self._impl_guard(resop, r_int(1), boolval) def emit_guard_class(self, resop): -print(resop) -print(dir(resop)) vtable_offset = self.cpu.vtable_offset -print('vtable_offset: %r' % vtable_offset) assert vtable_offset is not None lvalue_obj_vtable = self.impl_get_lvalue_at_offset_from_ptr( resop._arg0, r_int(vtable_offset), self.t_void_ptr) -print('resop._arg1: %r' % resop._arg1) boolval = self.ctxt.new_comparison( self.lib.GCC_JIT_COMPARISON_EQ, lvalue_obj_vtable.as_rvalue(), @@ -689,6 +685,39 @@ self.ctxt.null(ptr_rvalue.get_type())) self._impl_guard(resop, r_int(1), boolval) +def emit_guard_nonnull_class(self, resop): +# GUARD_NONNULL_CLASS means: +# "check that _arg0 (instance ptr) is non-NULL +#and then (if non-NULL) +# check the ptr's vtable for equality against _arg1 +#if both true then guard is true, +#if either fails then guard has failed" + +# Hence we need two conditionals; we can do this +# using a logical AND of the two conditionals; +# libgccjit should shortcircuit things appropriately. + +ptr_rvalue = self.expr_to_rvalue(resop._arg0) +boolval_is_nonnull = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_NE, +ptr_rvalue, +self.ctxt.null(ptr_rvalue.get_type())) + +vtable_offset = self.cpu.vtable_offset +assert vtable_offset is not None +lvalue_obj_vtable = self.impl_get_lvalue_at_offset_from_ptr( +resop._arg0, r_int(vtable_offset), self.t_void_ptr) +boolval_vtable_equality = self.ctxt.new_comparison( +self.lib.GCC_JIT_COMPARISON_EQ, +lvalue_obj_vtable.as_rvalue(), +self.expr_to_rvalue(resop._arg1)) + +self._impl_guard(resop, r_int(1), + self.ctxt.new_binary_op( + self.lib.GCC_JIT_BINARY_OP_LOGICAL_AND, + self.t_bool, + boolval_is_nonnull, boolval_vtable_equality)) + def _impl_write_output_args(self, params, args): # Write outputs back: for idx, arg in enumerate(args): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_int_operations to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75089:d0c24c40d739 Date: 2014-12-23 13:04 -0500 http://bitbucket.org/pypy/pypy/changeset/d0c24c40d739/ Log:Get test_int_operations to pass Implement remaining missing operations needed by test_int_operations (UINT_ comparisons, unary INT_ ops). FWIW, creates 778 loops. diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -875,7 +875,29 @@ def emit_int_ge(self, resop): self.impl_int_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) -# "UINT" comparisons: TODO +# "UINT" comparisons: +def impl_uint_cmp(self, resop, gcc_jit_comparison): +rval0 = self.expr_to_rvalue(resop._arg0) +rval1 = self.expr_to_rvalue(resop._arg1) +rval0 = self.ctxt.new_cast(rval0, self.t_UINT) +rval1 = self.ctxt.new_cast(rval1, self.t_UINT) +lvalres = self.expr_to_lvalue(resop.result) +resop_cmp = ( +self.ctxt.new_cast( +self.ctxt.new_comparison(gcc_jit_comparison, + rval0, rval1), +self.t_Signed) +) +self.b_current.add_assignment(lvalres, + resop_cmp) +def emit_uint_lt(self, resop): +self.impl_uint_cmp(resop, self.lib.GCC_JIT_COMPARISON_LT) +def emit_uint_le(self, resop): +self.impl_uint_cmp(resop, self.lib.GCC_JIT_COMPARISON_LE) +def emit_uint_gt(self, resop): +self.impl_uint_cmp(resop, self.lib.GCC_JIT_COMPARISON_GT) +def emit_uint_ge(self, resop): +self.impl_uint_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) # "FLOAT" comparisons: def impl_float_cmp(self, resop, gcc_jit_comparison): @@ -904,6 +926,36 @@ def emit_float_ge(self, resop): self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE) +# Unary "INT" operations: +def _impl_int_unaryop(self, resop, gcc_jit_unary_op): +rvalue = self.expr_to_rvalue(resop._arg0) +lvalres = self.expr_to_lvalue(resop.result) +unaryop_expr = self.ctxt.new_unary_op(gcc_jit_unary_op, + self.t_Signed, + rvalue) +self.b_current.add_assignment(lvalres, unaryop_expr) + +def emit_int_is_zero(self, resop): +self._impl_int_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_LOGICAL_NEGATE) +def emit_int_is_true(self, resop): +rvalarg = self.expr_to_rvalue(resop._arg0) +lvalres = self.expr_to_lvalue(resop.result) +resop_cmp = ( +self.ctxt.new_cast( +self.ctxt.new_comparison(self.lib.GCC_JIT_COMPARISON_NE, + rvalarg, + self.ctxt.zero(self.t_Signed)), +self.t_Signed) +) +self.b_current.add_assignment(lvalres, + resop_cmp) +def emit_int_neg(self, resop): +self._impl_int_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_MINUS) +def emit_int_invert(self, resop): +self._impl_int_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_BITWISE_NEGATE) + +# + def impl_get_lvalue_at_offset_from_ptr(self, ptr_expr, ll_offset, t_field): ptr = self.expr_to_rvalue(ptr_expr) diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -633,6 +633,13 @@ type_.inner_type, llvalue)) +def zero(self, numeric_type): +return RValue(self.lib, + self, + self.lib.gcc_jit_context_zero( + self.inner_ctxt, + numeric_type.inner_type)) + def new_rvalue_from_double(self, type_, llvalue): return RValue(self.lib, self, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Fix a MemoryError issue seen running test_int_operations
Author: David Malcolm Branch: libgccjit-backend Changeset: r75088:70555a2aeb22 Date: 2014-12-23 12:37 -0500 http://bitbucket.org/pypy/pypy/changeset/70555a2aeb22/ Log:Fix a MemoryError issue seen running test_int_operations test_int_operations was failing after compiling about 200 loops with a MemoryError, unable to fulfil an allocation of 129GB of RAM. Fix it by cleaning up the datablockwrapper after each compile. diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -261,6 +261,9 @@ clt.frame_info.update_frame_depth(baseofs, max_args) +self.datablockwrapper.done() # finish using cpu.asmmemmgr +self.datablockwrapper = None + self.ctxt.dump_to_file("/tmp/%s.c" % loopname, r_int(1)) #raise foo @@ -296,6 +299,10 @@ self.num_bridges += 1 self.make_function(name, inputargs, operations) + +self.datablockwrapper.done() # finish using cpu.asmmemmgr +self.datablockwrapper = None + self.ctxt.dump_to_file("/tmp/%s.c" % name, r_int(1)) jit_result = self.ctxt.compile() self.ctxt.release() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_ovf_operations and test_ovf_operations_reversed to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75092:dfab06318973 Date: 2014-12-23 15:41 -0500 http://bitbucket.org/pypy/pypy/changeset/dfab06318973/ Log:Get test_ovf_operations and test_ovf_operations_reversed to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -14,6 +14,11 @@ from rpython.rtyper.lltypesystem.rffi import * from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory +# Global state +num_anon_loops = 0 +num_guard_failure_fns = 0 +num_bridges = 0 + class Params: def __init__(self, assembler): self.paramlist = [] @@ -77,8 +82,9 @@ """ def __init__(self, assembler): self.failure_params = Params(assembler) -self.serial = assembler.num_guard_failure_fns -assembler.num_guard_failure_fns += 1 +global num_guard_failure_fns +self.serial = num_guard_failure_fns +num_guard_failure_fns += 1 self.t_fn_ptr_type = assembler.ctxt.new_function_ptr_type ( assembler.t_jit_frame_ptr, self.failure_params.paramtypes, @@ -155,10 +161,6 @@ self.propagate_exception_path = 0 #self.teardown() -self.num_anon_loops = 0 -self.num_guard_failure_fns = 0 -self.num_bridges = 0 - self.sizeof_signed = rffi.sizeof(lltype.Signed) self.label_for_descr = {} self.block_for_label_descr = {} @@ -251,8 +253,9 @@ self.lvalue_for_box = {} if not loopname: -loopname = 'anonloop_%i' % self.num_anon_loops -self.num_anon_loops += 1 +global num_anon_loops +loopname = 'anonloop_%i' % num_anon_loops +num_anon_loops += 1 print(" loopname: %r" % loopname) self.make_function(loopname, inputargs, operations) @@ -295,8 +298,9 @@ operations) self.lvalue_for_box = {} -name = "bridge_%i" % self.num_bridges -self.num_bridges += 1 +global num_bridges +name = "bridge_%i" % num_bridges +num_bridges += 1 self.make_function(name, inputargs, operations) @@ -399,6 +403,7 @@ self.loop_params.paramlist, r_int(0))) +self.lvalue_ovf = self.fn.new_local(self.t_bool, "ovf") self.b_current = self.fn.new_block("initial") # Add an initial comment summarizing the loop or bridge: @@ -725,6 +730,14 @@ self.t_bool, boolval_is_nonnull, boolval_vtable_equality)) +def emit_guard_no_overflow(self, resop): +self._impl_guard(resop, r_int(0), + self.lvalue_ovf.as_rvalue()) + +def emit_guard_overflow(self, resop): +self._impl_guard(resop, r_int(1), + self.lvalue_ovf.as_rvalue()) + def _impl_write_output_args(self, params, args): # Write outputs back: for idx, arg in enumerate(args): @@ -1031,3 +1044,29 @@ # ... = ARG1, self.ctxt.new_cast(self.expr_to_rvalue(resop._arg1), t_field)) + +# "INT_*_OVF" operations: +def _impl_int_ovf(self, resop, builtin_name): +""" +We implement ovf int binops using GCC builtins, +generating a call of the form: + ovf = __builtin_FOO_overflow(arg0, arg1, &result); +This is then optimized by gcc's builtins.c +fold_builtin_arith_overflow. +""" +rval0 = self.expr_to_rvalue(resop._arg0) +rval1 = self.expr_to_rvalue(resop._arg1) +lvalres = self.expr_to_lvalue(resop.result) +builtin_fn = self.ctxt.get_builtin_function(builtin_name) +# "ovf = __builtin_FOO_overflow(arg0, arg1, &result);" +call = self.ctxt.new_call(builtin_fn, + [rval0, + rval1, + lvalres.get_address()]) +self.b_current.add_assignment(self.lvalue_ovf, call) +def emit_int_add_ovf(self, resop): +self._impl_int_ovf(resop, '__builtin_add_overflow') +def emit_int_sub_ovf(self, resop): +self._impl_int_ovf(resop, '__builtin_sub_overflow') +def emit_int_mul_ovf(self, resop): +self._impl_int_ovf(resop, '__builtin_mul_overflow') diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -230,6 +230,10 @@ self.PARAM_P_P, INT]), +(self.GCC_JIT_FUNCTION_P, + 'gcc_jit_context_get_bu
[pypy-commit] pypy libgccjit-backend: Get test_noops to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75094:5e659ec2cfd9 Date: 2014-12-23 16:35 -0500 http://bitbucket.org/pypy/pypy/changeset/5e659ec2cfd9/ Log:Get test_noops to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -1067,6 +1067,11 @@ self.ctxt.new_cast(self.expr_to_rvalue(resop._arg1), t_field)) +def emit_debug_merge_point(self, resop): +pass # noop +def emit_jit_debug(self, resop): +pass # noop + # "INT_*_OVF" operations: def _impl_int_ovf(self, resop, builtin_name): """ ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_cast_int_to_ptr and test_cast_ptr_to_int to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75093:4c394d19f7b9 Date: 2014-12-23 16:25 -0500 http://bitbucket.org/pypy/pypy/changeset/4c394d19f7b9/ Log:Get test_cast_int_to_ptr and test_cast_ptr_to_int to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -849,7 +849,7 @@ def emit_float_abs(self, resop): self._impl_float_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_ABS) -# "CAST_" operations: +# "CAST_" operations for "FLOAT": def emit_cast_float_to_int(self, resop): rvalue = self.expr_to_rvalue(resop._arg0) lvalres = self.expr_to_lvalue(resop.result) @@ -967,6 +967,28 @@ def emit_int_invert(self, resop): self._impl_int_unaryop(resop, self.lib.GCC_JIT_UNARY_OP_BITWISE_NEGATE) +# "CAST_" operations for "INT" vs "PTR": +def emit_cast_ptr_to_int(self, resop): +rvalue_in = self.expr_to_rvalue(resop._arg0) +lvalue_tmp = self.fn.new_local(self.t_any, "tmp") +lvalue_result = self.expr_to_lvalue(resop.result) +self.b_current.add_assignment( +lvalue_tmp.access_field(self.u_ptr), +rvalue_in) +self.b_current.add_assignment( +lvalue_result, +lvalue_tmp.as_rvalue().access_field(self.u_signed)) +def emit_cast_int_to_ptr(self, resop): +rvalue_in = self.expr_to_rvalue(resop._arg0) +lvalue_tmp = self.fn.new_local(self.t_any, "tmp") +lvalue_result = self.expr_to_lvalue(resop.result) +self.b_current.add_assignment( +lvalue_tmp.access_field(self.u_signed), +rvalue_in) +self.b_current.add_assignment( +lvalue_result, +lvalue_tmp.as_rvalue().access_field(self.u_ptr)) + # def impl_get_lvalue_at_offset_from_ptr(self, ptr_expr, ll_offset, t_field): diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -356,6 +356,11 @@ self.GCC_JIT_LOCATION_P, self.GCC_JIT_FIELD_P]), +(self.GCC_JIT_RVALUE_P, + 'gcc_jit_rvalue_access_field', [self.GCC_JIT_RVALUE_P, + self.GCC_JIT_LOCATION_P, + self.GCC_JIT_FIELD_P]), + (self.GCC_JIT_LVALUE_P, 'gcc_jit_rvalue_dereference_field', [self.GCC_JIT_RVALUE_P, self.GCC_JIT_LOCATION_P, @@ -859,6 +864,14 @@ self, self.lib.gcc_jit_rvalue_get_type(self.inner_rvalue)) +def access_field(self, field): +return RValue(self.lib, + self, + self.lib.gcc_jit_rvalue_access_field( + self.inner_rvalue, + self.lib.null_location_ptr, + field.inner_field)) + def dereference_field(self, field): return LValue(self.lib, self, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Initial implementation of rop.CALL
Author: David Malcolm Branch: libgccjit-backend Changeset: r75096:a466f0d20644 Date: 2014-12-23 17:13 -0500 http://bitbucket.org/pypy/pypy/changeset/a466f0d20644/ Log:Initial implementation of rop.CALL Working test_runner.py "test_call*" testcases with this commit: test_call test_call_many_arguments test_call_stack_alignment test_call_with_const_floats Failing: test_call_box_func test_call_to_c_function test_call_to_c_function_with_callback test_call_release_gil_return_types test_call_release_gil_variable_function_and_arguments diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -1,6 +1,7 @@ from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.llsupport.assembler import BaseAssembler from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.llsupport.descr import CallDescr from rpython.jit.backend.llsupport.regalloc import FrameManager from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.backend.libgccjit.rffi_bindings import ( @@ -486,7 +487,7 @@ def get_box_as_lvalue(self, box): if box not in self.lvalue_for_box: self.lvalue_for_box[box] = ( -self.fn.new_local(self.get_type_for_box(box), +self.fn.new_local(self.get_type_for_expr(box), str(box))) return self.lvalue_for_box[box] @@ -508,15 +509,16 @@ raise NotImplementedError('unhandled expr: %s' % expr) -def get_type_for_box(self, box): -if isinstance(box, BoxInt): +def get_type_for_expr(self, expr): +if isinstance(expr, (BoxInt, ConstInt)): return self.t_Signed; -elif isinstance(box, BoxFloat): +elif isinstance(expr, (BoxFloat, ConstFloat)): return self.t_float; -elif isinstance(box, BoxPtr): +elif isinstance(expr, (BoxPtr, ConstPtr)): return self.t_void_ptr; else: -raise NotImplementedError('unhandled box: %s %s' % (box, type(box))) +raise NotImplementedError('unhandled expr: %s %s' + % (expr, type(expr))) def get_union_field_for_expr(self, expr): if isinstance(expr, (BoxInt, ConstInt)): @@ -1046,7 +1048,7 @@ self.b_current.add_assignment( lvalres, self.ctxt.new_cast(field_lvalue.as_rvalue(), - self.get_type_for_box(resop.result))) + self.get_type_for_expr(resop.result))) def emit_setfield_gc(self, resop): #print(repr(resop)) @@ -1069,6 +1071,53 @@ def emit_jit_debug(self, resop): pass # noop +# '_CANRAISE_FIRST', # - start of can_raise operations - +# '_CALL_FIRST', + +def emit_call(self, resop): +print(resop) +print(dir(resop)) +calldescr = resop.getdescr() +assert isinstance(calldescr, CallDescr) +#size = calldescr.get_result_size() +#sign = calldescr.is_result_signed() +print('resop.numargs(): %r' % resop.numargs()) +print('[resop.getarg(i) for i in range(resop.numargs())]: %r' + % [resop.getarg(i) for i in range(resop.numargs())]) +#print('resop.result: %r' % resop.result) + +print('resop.getarg(0): %r' % resop.getarg(0)) +print('dir(resop.getarg(0)): %r' % dir(resop.getarg(0))) +print('resop.getarg(0).type: %r' % resop.getarg(0).type) + +#arg0 is a fnptr +#arg1..N are the args to the call + +# FIXME: is the returntype of the fn always that of the result +# location? +returntype = self.get_type_for_expr(resop.result) + +# FIXME: are the params types always those of the input args? +paramtypes = [self.get_type_for_expr(resop.getarg(i)) + for i in range(1, resop.numargs())] + +fn_ptr_type = self.ctxt.new_function_ptr_type( +returntype, +paramtypes, +r_int(0)) # is_variadic +fn_ptr = self.ctxt.new_cast(self.expr_to_rvalue(resop.getarg(0)), +fn_ptr_type) +arg_rvalues = [self.expr_to_rvalue(resop.getarg(i)) + for i in range(1, resop.numargs())] +call = self.ctxt.new_call_through_ptr(fn_ptr, + arg_rvalues) +self.b_current.add_assignment(self.expr_to_lvalue(resop.result), + call) + +#'_CALL_LAST', +#'_CANRAISE_LAST', # - end of can_raise operations - + +# '_OVF_FIRST', # - start of is_ovf operations - # "INT_*_OVF" operations: def _impl_int_ovf(self, resop, builtin_name):
[pypy-commit] pypy libgccjit-backend: Fix test_compile_bridge
Author: David Malcolm Branch: libgccjit-backend Changeset: r75095:8fd7e004583c Date: 2014-12-23 16:45 -0500 http://bitbucket.org/pypy/pypy/changeset/8fd7e004583c/ Log:Fix test_compile_bridge diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -304,9 +304,6 @@ self.make_function(name, inputargs, operations) -self.datablockwrapper.done() # finish using cpu.asmmemmgr -self.datablockwrapper = None - self.ctxt.dump_to_file("/tmp/%s.c" % name, r_int(1)) jit_result = self.ctxt.compile() self.ctxt.release() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Fix test_field_basic
Author: David Malcolm Branch: libgccjit-backend Changeset: r75098:389b2c4ea525 Date: 2014-12-23 17:33 -0500 http://bitbucket.org/pypy/pypy/changeset/389b2c4ea525/ Log:Fix test_field_basic diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -1054,10 +1054,10 @@ #print(repr(resop)) assert isinstance(resop._arg0, (BoxPtr, ConstPtr)) #print(resop._arg1) - +fielddescr = resop.getdescr() field_lvalue = self.impl_get_lvalue_for_field( resop._arg0, -resop.getdescr()) +fielddescr) t_field = self.impl_get_type_for_field(fielddescr) self.b_current.add_assignment( ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_math_sqrt to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75099:01d5262da26e Date: 2014-12-23 19:57 -0500 http://bitbucket.org/pypy/pypy/changeset/01d5262da26e/ Log:Get test_math_sqrt to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -7,6 +7,7 @@ from rpython.jit.backend.libgccjit.rffi_bindings import ( make_eci, Library, make_param_array, make_field_array, Context, Type, RValue) +from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import ( BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr) from rpython.jit.metainterp.resoperation import * @@ -1075,24 +1076,47 @@ # '_CALL_FIRST', def emit_call(self, resop): -print(resop) -print(dir(resop)) +#print(resop) +#print(dir(resop)) calldescr = resop.getdescr() -assert isinstance(calldescr, CallDescr) -#size = calldescr.get_result_size() -#sign = calldescr.is_result_signed() -print('resop.numargs(): %r' % resop.numargs()) -print('[resop.getarg(i) for i in range(resop.numargs())]: %r' - % [resop.getarg(i) for i in range(resop.numargs())]) -#print('resop.result: %r' % resop.result) - -print('resop.getarg(0): %r' % resop.getarg(0)) -print('dir(resop.getarg(0)): %r' % dir(resop.getarg(0))) -print('resop.getarg(0).type: %r' % resop.getarg(0).type) +#assert isinstance(calldescr, CallDescr) +#print('dir(calldescr): %r' % dir(calldescr)) +#print('calldescr.__dict__: %r' % calldescr.__dict__) +#print('calldescr.extrainfo: %r' % calldescr.extrainfo) #arg0 is a fnptr #arg1..N are the args to the call +arg_rvalues = [self.expr_to_rvalue(resop.getarg(i)) + for i in range(1, resop.numargs())] + +#print('type(calldescr.extrainfo): %r' % type(calldescr.extrainfo)) +assert isinstance(calldescr.extrainfo, EffectInfo) +if calldescr.extrainfo.oopspecindex: +#print(' calldescr.extrainfo.oopspecindex: %r' +# % calldescr.extrainfo.oopspecindex) +if calldescr.extrainfo.oopspecindex == EffectInfo.OS_MATH_SQRT: +# Convert into a call to builtin: "double sqrt(double);" +fn = self.ctxt.get_builtin_function('sqrt') +call = self.ctxt.new_call(fn, + arg_rvalues) +self.b_current.add_assignment( +self.expr_to_lvalue(resop.result), +call) +return + +#size = calldescr.get_result_size() +#sign = calldescr.is_result_signed() +#print('resop.numargs(): %r' % resop.numargs()) +#print('[resop.getarg(i) for i in range(resop.numargs())]: %r' +# % [resop.getarg(i) for i in range(resop.numargs())]) +#print('resop.result: %r' % resop.result) + +#print('resop.getarg(0): %r' % resop.getarg(0)) +#print('dir(resop.getarg(0)): %r' % dir(resop.getarg(0))) +#print('resop.getarg(0).type: %r' % resop.getarg(0).type) + + # FIXME: is the returntype of the fn always that of the result # location? returntype = self.get_type_for_expr(resop.result) @@ -1107,8 +1131,6 @@ r_int(0)) # is_variadic fn_ptr = self.ctxt.new_cast(self.expr_to_rvalue(resop.getarg(0)), fn_ptr_type) -arg_rvalues = [self.expr_to_rvalue(resop.getarg(i)) - for i in range(1, resop.numargs())] call = self.ctxt.new_call_through_ptr(fn_ptr, arg_rvalues) self.b_current.add_assignment(self.expr_to_lvalue(resop.result), ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_increment_debug_counter to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75247:72cda48c154f Date: 2015-01-05 14:59 -0500 http://bitbucket.org/pypy/pypy/changeset/72cda48c154f/ Log:Get test_increment_debug_counter to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -192,11 +192,11 @@ self.ctxt.set_int_option( self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, r_int(2)) -if 0: +if 1: self.ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, r_int(1)) -if 0: +if 1: self.ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, r_int(1)) @@ -207,6 +207,7 @@ self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), r_int(1)) +self.t_signed_ptr = self.t_Signed.get_pointer() self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed), r_int(0)) self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME @@ -218,11 +219,13 @@ self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") self.u_float = self.ctxt.new_field(self.t_float, "u_float") -self.u_ptr = self.ctxt.new_field(self.t_void_ptr, "u_ptr") +self.u_void_ptr = self.ctxt.new_field(self.t_void_ptr, "u_void_ptr") +self.u_signed_ptr = self.ctxt.new_field(self.t_signed_ptr, "u_signed_ptr") self.t_any = self.ctxt.new_union_type ("any", [self.u_signed, self.u_float, -self.u_ptr]) +self.u_void_ptr, +self.u_signed_ptr]) def setup(self, looptoken): allblocks = self.get_asmmemmgr_blocks(looptoken) @@ -273,6 +276,8 @@ if 1: self.ctxt.dump_to_file("/tmp/%s.c" % loopname, r_int(1)) +if 0: +self.ctxt.dump_reproducer_to_file("/tmp/reproduce-%s.c" % loopname) #raise foo @@ -534,7 +539,7 @@ elif isinstance(expr, (BoxFloat, ConstFloat)): return self.u_float; elif isinstance(expr, (BoxPtr, ConstPtr)): -return self.u_ptr; +return self.u_void_ptr; else: raise NotImplementedError('unhandled expr: %s %s' % (expr, type(expr))) @@ -980,7 +985,7 @@ lvalue_tmp = self.fn.new_local(self.t_any, "tmp") lvalue_result = self.expr_to_lvalue(resop.result) self.b_current.add_assignment( -lvalue_tmp.access_field(self.u_ptr), +lvalue_tmp.access_field(self.u_void_ptr), rvalue_in) self.b_current.add_assignment( lvalue_result, @@ -994,7 +999,7 @@ rvalue_in) self.b_current.add_assignment( lvalue_result, -lvalue_tmp.as_rvalue().access_field(self.u_ptr)) +lvalue_tmp.as_rvalue().access_field(self.u_void_ptr)) # @@ -1021,6 +1026,9 @@ # +# +# '_ALWAYS_PURE_LAST', # - end of always_pure operations - + def impl_get_lvalue_at_offset_from_ptr(self, ptr_expr, ll_offset, t_field): ptr = self.expr_to_rvalue(ptr_expr) @@ -1081,6 +1089,25 @@ self.ctxt.new_cast(field_lvalue.as_rvalue(), self.get_type_for_expr(resop.result))) +# '_NOSIDEEFFECT_LAST', # - end of no_side_effect operations - + +def cast_signed_to_ptr_to_signed(self, rvalue): +tmp = self.fn.new_local(self.t_any, 'tmp') +self.b_current.add_assignment(tmp.access_field(self.u_signed), + rvalue) +return tmp.access_field(self.u_signed_ptr).as_rvalue() + +def emit_increment_debug_counter(self, resop): +# Equivalent of: +# signed *counter; +# (*counter)++; +ptr = self.expr_to_rvalue(resop._arg0) +ptr = self.cast_signed_to_ptr_to_signed(ptr) +self.b_current.add_assignment_op( +ptr.dereference(), +self.lib.GCC_JIT_BINARY_OP_PLUS, +self.ctxt.one(self.t_Signed)) + def emit_setfield_gc(self, resop): #print(repr(resop)) assert isinstance(resop._arg0, (BoxPtr, ConstPtr)) diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bindings.py @@ -124,6 +124,10 @@ CCHARP,
[pypy-commit] pypy libgccjit-backend: Provide a way to turn off the comments
Author: David Malcolm Branch: libgccjit-backend Changeset: r75245:a87b97f2b383 Date: 2014-12-24 05:20 -0500 http://bitbucket.org/pypy/pypy/changeset/a87b97f2b383/ Log:Provide a way to turn off the comments Running pytest under the profile module shows >50% wallclock time spent in str2charp, much of that in Block.add_comment. diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -123,7 +123,7 @@ self.set_handler(handler) def set_handler(self, handler): -print('set_handler(%r)' % handler) +#print('set_handler(%r)' % handler) # We want to write the equivalent of: #(*fn_ptr_ptr) = handler; @@ -172,6 +172,8 @@ eci = make_eci() self.lib = Library(eci) +self.add_comments = 1 + def make_context(self): self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() if 0: @@ -190,11 +192,11 @@ self.ctxt.set_int_option( self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, r_int(2)) -if 1: +if 0: self.ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, r_int(1)) -if 1: +if 0: self.ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, r_int(1)) @@ -269,7 +271,8 @@ self.datablockwrapper.done() # finish using cpu.asmmemmgr self.datablockwrapper = None -self.ctxt.dump_to_file("/tmp/%s.c" % loopname, r_int(1)) +if 1: +self.ctxt.dump_to_file("/tmp/%s.c" % loopname, r_int(1)) #raise foo @@ -306,7 +309,8 @@ self.make_function(name, inputargs, operations) -self.ctxt.dump_to_file("/tmp/%s.c" % name, r_int(1)) +if 1: +self.ctxt.dump_to_file("/tmp/%s.c" % name, r_int(1)) jit_result = self.ctxt.compile() self.ctxt.release() @@ -413,11 +417,13 @@ #print(dir(op)) #print(repr(op.getopname())) text += '\t%s\n' % op -self.b_current.add_comment(str(text)) +if self.add_comments: +self.b_current.add_comment(str(text)) # Get initial values from input args: for idx, arg in enumerate(inputargs): -self.b_current.add_comment("inputargs[%i]: %s" % (idx, arg)) +if self.add_comments: +self.b_current.add_comment("inputargs[%i]: %s" % (idx, arg)) # (gdb) p *(double*)&jitframe->arg0 # $7 = 10.5 # (gdb) p *(double*)&jitframe->arg1 @@ -442,7 +448,8 @@ #print(dir(op)) #print(repr(op.getopname())) # Add a comment describing this ResOperation -self.b_current.add_comment(str(op)) +if self.add_comments: +self.b_current.add_comment(str(op)) # Compile the operation itself... methname = 'emit_%s' % op.getopname() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Get test_ooops/test_ooops_non_gc to pass
Author: David Malcolm Branch: libgccjit-backend Changeset: r75246:207274050e18 Date: 2014-12-24 05:30 -0500 http://bitbucket.org/pypy/pypy/changeset/207274050e18/ Log:Get test_ooops/test_ooops_non_gc to pass diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -998,6 +998,29 @@ # +def _impl_ptr_cmp(self, resop, gcc_jit_comparison): +rval0 = self.expr_to_rvalue(resop._arg0) +rval1 = self.expr_to_rvalue(resop._arg1) +lvalres = self.expr_to_lvalue(resop.result) +resop_cmp = ( +self.ctxt.new_cast( +self.ctxt.new_comparison(gcc_jit_comparison, + rval0, rval1), +self.t_Signed) +) +self.b_current.add_assignment(lvalres, + resop_cmp) +def emit_ptr_eq(self, resop): +self._impl_ptr_cmp(resop, self.lib.GCC_JIT_COMPARISON_EQ) +def emit_ptr_ne(self, resop): +self._impl_ptr_cmp(resop, self.lib.GCC_JIT_COMPARISON_NE) +def emit_instance_ptr_eq(self, resop): +self._impl_ptr_cmp(resop, self.lib.GCC_JIT_COMPARISON_EQ) +def emit_instance_ptr_ne(self, resop): +self._impl_ptr_cmp(resop, self.lib.GCC_JIT_COMPARISON_NE) + +# + def impl_get_lvalue_at_offset_from_ptr(self, ptr_expr, ll_offset, t_field): ptr = self.expr_to_rvalue(ptr_expr) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Don't rely on dynamic linker name lookup when locating jump targets
Author: David Malcolm Branch: libgccjit-backend Changeset: r75252:2f581f6a1f99 Date: 2015-01-05 16:02 -0500 http://bitbucket.org/pypy/pypy/changeset/2f581f6a1f99/ Log:Don't rely on dynamic linker name lookup when locating jump targets Instead, jump through a saved function pointer. Doing so avoids the need to use RTLD_GLOBAL in dlopen in libgccjit's jit-playback.c. diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -42,6 +42,7 @@ self.name = name self.rffi_fn = rffi_fn self.patchpoints = [] +self.fn_ptr = None def new_block(self, name): return self.rffi_fn.new_block(name) @@ -291,6 +292,7 @@ fn_ptr = jit_result.get_code(loopname) looptoken._ll_function_addr = fn_ptr +self.fn.fn_ptr = fn_ptr looptoken.compiled_loop_token._ll_initial_locs = initial_locs @@ -326,6 +328,7 @@ # Patch the patchpoint for "faildescr" to point to our new code fn_ptr = jit_result.get_code(name) self.patchpoint_for_descr[faildescr].set_handler(fn_ptr) +self.fn.fn_ptr = fn_ptr def make_JITFRAME_struct(self, inputargs, operations): #print(jitframe.JITFRAME) @@ -586,19 +589,21 @@ b_dest = self.block_for_label_descr[jumpop.getdescr()] self.b_current.end_with_jump(b_dest) else: -# Implement as a tail-call: -# Sadly, we need to "import" the fn by name, since it was -# created on a different gcc_jit_context. +# Implement as a tail-call +# The function was created on a different gcc_jit_context, +# but we know its address in memory, so we can implement +# it as a call through a function pointer. p = Params(self) -other_fn = self.ctxt.new_function( -self.lib.GCC_JIT_FUNCTION_IMPORTED, +fn_ptr_type = self.ctxt.new_function_ptr_type( self.t_jit_frame_ptr, -dest_fn.name, -p.paramlist, -r_int(0)) +p.paramtypes, +r_int(0)) # is_variadic +ptr_to_other_fn = self.ctxt.new_rvalue_from_ptr(fn_ptr_type, +dest_fn.fn_ptr) args = [param.as_rvalue() for param in self.loop_params.paramlist] -call = self.ctxt.new_call(other_fn, args) +call = self.ctxt.new_call_through_ptr(ptr_to_other_fn, + args) self.b_current.end_with_return(call) def emit_finish(self, resop): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy libgccjit-backend: Introduce AssemblerLibgccjit.shared_ctxt to avoid rebuilding the basic types each time
Author: David Malcolm Branch: libgccjit-backend Changeset: r75253:619395643793 Date: 2015-01-05 16:28 -0500 http://bitbucket.org/pypy/pypy/changeset/619395643793/ Log:Introduce AssemblerLibgccjit.shared_ctxt to avoid rebuilding the basic types each time diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py --- a/rpython/jit/backend/libgccjit/assembler.py +++ b/rpython/jit/backend/libgccjit/assembler.py @@ -175,59 +175,65 @@ self.add_comments = 1 -def make_context(self): -self.ctxt = Context.acquire(self.lib)#self.lib.gcc_jit_context_acquire() +# Create "shared_ctxt" to hold the common types +# needed by every loop/bridge +# Compiling a loop or bridge will involve creating a child +# context of the shared_ctxt. +self.shared_ctxt = Context.acquire(self.lib) if 0: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE, r_int(1)) if 0: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, r_int(1)) if 1: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DEBUGINFO, r_int(1)) if 1: -self.ctxt.set_int_option( +self.shared_ctxt.set_int_option( self.lib.GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, r_int(2)) if 1: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, r_int(1)) if 1: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, r_int(1)) if 0: -self.ctxt.set_bool_option( +self.shared_ctxt.set_bool_option( self.lib.GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, r_int(1)) -self.t_Signed = self.ctxt.get_int_type(r_int(self.sizeof_signed), +self.t_Signed = self.shared_ctxt.get_int_type(r_int(self.sizeof_signed), r_int(1)) self.t_signed_ptr = self.t_Signed.get_pointer() -self.t_UINT = self.ctxt.get_int_type(r_int(self.sizeof_signed), +self.t_UINT = self.shared_ctxt.get_int_type(r_int(self.sizeof_signed), r_int(0)) -self.t_float = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME -self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) -self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) -self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) -self.t_char_ptr = self.ctxt.get_type( +self.t_float = self.shared_ctxt.get_type(self.lib.GCC_JIT_TYPE_DOUBLE) # FIXME +self.t_bool = self.shared_ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL) +self.t_void_ptr = self.shared_ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR) +self.t_void = self.shared_ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID) +self.t_char_ptr = self.shared_ctxt.get_type( self.lib.GCC_JIT_TYPE_CHAR).get_pointer() -self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed") -self.u_float = self.ctxt.new_field(self.t_float, "u_float") -self.u_void_ptr = self.ctxt.new_field(self.t_void_ptr, "u_void_ptr") -self.u_signed_ptr = self.ctxt.new_field(self.t_signed_ptr, "u_signed_ptr") -self.t_any = self.ctxt.new_union_type ("any", +self.u_signed = self.shared_ctxt.new_field(self.t_Signed, "u_signed") +self.u_float = self.shared_ctxt.new_field(self.t_float, "u_float") +self.u_void_ptr = self.shared_ctxt.new_field(self.t_void_ptr, "u_void_ptr") +self.u_signed_ptr = self.shared_ctxt.new_field(self.t_signed_ptr, "u_signed_ptr") +self.t_any = self.shared_ctxt.new_union_type ("any", [self.u_signed, self.u_float, self.u_void_ptr, self.u_signed_ptr]) +def make_context(self): +self.ctxt = self.shared_ctxt.new_child_context() + def setup(self, looptoken): allblocks = self.get_asmmemmgr_blocks(looptoken) self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py --- a/rpython/jit/backend/libgccjit/rffi_bindings.py +++ b/rpython/jit/backend/libgccjit/rffi_bind
[pypy-commit] pypy libgccjit-backend: notes.rst: gcc r219480 onwards should have everything needed by the backend
Author: David Malcolm Branch: libgccjit-backend Changeset: r75308:eddd1a835153 Date: 2015-01-12 12:43 -0500 http://bitbucket.org/pypy/pypy/changeset/eddd1a835153/ Log:notes.rst: gcc r219480 onwards should have everything needed by the backend diff --git a/rpython/jit/backend/libgccjit/notes.rst b/rpython/jit/backend/libgccjit/notes.rst --- a/rpython/jit/backend/libgccjit/notes.rst +++ b/rpython/jit/backend/libgccjit/notes.rst @@ -1,18 +1,18 @@ This is an experiment, and merely a work-in-progress. -In particular, this needs some changes to libgccjit that are currently -only in my local repo: +In particular, this needs some late-breaking changes to gcc 5's +libgccjit; gcc r219480 onwards (2015-01-12) should have everything: * new API entrypoints: - * :c:func:`gcc_jit_result_get_global` + * :c:func:`gcc_jit_result_get_global` (added in gcc r219480) - * :c:func:`gcc_jit_context_new_rvalue_from_long` + * :c:func:`gcc_jit_context_new_rvalue_from_long` (added in gcc r219401) - * :c:func:`gcc_jit_context_get_last_error` + * :c:func:`gcc_jit_context_get_last_error` (added in gcc r219363) * a new value :c:macro:`GCC_JIT_UNARY_OP_ABS` within - :c:type:`enum gcc_jit_unary_op`. + :c:type:`enum gcc_jit_unary_op` (added in r219321) * an extra param to :c:func:`gcc_jit_context_new_global` - (enum gcc_jit_global_kind). + (enum gcc_jit_global_kind; added in gcc r219480). ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: implement PyInt_AsUnsignedLongLongMask
Author: David Malcolm Branch: Changeset: r56009:542d481517d3 Date: 2012-07-09 16:06 -0400 http://bitbucket.org/pypy/pypy/changeset/542d481517d3/ Log:implement PyInt_AsUnsignedLongLongMask diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py --- a/pypy/module/cpyext/intobject.py +++ b/pypy/module/cpyext/intobject.py @@ -6,7 +6,7 @@ PyObject, PyObjectFields, CONST_STRING, CANNOT_FAIL, Py_ssize_t) from pypy.module.cpyext.pyobject import ( make_typedescr, track_reference, RefcountState, from_ref) -from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST +from pypy.rlib.rarithmetic import r_uint, intmask, LONG_TEST, r_ulonglong from pypy.objspace.std.intobject import W_IntObject import sys @@ -83,6 +83,20 @@ num = space.bigint_w(w_int) return num.uintmask() +@cpython_api([PyObject], rffi.ULONGLONG, error=-1) +def PyInt_AsUnsignedLongLongMask(space, w_obj): +"""Will first attempt to cast the object to a PyIntObject or +PyLongObject, if it is not already one, and then return its value as +unsigned long long, without checking for overflow. +""" +w_int = space.int(w_obj) +if space.is_true(space.isinstance(w_int, space.w_int)): +num = space.int_w(w_int) +return r_ulonglong(num) +else: +num = space.bigint_w(w_int) +return num.ulonglongmask() + @cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL) def PyInt_AS_LONG(space, w_int): """Return the value of the object w_int. No error checking is performed.""" diff --git a/pypy/module/cpyext/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py --- a/pypy/module/cpyext/test/test_intobject.py +++ b/pypy/module/cpyext/test/test_intobject.py @@ -34,6 +34,11 @@ assert (api.PyInt_AsUnsignedLongMask(space.wrap(10**30)) == 10**30 % ((sys.maxint + 1) * 2)) +assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(sys.maxint)) +== sys.maxint) +assert (api.PyInt_AsUnsignedLongLongMask(space.wrap(10**30)) +== 10**30 % (2**64)) + def test_coerce(self, space, api): class Coerce(object): def __int__(self): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit