Author: Maciej Fijalkowski <fij...@gmail.com> Branch: optresult Changeset: r77761:c3aeb7fe8605 Date: 2015-06-02 14:56 +0200 http://bitbucket.org/pypy/pypy/changeset/c3aeb7fe8605/
Log: work on rpython and recursive stuff diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -995,63 +995,64 @@ execute_call_release_gil_r = _execute_call_release_gil execute_call_release_gil_f = _execute_call_release_gil - def _execute_call_assembler(self, descr, *args): - # XXX simplify the following a bit - # - # pframe = CALL_ASSEMBLER(args..., descr=looptoken) - # ==> - # pframe = CALL looptoken.loopaddr(*args) - # JUMP_IF_FAST_PATH @fastpath - # res = CALL assembler_call_helper(pframe) - # jmp @done - # @fastpath: - # res = GETFIELD(pframe, 'result') - # @done: - # - call_op = self.lltrace.operations[self.current_index] - guard_op = self.lltrace.operations[self.current_index + 1] - assert guard_op.getopnum() == rop.GUARD_NOT_FORCED - self.force_guard_op = guard_op - pframe = self.cpu._execute_token(descr, *args) - del self.force_guard_op - # - jd = descr.outermost_jitdriver_sd - assert jd is not None, ("call_assembler(): the loop_token needs " - "to have 'outermost_jitdriver_sd'") - if jd.index_of_virtualizable != -1: - vable = args[jd.index_of_virtualizable] - else: - vable = lltype.nullptr(llmemory.GCREF.TO) - # - # Emulate the fast path - # - faildescr = self.cpu.get_latest_descr(pframe) - if faildescr == self.cpu.done_with_this_frame_descr_int: - return self.cpu.get_int_value(pframe, 0) - elif faildescr == self.cpu.done_with_this_frame_descr_ref: - return self.cpu.get_ref_value(pframe, 0) - elif faildescr == self.cpu.done_with_this_frame_descr_float: - return self.cpu.get_float_value(pframe, 0) - elif faildescr == self.cpu.done_with_this_frame_descr_void: - return None + def _new_execute_call_assembler(def_val): + def _execute_call_assembler(self, descr, *args): + # XXX simplify the following a bit + # + # pframe = CALL_ASSEMBLER(args..., descr=looptoken) + # ==> + # pframe = CALL looptoken.loopaddr(*args) + # JUMP_IF_FAST_PATH @fastpath + # res = CALL assembler_call_helper(pframe) + # jmp @done + # @fastpath: + # res = GETFIELD(pframe, 'result') + # @done: + # + call_op = self.lltrace.operations[self.current_index] + guard_op = self.lltrace.operations[self.current_index + 1] + assert guard_op.getopnum() == rop.GUARD_NOT_FORCED + self.force_guard_op = guard_op + pframe = self.cpu._execute_token(descr, *args) + del self.force_guard_op + # + jd = descr.outermost_jitdriver_sd + assert jd is not None, ("call_assembler(): the loop_token needs " + "to have 'outermost_jitdriver_sd'") + if jd.index_of_virtualizable != -1: + vable = args[jd.index_of_virtualizable] + else: + vable = lltype.nullptr(llmemory.GCREF.TO) + # + # Emulate the fast path + # + faildescr = self.cpu.get_latest_descr(pframe) + if faildescr == self.cpu.done_with_this_frame_descr_int: + return self.cpu.get_int_value(pframe, 0) + elif faildescr == self.cpu.done_with_this_frame_descr_ref: + return self.cpu.get_ref_value(pframe, 0) + elif faildescr == self.cpu.done_with_this_frame_descr_float: + return self.cpu.get_float_value(pframe, 0) + elif faildescr == self.cpu.done_with_this_frame_descr_void: + return None - assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish - try: - result = assembler_helper_ptr(pframe, vable) - except LLException, lle: - assert self.last_exception is None, "exception left behind" - self.last_exception = lle - # fish op - op = self.current_op - return op.result and op.result.value - if isinstance(result, float): - result = support.cast_to_floatstorage(result) - return result + assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish + try: + result = assembler_helper_ptr(pframe, vable) + except LLException, lle: + assert self.last_exception is None, "exception left behind" + self.last_exception = lle + # fish op + result = def_val + if isinstance(result, float): + result = support.cast_to_floatstorage(result) + return result + return _execute_call_assembler - execute_call_assembler_i = _execute_call_assembler - execute_call_assembler_r = _execute_call_assembler - execute_call_assembler_f = _execute_call_assembler - execute_call_assembler_n = _execute_call_assembler + execute_call_assembler_i = _new_execute_call_assembler(0) + execute_call_assembler_r = _new_execute_call_assembler(lltype.nullptr(llmemory.GCREF.TO)) + execute_call_assembler_f = _new_execute_call_assembler(0.0) + execute_call_assembler_n = _new_execute_call_assembler(None) def execute_same_as_i(self, _, x): return x diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py --- a/rpython/jit/codewriter/heaptracker.py +++ b/rpython/jit/codewriter/heaptracker.py @@ -105,10 +105,9 @@ def finish_registering(cpu): # annotation hack for small examples which have no vtable at all - pass - #if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): - # vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) - # register_known_gctype(cpu, vtable, rclass.OBJECT) + if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): + vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + register_known_gctype(cpu, vtable, rclass.OBJECT) def vtable2descr(cpu, vtable): assert lltype.typeOf(vtable) is lltype.Signed diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -8,14 +8,14 @@ from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside from rpython.conftest import option -from rpython.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist +from rpython.jit.metainterp.resoperation import ResOperation, rop,\ + get_deep_immutable_oplist, OpHelpers from rpython.jit.metainterp.history import (TreeLoop, Const, JitCellToken, TargetToken, AbstractFailDescr, ConstInt) from rpython.jit.metainterp import history, jitexc from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP, ResumeDataDirectReader from rpython.jit.codewriter import heaptracker, longlong -from rpython.jit.metainterp.inliner import Inliner def giveup(): @@ -161,7 +161,7 @@ if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) if part.operations[-1].getopnum() == rop.LABEL: - xxx + raise Exception("unrolling unsupported") d = part.operations[0].getdescr() assert isinstance(d, TargetToken) part.operations[-1] = part.operations[-1].copy_and_change(rop.JUMP, @@ -280,8 +280,37 @@ record_loop_or_bridge(metainterp_sd, loop) return target_token +def get_box_replacement(op, allow_none=False): + if allow_none and op is None: + return None # for failargs + while op.get_forwarded(): + op = op.get_forwarded() + return op + +def emit_op(lst, op): + op = get_box_replacement(op) + orig_op = op + # XXX specialize on number of args + replaced = False + for i in range(op.numargs()): + orig_arg = op.getarg(i) + arg = get_box_replacement(orig_arg) + if orig_arg is not arg: + if not replaced: + op = op.copy_and_change(op.getopnum()) + orig_op.set_forwarded(op) + replaced = True + op.setarg(i, arg) + if op.is_guard(): + if not replaced: + op = op.copy_and_change(op.getopnum()) + orig_op.set_forwarded(op) + op.setfailargs([get_box_replacement(a, True) + for a in op.getfailargs()]) + lst.append(op) + def patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd): - xxx + # XXX merge with rewriting vinfo = jitdriver_sd.virtualizable_info extra_ops = [] inputargs = loop.inputargs @@ -291,28 +320,33 @@ for descr in vinfo.static_field_descrs: assert i < len(inputargs) box = inputargs[i] - extra_ops.append( - ResOperation(rop.GETFIELD_GC, [vable_box], box, descr)) + opnum = OpHelpers.getfield_for_descr(descr) + emit_op(extra_ops, + ResOperation(opnum, [vable_box], descr)) + box.set_forwarded(extra_ops[-1]) i += 1 arrayindex = 0 for descr in vinfo.array_field_descrs: vable = vable_box.getref_base() arraylen = vinfo.get_array_length(vable, arrayindex) - arraybox = BoxPtr() - extra_ops.append( - ResOperation(rop.GETFIELD_GC, [vable_box], arraybox, descr)) + arrayop = ResOperation(rop.GETFIELD_GC, [vable_box], descr) + emit_op(extra_ops, arrayop) arraydescr = vinfo.array_descrs[arrayindex] assert i + arraylen <= len(inputargs) for index in range(arraylen): + opnum = OpHelpers.getarrayitem_for_descr(arraydescr) box = inputargs[i] - extra_ops.append( + emit_op(extra_ops, ResOperation(rop.GETARRAYITEM_GC, - [arraybox, ConstInt(index)], - box, descr=arraydescr)) + [arrayop, ConstInt(index)], + descr=arraydescr)) i += 1 + box.set_forwarded(extra_ops[-1]) arrayindex += 1 assert i == len(inputargs) - loop.operations = extra_ops + loop.operations + for op in loop.operations: + emit_op(extra_ops, op) + loop.operations = extra_ops def propagate_original_jitcell_token(trace): for op in trace.operations: @@ -915,7 +949,8 @@ calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ - xxx + import pdb + pdb.set_trace() jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -162,7 +162,9 @@ @specialize.argtype(0) def newconst(value): - if lltype.typeOf(value) == lltype.Signed: + if value is None: + return ConstPtr(lltype.nullptr(llmemory.GCREF.TO)) + elif lltype.typeOf(value) == lltype.Signed: return ConstInt(value) elif type(value) is bool: return ConstInt(int(value)) @@ -403,7 +405,7 @@ _attrs_ = ('value',) def __init__(self, value=0): - xxx + raise Exception("boxes no longer supported") if not we_are_translated(): if is_valid_int(value): value = int(value) # bool -> int @@ -470,7 +472,7 @@ _attrs_ = ('value',) def __init__(self, value=lltype.nullptr(llmemory.GCREF.TO)): - xxx + raise Exception("boxes no longer supported") assert lltype.typeOf(value) == llmemory.GCREF self.value = value @@ -756,7 +758,21 @@ @specialize.argtype(3) def record(self, opnum, argboxes, value, descr=None): op = ResOperation(opnum, argboxes, descr) - op.setvalue(value) + if value is None: + assert op.type == 'v' + elif type(value) is bool: + assert op.type == 'i' + op.setint(int(value)) + elif isinstance(value, float): + assert op.type == 'f' + op.setfloatstorage(value) + elif lltype.typeOf(value) == lltype.Signed: + assert op.type == 'i' + op.setint(value) + else: + assert lltype.typeOf(value) == llmemory.GCREF + assert op.type == 'r' + op.setref_base(value) self.operations.append(op) return op diff --git a/rpython/jit/metainterp/jitprof.py b/rpython/jit/metainterp/jitprof.py --- a/rpython/jit/metainterp/jitprof.py +++ b/rpython/jit/metainterp/jitprof.py @@ -110,9 +110,9 @@ return self.counters[num] def count_ops(self, opnum, kind=Counters.OPS): - from rpython.jit.metainterp.resoperation import rop + from rpython.jit.metainterp.resoperation import OpHelpers self.counters[kind] += 1 - if opnum == rop.CALL and kind == Counters.RECORDED_OPS: + if OpHelpers.is_call(opnum) and kind == Counters.RECORDED_OPS: self.calls += 1 def print_stats(self): diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -59,7 +59,7 @@ loop.operations) optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts) if unroll: - xxx + raise Exception("unrolling disabled") return optimize_unroll(metainterp_sd, jitdriver_sd, loop, optimizations, inline_short_preamble, start_state, diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -19,7 +19,7 @@ from rpython.rlib.jit import Counters from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.rlib.unroll import unrolling_iterable -from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory from rpython.rtyper import rclass @@ -682,9 +682,9 @@ def opimpl_getfield_gc_f_pure(self, box, fielddescr): if isinstance(box, ConstPtr): # if 'box' is directly a ConstPtr, bypass the heapcache completely - resbox = executor.execute(self.metainterp.cpu, self.metainterp, + resvalue = executor.execute(self.metainterp.cpu, self.metainterp, rop.GETFIELD_GC_PURE_F, fielddescr, box) - return resbox.constbox() + return ConstPtr(resvalue) return self._opimpl_getfield_gc_any_pureornot( rop.GETFIELD_GC_PURE_F, box, fielddescr, 'f') @@ -692,9 +692,9 @@ def opimpl_getfield_gc_r_pure(self, box, fielddescr): if isinstance(box, ConstPtr): # if 'box' is directly a ConstPtr, bypass the heapcache completely - resbox = executor.execute(self.metainterp.cpu, self.metainterp, + val = executor.execute(self.metainterp.cpu, self.metainterp, rop.GETFIELD_GC_PURE_R, fielddescr, box) - return resbox.constbox() + return ConstFloat(val) return self._opimpl_getfield_gc_any_pureornot( rop.GETFIELD_GC_PURE_R, box, fielddescr, 'r') @@ -1555,9 +1555,21 @@ if resbox is not None: return resbox self.metainterp.vable_and_vrefs_before_residual_call() - opnum = OpHelpers.call_may_force_for_descr(descr) - resbox = self.metainterp.execute_and_record_varargs( - opnum, allboxes, descr=descr) + tp = descr.get_result_type() + if tp == 'i': + resbox = self.metainterp.execute_and_record_varargs( + rop.CALL_MAY_FORCE_I, allboxes, descr=descr) + elif tp == 'r': + resbox = self.metainterp.execute_and_record_varargs( + rop.CALL_MAY_FORCE_R, allboxes, descr=descr) + elif tp == 'f': + resbox = self.metainterp.execute_and_record_varargs( + rop.CALL_MAY_FORCE_F, allboxes, descr=descr) + elif tp == 'v': + resbox = self.metainterp.execute_and_record_varargs( + rop.CALL_MAY_FORCE_N, allboxes, descr=descr) + else: + assert False if effectinfo.is_call_release_gil(): self.metainterp.direct_call_release_gil() self.metainterp.vrefs_after_residual_call() @@ -1565,7 +1577,7 @@ if assembler_call: vablebox, resbox = self.metainterp.direct_assembler_call( assembler_call_jd) - if resbox is not None: + if resbox and resbox.type != 'v': self.make_result_of_lastop(resbox) self.metainterp.vable_after_residual_call(funcbox) self.metainterp.generate_guard(rop.GUARD_NOT_FORCED, None) @@ -1578,15 +1590,42 @@ return resbox else: effect = effectinfo.extraeffect + tp = descr.get_result_type() if effect == effectinfo.EF_LOOPINVARIANT: - opnum = OpHelpers.call_loopinvariant_for_descr(descr) - return self.execute_varargs(opnum, - allboxes, - descr, False, False) + if tp == 'i': + return self.execute_varargs(rop.CALL_LOOPINVARIANT_I, + allboxes, + descr, False, False) + elif tp == 'r': + return self.execute_varargs(rop.CALL_LOOPINVARIANT_R, + allboxes, + descr, False, False) + elif tp == 'f': + return self.execute_varargs(rop.CALL_LOOPINVARIANT_F, + allboxes, + descr, False, False) + elif tp == 'v': + return self.execute_varargs(rop.CALL_LOOPINVARIANT_N, + allboxes, + descr, False, False) + else: + assert False exc = effectinfo.check_can_raise() pure = effectinfo.check_is_elidable() - opnum = OpHelpers.call_for_descr(descr) - return self.execute_varargs(opnum, allboxes, descr, exc, pure) + if tp == 'i': + return self.execute_varargs(rop.CALL_I, allboxes, descr, + exc, pure) + elif tp == 'r': + return self.execute_varargs(rop.CALL_R, allboxes, descr, + exc, pure) + elif tp == 'f': + return self.execute_varargs(rop.CALL_F, allboxes, descr, + exc, pure) + elif tp == 'v': + return self.execute_varargs(rop.CALL_N, allboxes, descr, + exc, pure) + else: + assert False finally: debug_stop("jit-residual-call") @@ -1957,7 +1996,11 @@ moreargs = [box] + extraargs else: moreargs = list(extraargs) - guard_op = self.history.record(opnum, moreargs, None) + if opnum == rop.GUARD_EXCEPTION: + guard_op = self.history.record(opnum, moreargs, + lltype.nullptr(llmemory.GCREF.TO)) + else: + guard_op = self.history.record(opnum, moreargs, None) assert isinstance(guard_op, GuardResOp) self.capture_resumedata(guard_op, resumepc) self.staticdata.profiler.count_ops(opnum, Counters.GUARDS) @@ -2681,7 +2724,7 @@ vrefbox = self.virtualref_boxes[i+1] # record VIRTUAL_REF_FINISH just before the current CALL_MAY_FORCE call_may_force_op = self.history.operations.pop() - assert call_may_force_op.getopnum() == rop.CALL_MAY_FORCE + assert call_may_force_op.is_call_may_force() self.history.record(rop.VIRTUAL_REF_FINISH, [vrefbox, virtualbox], None) self.history.operations.append(call_may_force_op) @@ -2971,12 +3014,13 @@ def direct_call_release_gil(self): op = self.history.operations.pop() - assert op.opnum == rop.CALL_MAY_FORCE + assert op.is_call_may_force() descr = op.getdescr() effectinfo = descr.get_extra_info() realfuncaddr, saveerr = effectinfo.call_release_gil_target funcbox = ConstInt(heaptracker.adr2int(realfuncaddr)) savebox = ConstInt(saveerr) + assert False, "not yet" self.history.record(rop.CALL_RELEASE_GIL, [savebox, funcbox] + op.getarglist()[1:], op.result, descr) diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -6,6 +6,7 @@ class AbstractValue(object): _repr_memo = {} is_info_class = False + _attrs_ = () def _get_hash_(self): return compute_identity_hash(self) @@ -129,21 +130,6 @@ if self.type != 'v': newop.copy_value_from(self) return newop - - @specialize.argtype(1) - def setvalue(self, value): - if lltype.typeOf(value) == lltype.Signed: - self._resint = value - elif type(value) == bool: - self._resint = int(value) - elif isinstance(value, float): - self._resfloat = value - elif value is None: - pass - else: - assert lltype.typeOf(value) == llmemory.GCREF - self._resref = value - def clone(self, memo): args = [memo.get(arg, arg) for arg in self.getarglist()] @@ -1124,6 +1110,10 @@ return rop.CALL_N @staticmethod + def is_call(opnum): + return rop._CALL_FIRST <= opnum <= rop._CALL_LAST + + @staticmethod def is_call_assembler(opnum): return (opnum == rop.CALL_ASSEMBLER_I or opnum == rop.CALL_ASSEMBLER_R or diff --git a/rpython/jit/metainterp/virtualref.py b/rpython/jit/metainterp/virtualref.py --- a/rpython/jit/metainterp/virtualref.py +++ b/rpython/jit/metainterp/virtualref.py @@ -27,7 +27,9 @@ adr = heaptracker.adr2int(adr) self.jit_virtual_ref_const_class = history.ConstInt(adr) fielddescrof = self.cpu.fielddescrof - self.cpu.gc_ll_descr._cache_gcstruct2vtable[self.JIT_VIRTUAL_REF] = self.jit_virtual_ref_vtable + if hasattr(self.cpu, 'gc_ll_descr'): + heaptracker.setup_cache_gcstruct2vtable(self.cpu.gc_ll_descr) + self.cpu.gc_ll_descr._cache_gcstruct2vtable[self.JIT_VIRTUAL_REF] = self.jit_virtual_ref_vtable self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, 'virtual_token') self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced') diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -320,7 +320,8 @@ else: # no vtable from lltype2vtable -- double-check to be sure # that it's not a subclass of OBJECT. - assert not is_subclass_of_object(TYPE) + pass + #assert not is_subclass_of_object(TYPE) def get_info(self, type_id): res = llop.get_group_member(GCData.TYPE_INFO_PTR, _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit