[pypy-commit] pypy libgccjit-backend: Work-in-progress

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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)

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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)

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-17 Thread dmalcolm
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

2014-12-18 Thread dmalcolm
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

2014-12-18 Thread dmalcolm
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

2014-12-18 Thread dmalcolm
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

2014-12-18 Thread dmalcolm
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

2014-12-18 Thread dmalcolm
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

2014-12-22 Thread dmalcolm
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

2014-12-22 Thread dmalcolm
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

2014-12-22 Thread dmalcolm
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

2014-12-22 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2014-12-23 Thread dmalcolm
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

2015-01-05 Thread dmalcolm
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

2015-01-05 Thread dmalcolm
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

2015-01-05 Thread dmalcolm
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

2015-01-06 Thread dmalcolm
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

2015-01-06 Thread dmalcolm
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

2015-01-12 Thread dmalcolm
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

2012-07-09 Thread dmalcolm
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