[pypy-commit] pypy optresult-unroll: fix some tests
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79309:bf7a0a3b5f92 Date: 2015-08-31 09:33 +0200 http://bitbucket.org/pypy/pypy/changeset/bf7a0a3b5f92/ Log:fix some tests diff --git a/rpython/jit/metainterp/test/test_send.py b/rpython/jit/metainterp/test/test_send.py --- a/rpython/jit/metainterp/test/test_send.py +++ b/rpython/jit/metainterp/test/test_send.py @@ -42,7 +42,7 @@ assert res == 2 # 'len' becomes a getfield('num_items') for now in lltype, # which is itself encoded as a 'getfield_gc' -self.check_resops(call=2, getfield_gc=2) +self.check_resops(call_r=2, getfield_gc_i=2) def test_send_to_single_target_method(self): myjitdriver = JitDriver(greens = [], reds = ['i', 'counter']) @@ -66,9 +66,9 @@ res = self.meta_interp(f, [1], policy=StopAtXPolicy(externfn), backendopt=True) assert res == 43 -self.check_resops({'int_gt': 2, 'getfield_gc': 2, +self.check_resops({'int_gt': 2, 'getfield_gc_i': 2, 'guard_true': 2, 'int_sub': 2, 'jump': 1, - 'call': 2, 'guard_no_exception': 2, + 'call_r': 2, 'guard_no_exception': 2, 'int_add': 2}) def test_red_send_to_green_receiver(self): @@ -557,7 +557,7 @@ policy = StopAtXPolicy(new, A.foo.im_func, B.foo.im_func) res = self.meta_interp(fn, [0, 20], policy=policy) assert res == 42 -self.check_resops(call=2) +self.check_resops(call_i=2) def test_residual_oosend_with_void(self): @@ -585,7 +585,7 @@ policy = StopAtXPolicy(new, A.foo.im_func) res = self.meta_interp(fn, [1, 20], policy=policy) assert res == 41 -self.check_resops(call=2) +self.check_resops(call_i=2) def test_constfold_pure_oosend(self): myjitdriver = JitDriver(greens=[], reds = ['i', 'obj']) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy vecopt-merge: slicing index must be positive
Author: Richard Plangger Branch: vecopt-merge Changeset: r79310:51a6240fbce7 Date: 2015-08-31 09:36 +0200 http://bitbucket.org/pypy/pypy/changeset/51a6240fbce7/ Log:slicing index must be positive adding split packs to packset added vec_guard_ratio parameter diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py b/rpython/jit/metainterp/optimizeopt/schedule.py --- a/rpython/jit/metainterp/optimizeopt/schedule.py +++ b/rpython/jit/metainterp/optimizeopt/schedule.py @@ -940,11 +940,16 @@ node.pack_position = i def split(self, packlist, vec_reg_size): +""" Combination phase creates the biggest packs that are possible. +In this step the pack is reduced in size to fit into an +vector register. +""" pack = self pack_type = self.pack_type() max_count = vec_reg_size // pack_type.getsize() assert max_count * pack_type.getsize() == vec_reg_size while pack.pack_byte_size() > vec_reg_size: +assert max_count > 0 newpack = pack.clone() oplist = pack.operations[:max_count] newpack.operations = pack.operations[max_count:] @@ -952,6 +957,7 @@ pack.update_pack_of_nodes() newpack.update_pack_of_nodes() pack = newpack +packlist.append(newpack) def rightmost_match_leftmost(self, other): """ Check if pack A can be combined with pack B """ diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py --- a/rpython/jit/metainterp/optimizeopt/vectorize.py +++ b/rpython/jit/metainterp/optimizeopt/vectorize.py @@ -97,6 +97,8 @@ resop_count = 0 # the count of operations minus debug_merge_points vector_instr = 0 +guard_count = 0 +blacklist = (rop.CALL, rop.CALL_ASSEMBLER) at_least_one_array_access = True for i,op in enumerate(loop.operations): if op.getopnum() == rop.DEBUG_MERGE_POINT: @@ -110,6 +112,13 @@ if op.is_primitive_array_access(): at_least_one_array_access = True +if warmstate.vec_ratio > 0.0: +if op.getopnum() in blacklist: +return True + +if op.is_guard(): +guard_count += 1 + if not at_least_one_array_access: return True @@ -119,6 +128,9 @@ if (float(vector_instr)/float(resop_count)) < warmstate.vec_ratio: return True +if float(guard_count)/float(resop_count) > warmstate.vec_guard_ratio: +return True + return False def cmp_pack_lt(a,b): diff --git a/rpython/jit/metainterp/test/test_vectorize.py b/rpython/jit/metainterp/test/test_vectorize.py --- a/rpython/jit/metainterp/test/test_vectorize.py +++ b/rpython/jit/metainterp/test/test_vectorize.py @@ -289,15 +289,32 @@ res = self.meta_interp(f, [i]) assert res == f(i) -@py.test.mark.parametrize('i,v1,v2',[(25,2.5,0.3), (15,44.0,22.2)]) +@py.test.mark.parametrize('i,v1,v2',[(25,2.5,0.3)]) def test_list_vectorize(self,i,v1,v2): myjitdriver = JitDriver(greens = [], reds = 'auto') +class ListF(object): +def __init__(self, size, init=0.0): +self.list = [init] * size +def __getitem__(self, key): +if key < 0: +raise IndexError +if key >= len(self.list): +raise IndexError +return self.list[key] +def __setitem__(self, key, value): +if key < 0: +raise IndexError +if key >= len(self.list): +raise IndexError +self.list[key] = value +def append(self, value): +self.list.append(value) def f(d, v1, v2): -a = [v1] * i -b = [v2] * i +a = ListF(d, v1) +b = ListF(d, v2) i = 0 -while i < len(a): +while i < d: myjitdriver.jit_merge_point() a[i] = a[i] + b[i] i += 1 diff --git a/rpython/jit/metainterp/warmspot.py b/rpython/jit/metainterp/warmspot.py --- a/rpython/jit/metainterp/warmspot.py +++ b/rpython/jit/metainterp/warmspot.py @@ -72,7 +72,7 @@ loop_longevity=0, retrace_limit=5, function_threshold=4, enable_opts=ALL_OPTS_NAMES, max_retrace_guards=15, max_unroll_recursion=7, vec=0, vec_all=0, vec_cost=0, -vec_length=60, vec_ratio=2, **kwds): +vec_length=60, vec_ratio=2, vec_guard_ratio=3, **kwds): from rpython.config.config import ConfigError translator = interp.typer.annotator.translator try: @@ -100,6 +100,7 @@ jd.warmstate.set_param_vec_cost(vec_cost) jd.warmstate.set_param_vec_length(vec_length) jd.warmstate.set_param_
[pypy-commit] pypy optresult-unroll: fix?
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79311:6a2ee3a1f8da Date: 2015-08-31 10:27 +0200 http://bitbucket.org/pypy/pypy/changeset/6a2ee3a1f8da/ Log:fix? diff --git a/rpython/jit/metainterp/test/test_virtual.py b/rpython/jit/metainterp/test/test_virtual.py --- a/rpython/jit/metainterp/test/test_virtual.py +++ b/rpython/jit/metainterp/test/test_virtual.py @@ -919,7 +919,7 @@ assert res == f(10) self.check_aborted_count(0) self.check_target_token_count(3) -self.check_resops(int_mul=2) +self.check_resops(int_mul=3) def test_nested_loops_bridge(self): class Int(object): @@ -963,7 +963,7 @@ res = self.meta_interp(f, [32]) assert res == f(32) self.check_aborted_count(0) -self.check_target_token_count(3) +self.check_target_token_count(4) class VirtualMiscTests: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: oops, don't emit write barriers for ints
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79312:e0a87d87e411 Date: 2015-08-31 10:54 +0200 http://bitbucket.org/pypy/pypy/changeset/e0a87d87e411/ Log:oops, don't emit write barriers for ints diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py --- a/rpython/jit/backend/llsupport/descr.py +++ b/rpython/jit/backend/llsupport/descr.py @@ -67,7 +67,7 @@ assert self.tid != 0 return self.tid -def get_size_descr(gccache, STRUCT, vtable): +def get_size_descr(gccache, STRUCT, vtable=lltype.nullptr(rclass.OBJECT_VTABLE)): cache = gccache._cache_size assert not isinstance(vtable, bool) try: diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -621,7 +621,7 @@ val = op.getarg(0) if not self.write_barrier_applied(val): v = op.getarg(1) -if (not isinstance(v, ConstPtr) or +if (v.type == 'r' and not isinstance(v, ConstPtr) or rgc.needs_write_barrier(v.value)): self.gen_write_barrier(val) #op = op.copy_and_change(rop.SETFIELD_RAW) @@ -631,7 +631,7 @@ val = op.getarg(0) if not self.write_barrier_applied(val): v = op.getarg(2) -if (not isinstance(v, ConstPtr) or +if (v.type == 'r' and not isinstance(v, ConstPtr) or rgc.needs_write_barrier(v.value)): self.gen_write_barrier_array(val, op.getarg(1)) #op = op.copy_and_change(rop.SET{ARRAYITEM,INTERIORFIELD}_RAW) diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -23,7 +23,7 @@ # # -- gc_malloc -- S = lltype.GcStruct('S', ('x', lltype.Signed)) -sizedescr = descr.get_size_descr(gc_ll_descr, S, False) +sizedescr = descr.get_size_descr(gc_ll_descr, S) p = gc_ll_descr.gc_malloc(sizedescr) assert record == [(sizedescr.size, p)] del record[:] @@ -143,7 +143,7 @@ def test_gc_malloc(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) -sizedescr = descr.get_size_descr(self.gc_ll_descr, S, False) +sizedescr = descr.get_size_descr(self.gc_ll_descr, S) p = self.gc_ll_descr.gc_malloc(sizedescr) assert lltype.typeOf(p) == llmemory.GCREF assert self.llop1.record == [("fixedsize", repr(sizedescr.size), diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -754,7 +754,7 @@ def test_malloc_1(self): cpu = self.cpu -sizeof = cpu.sizeof(self.S, False) +sizeof = cpu.sizeof(self.S, None) sizeof.tid = 0 size = sizeof.size loop = self.parse(""" diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -29,13 +29,13 @@ def check_rewrite(self, frm_operations, to_operations, **namespace): S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) -sdescr = get_size_descr(self.gc_ll_descr, S, False) +sdescr = get_size_descr(self.gc_ll_descr, S) sdescr.tid = 1234 # T = lltype.GcStruct('T', ('y', lltype.Signed), ('z', lltype.Ptr(S)), ('t', lltype.Signed)) -tdescr = get_size_descr(self.gc_ll_descr, T, False) +tdescr = get_size_descr(self.gc_ll_descr, T) tdescr.tid = 5678 tzdescr = get_field_descr(self.gc_ll_descr, T, 'z') # @@ -55,7 +55,7 @@ clendescr = cdescr.lendescr # E = lltype.GcStruct('Empty') -edescr = get_size_descr(self.gc_ll_descr, E, False) +edescr = get_size_descr(self.gc_ll_descr, E) edescr.tid = 9000 # vtable_descr = self.gc_ll_descr.fielddescr_vtable @@ -1045,13 +1045,13 @@ self.check_rewrite(""" [] p0 = new(descr=tdescr) -p1 = getfield_gc(p0, descr=tdescr) +p1 = getfield_gc_r(p0, descr=tdescr) jump(p1) """, """ [] p0 = call_malloc_nursery(%(tdescr.size)d) setfield_gc(p0, 5678, descr=tiddescr) zero_ptr_field(p0, %(tdescr.gc_fielddescrs[0].offset)s) -p1 = getfield_gc(p0, descr=tdescr) +p1 = getfield_gc_r(p
[pypy-commit] pypy optresult-unroll: ups
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79313:45f08e1b74be Date: 2015-08-31 11:08 +0200 http://bitbucket.org/pypy/pypy/changeset/45f08e1b74be/ Log:ups diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -621,8 +621,8 @@ val = op.getarg(0) if not self.write_barrier_applied(val): v = op.getarg(1) -if (v.type == 'r' and not isinstance(v, ConstPtr) or -rgc.needs_write_barrier(v.value)): +if (v.type == 'r' and (not isinstance(v, ConstPtr) or +rgc.needs_write_barrier(v.value))): self.gen_write_barrier(val) #op = op.copy_and_change(rop.SETFIELD_RAW) self.emit_op(op) @@ -631,8 +631,8 @@ val = op.getarg(0) if not self.write_barrier_applied(val): v = op.getarg(2) -if (v.type == 'r' and not isinstance(v, ConstPtr) or -rgc.needs_write_barrier(v.value)): +if (v.type == 'r' and (not isinstance(v, ConstPtr) or +rgc.needs_write_barrier(v.value))): self.gen_write_barrier_array(val, op.getarg(1)) #op = op.copy_and_change(rop.SET{ARRAYITEM,INTERIORFIELD}_RAW) self.emit_op(op) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Kill push_gcmap(mov=True): it is always followed by taking the gcmap
Author: Armin Rigo Branch: Changeset: r79314:8d8edb9e1343 Date: 2015-08-31 11:07 +0200 http://bitbucket.org/pypy/pypy/changeset/8d8edb9e1343/ Log:Kill push_gcmap(mov=True): it is always followed by taking the gcmap back from the stack to store it inside the jitframe. It can be done directory with push_gcmap(store=True), which is not more instructions (nor a longer one). diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -114,10 +114,7 @@ def build_frame_realloc_slowpath(self): mc = codebuf.MachineCodeBlockWrapper() self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats) -# this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame -mc.MOV_rs(ecx.value, WORD) -gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') -mc.MOV_br(gcmap_ofs, ecx.value) +# the caller already did push_gcmap(store=True) if IS_X86_64: mc.MOV_rs(esi.value, WORD*2) @@ -147,7 +144,7 @@ self._load_shadowstack_top_in_ebx(mc, gcrootmap) mc.MOV_mr((ebx.value, -WORD), eax.value) -mc.MOV_bi(gcmap_ofs, 0) +self.pop_gcmap(mc) # cancel the push_gcmap(store=True) in the caller self._pop_all_regs_from_frame(mc, [], self.cpu.supports_floats) mc.RET() self._frame_realloc_slowpath = mc.materialize(self.cpu, []) @@ -164,6 +161,7 @@ # the end of this function. self._push_all_regs_to_frame(mc, cond_call_register_arguments + [eax], supports_floats, callee_only) +# the caller already did push_gcmap(store=True) if IS_X86_64: mc.SUB(esp, imm(WORD)) # alignment self.set_extra_stack_depth(mc, 2 * WORD) @@ -182,8 +180,8 @@ mc.ADD(esp, imm(WORD * 7)) self.set_extra_stack_depth(mc, 0) self._reload_frame_if_necessary(mc, align_stack=True) +self.pop_gcmap(mc) # cancel the push_gcmap(store=True) in the caller self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only) -self.pop_gcmap(mc) # push_gcmap(store=True) done by the caller mc.RET() return mc.materialize(self.cpu, []) @@ -203,10 +201,7 @@ assert kind in ['fixed', 'str', 'unicode', 'var'] mc = codebuf.MachineCodeBlockWrapper() self._push_all_regs_to_frame(mc, [eax, edi], self.cpu.supports_floats) -# store the gc pattern -ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') -mc.MOV_rs(ecx.value, WORD) -mc.MOV_br(ofs, ecx.value) +# the caller already did push_gcmap(store=True) # if kind == 'fixed': addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() @@ -258,8 +253,7 @@ self.set_extra_stack_depth(mc, 0) self._pop_all_regs_from_frame(mc, [eax, edi], self.cpu.supports_floats) mc.MOV(edi, heap(nursery_free_adr)) # load this in EDI -# clear the gc pattern -mc.MOV_bi(ofs, 0) +self.pop_gcmap(mc) # push_gcmap(store=True) done by the caller mc.RET() # # If the slowpath malloc failed, we raise a MemoryError that @@ -646,7 +640,7 @@ jg_location = mc.get_relative_pos() mc.MOV_si(WORD, 0xff) # force writing 32 bit ofs2 = mc.get_relative_pos() - 4 -self.push_gcmap(mc, gcmap, mov=True) +self.push_gcmap(mc, gcmap, store=True) mc.CALL(imm(self._frame_realloc_slowpath)) # patch the JG above offset = mc.get_relative_pos() - jg_location @@ -1797,12 +1791,9 @@ self.mc.JMP(imm(target)) return startpos -def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False): +def push_gcmap(self, mc, gcmap, push=False, store=False): if push: mc.PUSH(imm(rffi.cast(lltype.Signed, gcmap))) -elif mov: -mc.MOV(RawEspLoc(0, REF), - imm(rffi.cast(lltype.Signed, gcmap))) else: assert store ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') @@ -2280,7 +2271,7 @@ self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later jmp_adr = self.mc.get_relative_pos() # save the gcmap -self.push_gcmap(self.mc, gcmap, mov=True) +self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(imm(follow_jump(self.malloc_slowpath))) offset = self.mc.get_relative_pos() - jmp_adr assert 0 < offset <= 127 @@ -2301,7 +2292,7 @@ self.mc.J_il8(rx86.Conditions['NA'], 0) # patched later jmp_adr = self.mc.get_relative_pos() # save the gcmap -self.push_gcmap(self.mc, gcmap, mov=True) +self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(imm(follow_jump(self.mallo
[pypy-commit] pypy default: merge heads
Author: Armin Rigo Branch: Changeset: r79315:37723950bd21 Date: 2015-08-31 11:36 +0200 http://bitbucket.org/pypy/pypy/changeset/37723950bd21/ Log:merge heads diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info --- a/lib_pypy/greenlet.egg-info +++ b/lib_pypy/greenlet.egg-info @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: greenlet -Version: 0.4.7 +Version: 0.4.9 Summary: Lightweight in-process concurrent programming Home-page: https://github.com/python-greenlet/greenlet Author: Ralf Schmitt (for CPython), PyPy team diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,7 +1,7 @@ import sys import _continuation -__version__ = "0.4.7" +__version__ = "0.4.9" # # Exceptions ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: For pypy translated without the _thread module: optimization
Author: Armin Rigo Branch: Changeset: r79316:9458d6ef6c53 Date: 2015-08-31 11:53 +0200 http://bitbucket.org/pypy/pypy/changeset/9458d6ef6c53/ Log:For pypy translated without the _thread module: optimization diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -9,6 +9,7 @@ implementation for this feature, and patches 'space.threadlocals' when 'thread' is initialized. """ +_immutable_fields_ = ['_value?'] _value = None def get_ec(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: we forgot to put enter/leave portal frame into a does not have effect on heap
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79317:b63169a0ed5e Date: 2015-08-31 13:16 +0200 http://bitbucket.org/pypy/pypy/changeset/b63169a0ed5e/ Log:we forgot to put enter/leave portal frame into a does not have effect on heap diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -309,6 +309,8 @@ opnum == rop.UNICODESETITEM or # no effect on GC struct/array opnum == rop.DEBUG_MERGE_POINT or# no effect whatsoever opnum == rop.JIT_DEBUG or# no effect whatsoever +opnum == rop.ENTER_PORTAL_FRAME or # no effect whatsoever +opnum == rop.LEAVE_PORTAL_FRAME or # no effect whatsoever opnum == rop.COPYSTRCONTENT or # no effect on GC struct/array opnum == rop.COPYUNICODECONTENT):# no effect on GC struct/array return ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: changes to make parsing work
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79318:ff5f9e91ac2a Date: 2015-08-31 13:56 +0200 http://bitbucket.org/pypy/pypy/changeset/ff5f9e91ac2a/ Log:changes to make parsing work diff --git a/rpython/jit/tool/oparser.py b/rpython/jit/tool/oparser.py --- a/rpython/jit/tool/oparser.py +++ b/rpython/jit/tool/oparser.py @@ -293,7 +293,7 @@ return opnum, args, descr, fail_args -def create_op(self, opnum, args, descr, fail_args): +def create_op(self, opnum, args, res, descr, fail_args): if opnum in ALL_ESCAPE_OPS: op = ALL_ESCAPE_OPS[opnum]() op.initarglist(args) @@ -319,13 +319,13 @@ opnum, args, descr, fail_args = self.parse_op(op) if res in self.vars: raise ParseError("Double assign to var %s in line: %s" % (res, line)) -resop = self.create_op(opnum, args, descr, fail_args) +resop = self.create_op(opnum, args, res, descr, fail_args) self.vars[res] = resop return resop def parse_op_no_result(self, line): opnum, args, descr, fail_args = self.parse_op(line) -res = self.create_op(opnum, args, descr, fail_args) +res = self.create_op_no_result(opnum, args, descr, fail_args) return res def parse_next_op(self, line): diff --git a/rpython/tool/jitlogparser/parser.py b/rpython/tool/jitlogparser/parser.py --- a/rpython/tool/jitlogparser/parser.py +++ b/rpython/tool/jitlogparser/parser.py @@ -156,8 +156,13 @@ def box_for_var(self, res): return res -def create_op(self, opnum, args, descr, fail_args): -return self.Op(intern(opname[opnum].lower()), args, None, descr, fail_args) +def create_op(self, opnum, args, res, descr, fail_args): +return self.Op(intern(opname[opnum].lower()), args, res, + descr, fail_args) + +def create_op_no_result(self, opnum, args, descr, fail_args): +return self.Op(intern(opname[opnum].lower()), args, None, + descr, fail_args) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] benchmarks default: One more benchmark
Author: Maciej Fijalkowski Branch: Changeset: r333:7b876ef4812e Date: 2015-08-31 14:35 +0200 http://bitbucket.org/pypy/benchmarks/changeset/7b876ef4812e/ Log:One more benchmark diff --git a/warmup/bridges.py b/warmup/bridges.py new file mode 100644 --- /dev/null +++ b/warmup/bridges.py @@ -0,0 +1,29 @@ + +for i in range(100): +exec """ +def f(): +s = 0 +i = 0 +while i < 1: +i += 1 +if i % 2 == 0: +s += 1 +if i % 3 == 0: +s += 1 +if i % 5 == 0: +s += 1 +if i % 7 == 0: +s += 1 +if i % 11 == 0: +s += 1 +if i % 13 == 0: +s += 1 +if i % 17 == 0: +s += 1 +if i % 19 == 0: +s += 1 +if i % 23 == 0: +s += 1 + +f() +""" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy vecopt-merge: fixed the scheduling tests, two of them where wrong and execute vector instructions on half filled vector registers
Author: Richard Plangger Branch: vecopt-merge Changeset: r79320:5a31e0903f8d Date: 2015-08-31 15:06 +0200 http://bitbucket.org/pypy/pypy/changeset/5a31e0903f8d/ Log:fixed the scheduling tests, two of them where wrong and execute vector instructions on half filled vector registers diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py b/rpython/jit/metainterp/optimizeopt/schedule.py --- a/rpython/jit/metainterp/optimizeopt/schedule.py +++ b/rpython/jit/metainterp/optimizeopt/schedule.py @@ -272,21 +272,12 @@ self.sched_data = sched_data self.vecops = oplist self.costmodel = sched_data.costmodel -# self.input_type = pack.input_type self.output_type = pack.output_type # self.check_if_pack_supported(pack) - -# -if self.must_be_full_but_is_not(pack): -for op in pack.operations: -operation = op.getoperation() -self.sched_data.unpack_from_vector(operation, scheduler) -self.vecops.append(operation) -else: -self.pack = pack -self.transform_pack() +self.pack = pack +self.transform_pack() # self.pack = None self.costmodel = None @@ -295,9 +286,6 @@ self.input_type = None self.output_type = None -def must_be_full_but_is_not(self, pack): -return False - def before_argument_transform(self, args): pass @@ -1008,6 +996,8 @@ packlist.append(newpack) else: newpack.clear() +newpack.operations = [] +break def slice_operations(self, vec_reg_size): count = opcount_filling_vector_register(self, vec_reg_size) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py --- a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py @@ -24,8 +24,9 @@ I16 = PackType('i',2,True,8) class FakePackSet(PackSet): -def __init__(self): -self.packs = None +def __init__(self, packs): +self.packs = packs +self.vec_reg_size = 16 class FakeDependencyGraph(DependencyGraph): """ A dependency graph that is able to emit every instruction @@ -115,8 +116,7 @@ pair = Pair(o1,o2,pack.input_type,pack.output_type) pairs.append(pair) -opt.packset = FakePackSet() -opt.packset.packs = pairs +opt.packset = FakePackSet(pairs) if not prepend_invariant: def pio(oplist, labels): @@ -149,7 +149,8 @@ loop2 = self.schedule(loop1, [pack1]) loop3 = self.parse(""" v10[i32|4] = vec_raw_load(p0, i0, 4, descr=float) -v11[i32|2] = vec_raw_load(p0, i4, 2, descr=float) +f10 = raw_load(p0, i4, descr=float) +f11 = raw_load(p0, i5, descr=float) """, False) self.assert_equal(loop2, loop3) @@ -379,17 +380,19 @@ loop1 = self.parse(""" i10 = raw_load(p0, i1, descr=float) i11 = raw_load(p0, i2, descr=float) +i12 = raw_load(p0, i3, descr=float) +i13 = raw_load(p0, i4, descr=float) raw_store(p0, i3, i10, descr=float) raw_store(p0, i4, i11, descr=float) """) -pack1 = self.pack(loop1, 0, 2, None, I32_2) -pack2 = self.pack(loop1, 2, 4, I32_2, None) +pack1 = self.pack(loop1, 0, 4, None, I32) +pack2 = self.pack(loop1, 4, 6, I32_2, None) loop2 = self.schedule(loop1, [pack1,pack2], prepend_invariant=True) loop3 = self.parse(""" -v1[i32|2] = vec_raw_load(p0, i1, 2, descr=float) -i10 = vec_int_unpack(v1[i32|2], 0, 1) +v1[i32|4] = vec_raw_load(p0, i1, 4, descr=float) +i10 = vec_int_unpack(v1[i32|4], 0, 1) raw_store(p0, i3, i10, descr=float) -i11 = vec_int_unpack(v1[i32|2], 1, 1) +i11 = vec_int_unpack(v1[i32|4], 1, 1) raw_store(p0, i4, i11, descr=float) """, False) # unfortunate ui32 is the type for float32... the unsigned u is for @@ -466,5 +469,13 @@ packs.append(pack) assert len(packs) == 2 +def test_combine_packset_nearly_empty_pack(self): +trace = self.parse(""" +i10 = int_add(i1, i3) +i11 = int_add(i2, i3) +""") +pack = self.pack(trace, 0, 2, I16, I16) +packset = FakePackSet([pack]) +packset.split_overloaded_packs() +assert len(packset.packs) == 0 - diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py --- a/rpython/jit/metainterp/optimizeopt/vectorize.py +++ b/rpython/jit/metainterp/optimizeopt/vectorize.py @@ -317,9 +317,7 @@ loop = self.loop operations = loop.operations -self.packset = PackSet(self.dependency_g
[pypy-commit] pypy vecopt-merge: resolving some issues introduced by the simpler combination and separate splitting phase,
Author: Richard Plangger Branch: vecopt-merge Changeset: r79319:75f6354522df Date: 2015-08-31 14:33 +0200 http://bitbucket.org/pypy/pypy/changeset/75f6354522df/ Log:resolving some issues introduced by the simpler combination and separate splitting phase, needs to remove packs that are not full diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py b/rpython/jit/metainterp/optimizeopt/schedule.py --- a/rpython/jit/metainterp/optimizeopt/schedule.py +++ b/rpython/jit/metainterp/optimizeopt/schedule.py @@ -240,6 +240,11 @@ def getcount(self): return self.count +def pack_byte_size(self, pack): +if len(pack.operations) == 0: +return 0 +return self.getsize() * pack.opcount() + PT_GENERIC = PackType(PackType.UNKNOWN_TYPE, -1, False) PT_FLOAT_2 = PackType(FLOAT, 4, False, 2) @@ -873,11 +878,43 @@ assert not isinstance(box, BoxVector) self.box_to_vbox[box] = (off, vector) +def opcount_filling_vector_register(pack, vec_reg_size): +""" how many operations of that kind can one execute +with a machine instruction of register size X? +""" +pack_type = pack.input_type +if pack_type is None: +pack_type = pack.output_type # load operations + +op = pack.leftmost() +if op.casts_box(): +count = pack_type.getcount() +return count + +count = vec_reg_size // pack_type.getsize() +return count + +def maximum_byte_size(pack, vec_reg_size): +""" The maxmum size in bytes the operation is able to +process with the hardware register and the operation +semantics. +""" +op = pack.leftmost() +if op.casts_box(): +# casting is special, often only takes a half full vector +pack_type = pack.input_type +if pack_type is None: +pack_type = self.output_type # load operations +return pack_type.byte_size() +return vec_reg_size + class Pack(object): """ A pack is a set of n statements that are: * isomorphic * independent """ +FULL = 0 + def __init__(self, ops, input_type, output_type): self.operations = ops self.accum = None @@ -899,30 +936,43 @@ ptype = self.output_type return ptype -def pack_byte_size(self): -return self.pack_type().getsize() * self.opcount() +def input_byte_size(self): +""" The amount of bytes the operations need with the current +entries in self.operations. E.g. cast_singlefloat_to_float +takes only #2 operations. +""" +return self._byte_size(self.input_type) + +def output_byte_size(self): +""" The amount of bytes the operations need with the current +entries in self.operations. E.g. vec_load(..., descr=short) +with 10 operations returns 20 +""" +return self._byte_size(self.output_type) + +def pack_load(self, vec_reg_size): +""" Returns the load of the pack. A value +smaller than 0 indicates that it is empty +or nearly empty, zero indicates that all slots +are used and > 0 indicates that too many operations +are in this pack instance. +""" +if len(self.operations) == 0: +return -1 +size = maximum_byte_size(self, vec_reg_size) +if self.input_type is None: +# e.g. load operations +return self.output_type.pack_byte_size(self) - size +# default only consider the input type +# e.g. store operations, int_add, ... +return self.input_type.pack_byte_size(self) - size + def is_full(self, vec_reg_size): """ If one input element times the opcount is equal to the vector register size, we are full! """ -ptype = self.pack_type() -op = self.leftmost() -if op.casts_box(): -cur_bytes = ptype.getsize() * self.opcount() -max_bytes = self.input_type.byte_size() -assert cur_bytes <= max_bytes -return cur_bytes == max_bytes - -bytes = self.pack_byte_size() -assert bytes <= vec_reg_size -if bytes == vec_reg_size: -return True -if ptype.getcount() != -1: -size = ptype.getcount() * ptype.getsize() -assert bytes <= size -return bytes == size -return False +return self.pack_load(vec_reg_size) == Pack.FULL def opnum(self): assert len(self.operations) > 0 @@ -930,9 +980,8 @@ def clear(self): for node in self.operations: -if node.pack is not self: -node.pack = None -node.pack_position = -1 +node.pack = None +node.pack_position = -1 def update_pack_of_nodes(self): for i,node in enumerate(self.operations): @@ -945,19 +994,28 @@ vector register. """
[pypy-commit] pypy.org extradoc: update downloads for 2.6.1
Author: mattip Branch: extradoc Changeset: r631:43c668d35ecc Date: 2015-08-30 22:46 +0300 http://bitbucket.org/pypy/pypy.org/changeset/43c668d35ecc/ Log:update downloads for 2.6.1 diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -74,7 +74,7 @@ performance improvements. We provide binaries for x86 and ARM Linux, Mac OS/X and Windows for: -the Python2.7 compatible release — PyPy 2.6.0 — (http://doc.pypy.org/en/latest/release-2.6.0.html";>what's new in PyPy 2.6.0?) +the Python2.7 compatible release — PyPy 2.6.1 — (http://doc.pypy.org/en/latest/release-2.6.1.html";>what's new in PyPy 2.6.1?) the Python3.2.5 compatible release — PyPy3 2.4.0 — (http://doc.pypy.org/en/latest/release-pypy3-2.4.0.html";>what's new in PyPy3 2.4.0?). the Python2.7 Software Transactional Memory special release — PyPy-STM 2.5.1 (Linux x86-64 only) @@ -113,20 +113,35 @@ degrees of being up-to-date. - -Python2.7 compatible PyPy 2.6.0 - -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-linux.tar.bz2";>Linux x86 binary (32bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-linux64.tar.bz2";>Linux x86-64 binary (64bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-linux-armhf-raspbian.tar.bz2";>ARM Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Raspbian) (see [1] below) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-linux-armhf-raring.tar.bz2";>ARM Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Ubuntu Raring) (see [1] below) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-linux-armel.tar.bz2";>ARM Softfloat Linux binary (ARMEL/gnueabi, tar.bz2, Ubuntu Precise) (see [1] below) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-osx64.tar.bz2";>Mac OS/X binary (64bit) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-win32.zip";>Windows binary (32bit) (you might need the VS 2008 runtime library -installer http://www.microsoft.com/en-us/download/details.aspx?id=5582";>vcredist_x86.exe.) -https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-src.tar.bz2";>Source (tar.bz2); https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.0-src.zip";>Source (zip). See below for more about the sources. -https://bitbucket.org/pypy/pypy/downloads";>All our downloads, including previous versions. We also have a -http://cobra.cs.uni-duesseldorf.de/~buildmaster/mirror/";>mirror, but please use only if you have troubles accessing the links above + +Python2.7 compatible PyPy 2.6.1 + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-linux.tar.bz2";>Linux x86 binary (32bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-linux64.tar.bz2";>Linux x86-64 binary (64bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-linux-armhf-raspbian.tar.bz2";>ARM Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Raspbian) (see [1] below) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-linux-armhf-raring.tar.bz2";>ARM Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Ubuntu Raring) (see [1] below) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-linux-armel.tar.bz2";>ARM Softfloat Linux binary (ARMEL/gnueabi, tar.bz2, Ubuntu Precise) (see [1] below) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-osx64.tar.bz2";>Mac OS/X binary (64bit) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-freebsd64.tar.bz2";>FreeBSD 9.2 x86 64 bit (see ``[1]` below) + +System Message: WARNING/2 ([dynamic-text], line 80); backlink +Inline literal start-string without end-string. + + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-win32.zip";>Windows binary (32bit) (you might need the VS 2008 runtime library +installer http://www.microsoft.com/en-us/download/details.aspx?id=5582";>vcredist_x86.exe.) + +https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-src.tar.bz2";>Source (tar.bz2); https://bitbucket.org/pypy/pypy/downloads/pypy-2.6.1-src.zip";>Source (zip). See below for more about the sources. + +https://bitbucket.org/pypy/pypy/downloads";>All our downloads, including previous versions. We also have a +http://cobra.cs.uni-duesseldorf.de/~buildmaster/mirror/";>mirror, but please use only if you have troubles accessing the links above + @@ -190,7 +205,7 @@ uncompressed, they run in-place. For now you can uncompress them either somewhere in your home directory or, say, in /opt, and if you want, put a symlink from somewhere like -/usr/local/bin/pypy to /path/to/pypy-2.6.0/bin/pypy. Do +/usr/local/bin/pypy to /path/to/pypy-2.6.1/bin/pypy. Do not move or copy the executable pypy outside the tree – put a symlink to it, otherwise it will not find its libraries. @@ -232,7 +247,7 @@ Get the source code. The following packages contain the source at the same revision as the above binaries:
[pypy-commit] pypy default: fix merge
Author: mattip Branch: Changeset: r79322:3cc794961fe4 Date: 2015-08-31 18:40 +0300 http://bitbucket.org/pypy/pypy/changeset/3cc794961fe4/ Log:fix merge diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -29,7 +29,7 @@ #define PY_VERSION "2.7.10" /* PyPy version as a string */ -#define PYPY_VERSION "2.6.1" +#define PYPY_VERSION "2.7.0-alpha0" /* Subversion Revision number of this file (not of the repository). * Empty since Mercurial migration. */ diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -10,7 +10,7 @@ #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION= 1013 #XXX # sync with include/modsupport.h -PYPY_VERSION = (2, 6, 1, "final", 0)#XXX # sync patchlevel.h +PYPY_VERSION = (2, 7, 0, "alpha", 0)#XXX # sync patchlevel.h import pypy ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge release-2.6.1 back into release
Author: mattip Branch: Changeset: r79321:7f0947a44418 Date: 2015-08-31 18:33 +0300 http://bitbucket.org/pypy/pypy/changeset/7f0947a44418/ Log:merge release-2.6.1 back into release diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -15,3 +15,4 @@ e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 +f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -168,7 +168,6 @@ Michael Twomey Lucian Branescu Mihaila Yichao Yu - Anton Gulenko Gabriel Lavoie Olivier Dormond Jared Grubb @@ -215,6 +214,7 @@ Carl Meyer Karl Ramm Pieter Zieschang + Anton Gulenko Gabriel Lukas Vacek Andrew Dalke @@ -247,6 +247,7 @@ Toni Mattis Lucas Stadler Julian Berman + Markus Holtermann roberto@goyle Yury V. Zaytsev Anna Katrina Dominguez diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -67,7 +67,7 @@ # The short X.Y version. version = '2.6' # The full version, including alpha/beta/rc tags. -release = '2.6.0' +release = '2.6.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -32,6 +32,7 @@ Lukas Diekmann Sven Hager Anders Lehmann + Richard Plangger Aurelien Campeas Remi Meier Niklaus Haldimann @@ -57,7 +58,6 @@ Ludovic Aubry Jacob Hallen Jason Creighton - Richard Plangger Alex Martelli Michal Bendowski stian @@ -138,7 +138,6 @@ Michael Twomey Lucian Branescu Mihaila Yichao Yu - Anton Gulenko Gabriel Lavoie Olivier Dormond Jared Grubb @@ -185,6 +184,7 @@ Carl Meyer Karl Ramm Pieter Zieschang + Anton Gulenko Gabriel Lukas Vacek Andrew Dalke @@ -217,6 +217,7 @@ Toni Mattis Lucas Stadler Julian Berman + Markus Holtermann roberto@goyle Yury V. Zaytsev Anna Katrina Dominguez @@ -252,6 +253,7 @@ shoma hosaka Daniel Neuhäuser Ben Mather + Niclas Olofsson halgari Boglarka Vezer Chris Pressey diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-2.6.1.rst release-2.6.0.rst release-2.5.1.rst release-2.5.0.rst diff --git a/pypy/doc/release-2.6.1.rst b/pypy/doc/release-2.6.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-2.6.1.rst @@ -0,0 +1,129 @@ +== +PyPy 2.6.1 +== + +We're pleased to announce PyPy 2.6.1, an update to PyPy 2.6.0 released June 1. +We have updated stdlib to 2.7.10, `cffi`_ to version 1.3, extended support for +the new vmprof_ statistical profiler for multiple threads, and increased +functionality of numpy. + +You can download the PyPy 2.6.1 release here: + +http://pypy.org/download.html + +We would like to thank our donors for the continued support of the PyPy +project, and our volunteers and contributors. + +.. _`cffi`: https://cffi.readthedocs.org + +We would also like to encourage new people to join the project. PyPy has many +layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation +improvements, tweaking popular `modules`_ to run on pypy, or general `help`_ with making +RPython's JIT even better. + +.. _`PyPy`: http://doc.pypy.org +.. _`RPython`: https://rpython.readthedocs.org +.. _`modules`: http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly +.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html + +What is PyPy? += + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7. It's fast (`pypy and cpython 2.7.x`_ performance comparison) +due to its integrated tracing JIT compiler. + +This release supports **x86** machines on most common operating systems +(Linux 32/64, Mac OS X 64, Windows 32, OpenBSD_, freebsd_), +as well as newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux. + +We also welcome developers of other +`dynamic languages`_ to see what RPython can do for them. + +.. _`pypy and cpython 2.7.x`: http://speed.pypy.org +.. _OpenBSD: http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/lang/pypy +.. _freebsd: https://svnweb.freebsd.org/ports/head/lang/pypy/ +.. _`dynamic languages`: http://pypyjs.org + +Highlights +=== + +* Bug Fixes + + * Revive non-SSE2 support + + * Fixes for detaching _io.Buffer* + + * On Windows, close (and flush) all open sockets on exiting + + * Drop support for ancient macOS v10.4 and before + + * Clear up contention in the garbage collector between trace-me-later and pinning + + * Issues reported with our previous release were resolved_ af
[pypy-commit] pypy optresult-unroll: cleanup a bit
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79323:256f5d6b85c3 Date: 2015-08-31 18:43 +0200 http://bitbucket.org/pypy/pypy/changeset/256f5d6b85c3/ Log:cleanup a bit diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py --- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py +++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py @@ -418,4 +418,5 @@ return [label_op] + self.short + [jump_op] class ExtendedShortPreambleBuilder(AbstractShortPreambleBuilder): -pass +def __init__(self, sb): +self.sb = sb diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -1,5 +1,4 @@ -import sys from rpython.jit.metainterp.history import Const, TargetToken, JitCellToken from rpython.jit.metainterp.optimizeopt.shortpreamble import ShortBoxes,\ ShortPreambleBuilder, ExtendedShortPreambleBuilder, PreambleOp @@ -199,7 +198,7 @@ target_token.virtual_state = virtual_state target_token.short_preamble = short_preamble jitcelltoken.target_tokens.append(target_token) -self.short_preamble_producer = None # ExtendedShortPreambleBuilder() +self.short_preamble_producer = ExtendedShortPreambleBuilder(sb) label_op.initarglist(label_op.getarglist() + sb.used_boxes) return target_token @@ -232,25 +231,24 @@ self.send_extra_operation(guard) except VirtualStatesCantMatch: continue -pass_to_short = target_virtual_state.make_inputargs(args, -self.optimizer, append_virtuals=True) -args = target_virtual_state.make_inputargs(args, -self.optimizer) +args, virtuals = target_virtual_state.make_inputargs_and_virtuals( +args, self.optimizer) short_preamble = target_token.short_preamble -lgt = len(short_preamble) - 1 -assert lgt >= 0 -extra = self.inline_short_preamble(pass_to_short, args, -short_preamble[0].getarglist(), short_preamble[1:lgt], -short_preamble[-1].getarglist(), self.optimizer.patchguardop) +extra = self.inline_short_preamble(args + virtuals, args, +short_preamble, self.optimizer.patchguardop) self.send_extra_operation(jump_op.copy_and_change(rop.JUMP, args=args + extra, descr=target_token)) return None # explicit because the return can be non-None return virtual_state -def inline_short_preamble(self, jump_args, args_no_virtuals, - short_inputargs, short_ops, - short_jump_op, patchguardop): +def inline_short_preamble(self, jump_args, args_no_virtuals, short, + patchguardop): +short_inputargs = short[0].getarglist() +short_jump_op = short[-1].getarglist() +lgt = len(short) - 1 +assert lgt >= 0 +short_ops = short[1:lgt] try: self._check_no_forwarding([short_inputargs, short_ops], False) assert len(short_inputargs) == len(jump_args) @@ -284,15 +282,14 @@ infos = {} for arg in end_args: infos[arg] = self.optimizer.getinfo(arg) -label_args = virtual_state.make_inputargs(end_args, self.optimizer) +label_args, virtuals = virtual_state.make_inputargs_and_virtuals( +end_args, self.optimizer) for arg in label_args: infos[arg] = self.optimizer.getinfo(arg) sb = ShortBoxes() -label_args_plus_virtuals = virtual_state.make_inputargs(end_args, -self.optimizer, append_virtuals=True) short_boxes = sb.create_short_boxes(self.optimizer, renamed_inputargs, -label_args_plus_virtuals) -short_inputargs = sb.create_short_inputargs(label_args_plus_virtuals) +label_args + virtuals) +short_inputargs = sb.create_short_inputargs(label_args + virtuals) for produced_op in short_boxes: op = produced_op.short_op.res if not isinstance(op, Const): diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py @@ -572,8 +572,7 @@ runtime_boxes[i], state) return state -def make_inputargs(self, inputargs, optimizer, force_boxes=False, - append_virtua
[pypy-commit] pypy optresult-unroll: allow modifications of short preamble in-place
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79324:6c309d777d44 Date: 2015-08-31 18:58 +0200 http://bitbucket.org/pypy/pypy/changeset/6c309d777d44/ Log:allow modifications of short preamble in-place diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py --- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py +++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py @@ -400,6 +400,9 @@ return preamble_op def add_preamble_op(self, preamble_op): +""" Notice that we're actually using the preamble_op, add it to +label and jump +""" if preamble_op.invented_name: self.extra_same_as.append(preamble_op.op) op = preamble_op.op @@ -418,5 +421,26 @@ return [label_op] + self.short + [jump_op] class ExtendedShortPreambleBuilder(AbstractShortPreambleBuilder): -def __init__(self, sb): +""" A special preamble builder that is called while we're building +short preamble +""" +def __init__(self, target_token, sb): self.sb = sb +self.extra_same_as = self.sb.extra_same_as +self.target_token = target_token + +def setup(self, inputargs, jump_args, short, label_args): +self.inputargs = inputargs +self.jump_args = jump_args +self.short = short +self.label_args = label_args + +def add_preamble_op(self, preamble_op): +if preamble_op.invented_name: +self.extra_same_as.append(preamble_op.op) +op = preamble_op.op +if op in self.sb.label_dict: +return +self.sb.label_dict[op] = None +self.label_args.append(op) +self.jump_args.append(preamble_op.preamble_op) diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -130,7 +130,7 @@ state.virtual_state) label_op.setdescr(target_token) # force the boxes for virtual state to match -new_virtual_state = self.jump_to_existing_trace(end_jump) +new_virtual_state = self.jump_to_existing_trace(end_jump, label_op) if new_virtual_state is not None: celltoken = start_label.getdescr() assert isinstance(celltoken, JitCellToken) @@ -160,7 +160,7 @@ self.optimizer.flush() for a in jump_op.getarglist(): self.optimizer.force_box_for_end_of_preamble(a) -vs = self.jump_to_existing_trace(jump_op) +vs = self.jump_to_existing_trace(jump_op, None) if vs is None: return info, self.optimizer._newoperations[:] warmrunnerdescr = self.optimizer.metainterp_sd.warmrunnerdesc @@ -198,7 +198,8 @@ target_token.virtual_state = virtual_state target_token.short_preamble = short_preamble jitcelltoken.target_tokens.append(target_token) -self.short_preamble_producer = ExtendedShortPreambleBuilder(sb) +self.short_preamble_producer = ExtendedShortPreambleBuilder( +target_token, sb) label_op.initarglist(label_op.getarglist() + sb.used_boxes) return target_token @@ -210,7 +211,7 @@ return info, self.optimizer._newoperations[:] -def jump_to_existing_trace(self, jump_op): +def jump_to_existing_trace(self, jump_op, label_op): jitcelltoken = jump_op.getdescr() assert isinstance(jitcelltoken, JitCellToken) virtual_state = self.get_virtual_state(jump_op.getarglist()) @@ -235,7 +236,8 @@ args, self.optimizer) short_preamble = target_token.short_preamble extra = self.inline_short_preamble(args + virtuals, args, -short_preamble, self.optimizer.patchguardop) +short_preamble, self.optimizer.patchguardop, +target_token, label_op) self.send_extra_operation(jump_op.copy_and_change(rop.JUMP, args=args + extra, descr=target_token)) @@ -243,34 +245,40 @@ return virtual_state def inline_short_preamble(self, jump_args, args_no_virtuals, short, - patchguardop): + patchguardop, target_token, label_op): short_inputargs = short[0].getarglist() -short_jump_op = short[-1].getarglist() -lgt = len(short) - 1 -assert lgt >= 0 -short_ops = short[1:lgt] +short_jump_args = short[-1].getarglist() +if (self.short_preamble_producer and +self.short_preamble_producer.target_token is target_token): +# this means we're inlining the short preamble that's being +# built. Make sure w
[pypy-commit] pypy keys_with_hash: Identified a difference of performance with CPython: at least in
Author: Armin Rigo Branch: keys_with_hash Changeset: r79325:8ca42034ab3f Date: 2015-08-31 16:47 +0200 http://bitbucket.org/pypy/pypy/changeset/8ca42034ab3f/ Log:Identified a difference of performance with CPython: at least in RPython code, there are places where we should reuse the hash of a dict key instead of recomputing it diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -965,6 +965,9 @@ other_dict = self.unerase(w_other.sstorage) result_dict = self.get_empty_dict() for key in iterator: +# xxx performance issue when compared to CPython: the next +# two lines will recompute twice the hash of 'key', whereas +# CPython reuses the hash from 'iterator' in both cases. if key not in other_dict: result_dict[key] = None return self.erase(result_dict) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy keys_with_hash: iterkeys_with_hash()
Author: Armin Rigo Branch: keys_with_hash Changeset: r79326:d81cb45a927e Date: 2015-08-31 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/d81cb45a927e/ Log:iterkeys_with_hash() diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -11,7 +11,7 @@ SomeString, SomeChar, SomeList, SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, SomeInstance, SomeBuiltin, SomeBuiltinMethod, SomeFloat, SomeIterator, SomePBC, SomeNone, SomeType, s_ImpossibleValue, -s_Bool, s_None, unionof, add_knowntypedata, +s_Bool, s_None, s_Int, unionof, add_knowntypedata, HarmlesslyBlocked, SomeWeakRef, SomeUnicodeString, SomeByteArray) from rpython.annotator.bookkeeper import getbookkeeper, immutablevalue from rpython.annotator import builtin @@ -409,6 +409,8 @@ return s_ImpossibleValue else: return SomeTuple((s_key, s_value)) +if variant == 'keys_with_hash': +return SomeTuple((self.dictdef.read_key(), s_Int)) else: raise ValueError diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -788,6 +788,27 @@ d = d.keys() return reversed(d) +def iterkeys_with_hash(d): +"""Iterates (key, hash) pairs without recomputing the hash.""" +assert not we_are_translated()# this code is only before translation +for k in d: +yield k, compute_hash(k) + +class Entry(ExtRegistryEntry): +_about_ = iterkeys_with_hash + +def compute_result_annotation(self, s_d): +from rpython.annotator.model import SomeDict, SomeIterator, s_None +if isinstance(s_d, SomeDict): +return SomeIterator(s_d, 'keys_with_hash') +if s_None.contains(s_d): +return None +raise Exception("iterkeys_with_hash(x): x not a dict") + +def specialize_call(self, hop): +from rpython.rtyper.lltypesystem.rdict import DictIteratorRepr +hop.exception_cannot_occur() +return DictIteratorRepr(hop.args_r[0], "keys_with_hash").newiter(hop) # diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py --- a/rpython/rlib/test/test_objectmodel.py +++ b/rpython/rlib/test/test_objectmodel.py @@ -592,6 +592,22 @@ r = interpret(f, [29]) assert r == 1 +def test_iterkeys_with_hash(): +def f(i): +d = {i+.0: 5, i+.5: 6} +total = 0 +for k, h in iterkeys_with_hash(d): +print k, h +print compute_hash(k) +total += k * h +total -= (i + 0.0) * compute_hash(i + 0.0) +total -= (i + 0.5) * compute_hash(i + 0.5) +return total + +assert f(29) == 0.0 +r = interpret(f, [29]) +assert r == 0.0 + def test_import_from_mixin(): class M:# old-style def f(self): pass diff --git a/rpython/rtyper/rdict.py b/rpython/rtyper/rdict.py --- a/rpython/rtyper/rdict.py +++ b/rpython/rtyper/rdict.py @@ -79,7 +79,8 @@ hop.has_implicit_exception(RuntimeError) hop.exception_is_here() v_index = hop.gendirectcall(self._ll_dictnext, v_iter) -if variant == 'items' and hop.r_result.lowleveltype != lltype.Void: +if ((variant == 'items' and hop.r_result.lowleveltype != lltype.Void) or + variant == 'keys_with_hash'): # this allocates the tuple for the result, directly in the function # where it will be used (likely). This will let it be removed. c1 = hop.inputconst(lltype.Void, hop.r_result.lowleveltype.TO) @@ -98,11 +99,14 @@ c_key = hop.inputconst(lltype.Void, 'key') v_key = hop.genop('getinteriorfield', [v_entries, v_index, c_key], resulttype=KEY) -if variant != 'keys' and variant != 'reversed': +if variant == 'values' or variant == 'items': VALUE = ENTRIES.TO.OF.value c_value = hop.inputconst(lltype.Void, 'value') v_value = hop.genop('getinteriorfield', [v_entries,v_index,c_value], resulttype=VALUE) +elif variant == 'keys_with_hash': +v_value = hop.gendirectcall(ENTRIES.TO.hash, v_entries, v_index) +# if variant == 'keys' or variant == 'reversed': return self.r_dict.recast_key(hop.llops, v_key) elif variant == 'values': @@ -110,7 +114,7 @@ elif hop.r_result.lowleveltype == lltype.Void: return hop.inputconst(lltype.Void, None) else: -assert variant == 'items' +assert variant == 'items' or variant == 'keys_with_hash' ITEM0 = v_result.concretetype.TO.item0 ITEM1 = v_result.concretetype.TO.item1 if ITE
[pypy-commit] pypy optresult-unroll: add a bigger warning
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79329:92bdb99cc924 Date: 2015-08-31 19:13 +0200 http://bitbucket.org/pypy/pypy/changeset/92bdb99cc924/ Log:add a bigger warning diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -252,6 +252,7 @@ self.short_preamble_producer.target_token is target_token): # this means we're inlining the short preamble that's being # built. Make sure we modify the correct things in-place +# THIS WILL MODIFY ALL THE LISTS PROVIDED, POTENTIALLY self.short_preamble_producer.setup(short_inputargs, short_jump_args, short, label_op.getarglist()) try: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: fix one more detail
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79327:013e6243e065 Date: 2015-08-31 19:06 +0200 http://bitbucket.org/pypy/pypy/changeset/013e6243e065/ Log:fix one more detail diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -272,8 +272,9 @@ i += 1 self.optimizer.send_extra_operation(op) # force all of them except the virtuals -for arg in short_jump_args: +for arg in args_no_virtuals + short_jump_args: self.optimizer.force_box(self.get_box_replacement(arg)) +self.optimizer.flush() return [self.get_box_replacement(box) for box in short_jump_args] finally: for op in short_inputargs: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: finish the weird modify-short-preamble-in-place
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79328:00a0ca84a79d Date: 2015-08-31 19:12 +0200 http://bitbucket.org/pypy/pypy/changeset/00a0ca84a79d/ Log:finish the weird modify-short-preamble-in-place diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py --- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py +++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py @@ -344,7 +344,32 @@ empty_info = EmptyInfo() class AbstractShortPreambleBuilder(object): -pass +def use_box(self, box, preamble_op, optimizer=None): +for arg in preamble_op.getarglist(): +if isinstance(arg, Const): +continue +if isinstance(arg, AbstractInputArg): +info = arg.get_forwarded() +if info is not None and info is not empty_info: +info.make_guards(arg, self.short) +elif arg.get_forwarded() is None: +pass +else: +self.short.append(arg) +info = arg.get_forwarded() +if info is not empty_info: +info.make_guards(arg, self.short) +arg.set_forwarded(None) +self.short.append(preamble_op) +if preamble_op.is_ovf(): +self.short.append(ResOperation(rop.GUARD_NO_OVERFLOW, [], None)) +info = preamble_op.get_forwarded() +preamble_op.set_forwarded(None) +if optimizer is not None: +optimizer.setinfo_from_preamble(box, info, None) +if info is not empty_info: +info.make_guards(preamble_op, self.short) +return preamble_op class ShortPreambleBuilder(AbstractShortPreambleBuilder): """ ShortPreambleBuilder is used during optimizing of the peeled loop, @@ -372,33 +397,6 @@ self.extra_same_as = [] self.short_inputargs = short_inputargs -def use_box(self, box, preamble_op, optimizer=None): -for arg in preamble_op.getarglist(): -if isinstance(arg, Const): -continue -if isinstance(arg, AbstractInputArg): -info = arg.get_forwarded() -if info is not None and info is not empty_info: -info.make_guards(arg, self.short) -elif arg.get_forwarded() is None: -pass -else: -self.short.append(arg) -info = arg.get_forwarded() -if info is not empty_info: -info.make_guards(arg, self.short) -arg.set_forwarded(None) -self.short.append(preamble_op) -if preamble_op.is_ovf(): -self.short.append(ResOperation(rop.GUARD_NO_OVERFLOW, [], None)) -info = preamble_op.get_forwarded() -preamble_op.set_forwarded(None) -if optimizer is not None: -optimizer.setinfo_from_preamble(box, info, None) -if info is not empty_info: -info.make_guards(preamble_op, self.short) -return preamble_op - def add_preamble_op(self, preamble_op): """ Notice that we're actually using the preamble_op, add it to label and jump @@ -444,3 +442,8 @@ self.sb.label_dict[op] = None self.label_args.append(op) self.jump_args.append(preamble_op.preamble_op) + +def use_box(self, box, preamble_op, optimizer=None): +jump_op = self.short.pop() +AbstractShortPreambleBuilder.use_box(self, box, preamble_op, optimizer) +self.short.append(jump_op) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -8372,9 +8372,9 @@ expected = """ [p1, p2] call_n(p2, descr=nonwritedescr) +ifoo = arraylen_gc(p1, descr=gcarraydescr) # killed p3 = new_with_vtable(descr=nodesize) setarrayitem_gc(p1, 3, p3, descr=gcarraydescr) -ifoo = arraylen_gc(p1, descr=gcarraydescr) # killed jump(p1, p3) """ self.optimize_loop(ops, expected) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: fix?
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79330:94a4ee12ccc0 Date: 2015-08-31 19:17 +0200 http://bitbucket.org/pypy/pypy/changeset/94a4ee12ccc0/ Log:fix? diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py @@ -256,12 +256,10 @@ raise BadVirtualState for i in range(len(self.fieldstate)): fieldbox = info.getitem(self.arraydescr, i) -if fieldbox is None: -raise Exception("do we ever get here?") -v = value.get_missing_null_value() s = self.fieldstate[i] -if s.position > self.position: -s.enum_forced_boxes(boxes, fieldbox, optimizer, force_boxes) +if s is not None: +if s.position > self.position: +s.enum_forced_boxes(boxes, fieldbox, optimizer, force_boxes) def _enum(self, virtual_state): for s in self.fieldstate: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: We can run a 32-bit python inside a real 64-bit environment
Author: Armin Rigo Branch: Changeset: r79332:af6c413a83e8 Date: 2015-08-31 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/af6c413a83e8/ Log:We can run a 32-bit python inside a real 64-bit environment diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -39,7 +39,8 @@ "_csv", "cppyy", "_pypyjson" ]) -if sys.platform.startswith('linux') and os.uname()[4] == 'x86_64': +if (sys.platform.startswith('linux') and os.uname()[4] == 'x86_64' +and sys.maxint > 2**32):# it's not enough that we get x86_64 working_modules.add('_vmprof') translation_modules = default_modules.copy() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy keys_with_hash: in-progress
Author: Armin Rigo Branch: keys_with_hash Changeset: r79331:d7605de37f95 Date: 2015-08-31 19:57 +0200 http://bitbucket.org/pypy/pypy/changeset/d7605de37f95/ Log:in-progress diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -369,14 +369,19 @@ return None# r_dict: can throw anything return [] # else: no possible exception -@op.contains.register(SomeDict) -def contains_SomeDict(annotator, dct, element): - annotator.annotation(dct).dictdef.generalize_key(annotator.annotation(element)) -if annotator.annotation(dct)._is_empty(): +# also used for objectmodel.contains_with_hash() +def dict_contains(s_dct, s_element): +s_dct.dictdef.generalize_key(s_element) +if s_dct._is_empty(): s_bool = SomeBool() s_bool.const = False return s_bool return s_Bool + +@op.contains.register(SomeDict) +def contains_SomeDict(annotator, dct, element): +return dict_contains(annotator.annotation(dct), + annotator.annotation(element)) contains_SomeDict.can_only_throw = _can_only_throw class __extend__(SomeDict): diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -792,7 +792,14 @@ """Iterates (key, hash) pairs without recomputing the hash.""" assert not we_are_translated()# this code is only before translation for k in d: -yield k, compute_hash(k) +yield k, hash(k) + +def contains_with_hash(d, key, h): +"""Same as 'key in d'. The extra argument is the hash. Use this only +if you got the hash just now from some other ..._with_hash() function.""" +assert not we_are_translated()# this code is only before translation +assert hash(key) == h +return key in d class Entry(ExtRegistryEntry): _about_ = iterkeys_with_hash @@ -810,6 +817,27 @@ hop.exception_cannot_occur() return DictIteratorRepr(hop.args_r[0], "keys_with_hash").newiter(hop) +class Entry(ExtRegistryEntry): +_about_ = contains_with_hash + +def compute_result_annotation(self, s_d, s_key, s_hash): +from rpython.annotator.model import s_Bool, SomeDict, s_None +from rpython.annotator.unaryop import dict_contains +if isinstance(s_d, SomeDict): +return dict_contains(s_d, s_key) +if s_None.contains(s_d): +return None +raise Exception("contains_with_hash(x, ...): x not a dict") + +def specialize_call(self, hop): +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.rdict import ll_contains_with_hash +r_dict = hop.args_r[0] +v_dict, v_key, v_hash = hop.inputargs(r_dict, r_dict.key_repr, + lltype.Signed) +hop.exception_cannot_occur() +return hop.gendirectcall(ll_contains_with_hash, v_dict, v_key, v_hash) + # def import_from_mixin(M, special_methods=['__init__', '__del__']): diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py --- a/rpython/rlib/test/test_objectmodel.py +++ b/rpython/rlib/test/test_objectmodel.py @@ -608,6 +608,16 @@ r = interpret(f, [29]) assert r == 0.0 +def test_contains_with_hash(): +def f(i): +d = {i+.5: 5} +assert contains_with_hash(d, i+.5, compute_hash(i+.5)) +assert not contains_with_hash(d, i+.3, compute_hash(i+.3)) +return 0 + +f(29) +interpret(f, [29]) + def test_import_from_mixin(): class M:# old-style def f(self): pass diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -871,6 +871,11 @@ i = ll_dict_lookup(d, key, d.keyhash(key)) return not i & HIGHEST_BIT +# for objectmodel.contains_with_hash() +def ll_contains_with_hash(d, key, hash): +i = ll_dict_lookup(d, key, hash) +return not i & HIGHEST_BIT + POPITEMINDEX = lltype.Struct('PopItemIndex', ('nextindex', lltype.Signed)) global_popitem_index = lltype.malloc(POPITEMINDEX, zero=True, immortal=True) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy optresult-unroll: kill mark_opaque_ptr tests, the plan is to do it differently anyway
Author: Maciej Fijalkowski Branch: optresult-unroll Changeset: r79333:d97a7a41ff5b Date: 2015-08-31 20:26 +0200 http://bitbucket.org/pypy/pypy/changeset/d97a7a41ff5b/ Log:kill mark_opaque_ptr tests, the plan is to do it differently anyway diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -8544,89 +8544,6 @@ """ self.raises(InvalidLoop, self.optimize_loop, ops, ops) -def test_licm_boxed_opaque_getitem(self): -ops = """ -[p1] -p2 = getfield_gc_r(p1, descr=nextdescr) -mark_opaque_ptr(p2) -guard_class(p2, ConstClass(node_vtable)) [] -i3 = getfield_gc_i(p2, descr=valuedescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p1) -""" -expected = """ -[p1, p2, i3] -i4 = call_i(i3, descr=nonwritedescr) -jump(p1, p2, i3) -""" -self.optimize_loop(ops, expected) - -def test_licm_boxed_opaque_getitem_unknown_class(self): -# Explanation: the getfield_gc(p2) is done on what starts as -# an opaque object. The getfield_gc(p1) is moved out of the -# (non-preamble) loop. It looks like the getfield_gc(p2) -# should also move out. However, moving the getfield_gc(p2) -# earlier can be dangerous with opaque pointers: we can't move -# it before other guards that indirectly check for which type -# of object is in p2. (In this simple test there are no guard -# at all between the start of the loop and the -# getfield_gc(p2), but in general there are.) -# -# There are two cases: (1) moving the getfield_gc(p2) out of -# the loop into the preamble: this does not look like a -# problem because we already have a getfield_gc(p2) there, on -# the same p2. Case (2) is moving the getfield_gc(p2) into -# the short preamble: this is more problematic because the -# short preamble can't do the indirect checking on p1. -ops = """ -[p1] -p2 = getfield_gc_r(p1, descr=nextdescr) -mark_opaque_ptr(p2) -i3 = getfield_gc_i(p2, descr=valuedescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p1) -""" -expected = """ -[p1, p2] -i3 = getfield_gc_i(p2, descr=valuedescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p1, p2) -""" -self.optimize_loop(ops, expected) - -def test_licm_unboxed_opaque_getitem(self): -ops = """ -[p2] -mark_opaque_ptr(p2) -guard_class(p2, ConstClass(node_vtable)) [] -i3 = getfield_gc_i(p2, descr=otherdescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p2) -""" -expected = """ -[p1, i3] -i4 = call_i(i3, descr=nonwritedescr) -jump(p1, i3) -""" -self.optimize_loop(ops, expected) - -def test_licm_unboxed_opaque_getitem_unknown_class(self): -# see test_licm_boxed_opaque_getitem_unknown_class -ops = """ -[p2] -mark_opaque_ptr(p2) -i3 = getfield_gc_i(p2, descr=otherdescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p2) -""" -expected = """ -[p2] -i3 = getfield_gc_i(p2, descr=otherdescr) -i4 = call_i(i3, descr=nonwritedescr) -jump(p2) -""" -self.optimize_loop(ops, expected) - def test_only_strengthen_guard_if_class_matches_2(self): ops = """ [p1] ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit