[pypy-commit] pypy optresult: work on rpython and recursive stuff
fijal
noreply at buildbot.pypy.org
Tue Jun 2 15:19:27 CEST 2015
Author: Maciej Fijalkowski <fijall at 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,
More information about the pypy-commit
mailing list