[pypy-svn] r29490 - in pypy/dist/pypy: jit/timeshifter jit/timeshifter/test rpython rpython/lltypesystem
arigo at codespeak.net
arigo at codespeak.net
Thu Jun 29 15:40:50 CEST 2006
Author: arigo
Date: Thu Jun 29 15:40:47 2006
New Revision: 29490
Added:
pypy/dist/pypy/jit/timeshifter/oop.py (contents, props changed)
Modified:
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_vlist.py
pypy/dist/pypy/jit/timeshifter/vlist.py
pypy/dist/pypy/rpython/lltypesystem/rlist.py
pypy/dist/pypy/rpython/rgenop.py
Log:
(arre, pedronis, arigo)
Forcing lists, and more oopspec wacking to support falling back to the
original operation in case of forced lists.
Added: pypy/dist/pypy/jit/timeshifter/oop.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/timeshifter/oop.py Thu Jun 29 15:40:47 2006
@@ -0,0 +1,71 @@
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython import rgenop
+from pypy.jit.timeshifter.rcontainer import cachedtype
+from pypy.jit.timeshifter import rvalue
+
+
+class Index:
+ def __init__(self, n):
+ self.n = n
+
+
+class OopSpecDesc:
+ __metaclass__ = cachedtype
+
+ def __init__(self, fnobj):
+ ll_func = fnobj._callable
+ FUNCTYPE = lltype.typeOf(fnobj)
+ nb_args = len(FUNCTYPE.ARGS)
+
+ # parse the oopspec and fill in the arguments
+ operation_name, args = ll_func.oopspec.split('(', 1)
+ assert args.endswith(')')
+ args = args[:-1] + ',' # trailing comma to force tuple syntax
+ argnames = ll_func.func_code.co_varnames[:nb_args]
+ d = dict(zip(argnames, [Index(n) for n in range(nb_args)]))
+ self.argtuple = eval(args, d)
+ # end of rather XXX'edly hackish parsing
+
+ self.argpositions = []
+ for i, obj in enumerate(self.argtuple):
+ if isinstance(obj, Index):
+ self.argpositions.append(obj.n + 1)
+ else:
+ self.argpositions.append(0)
+
+ for i in range(nb_args):
+ ARGTYPE = FUNCTYPE.ARGS[i]
+ assert ((i+1) in self.argpositions) == (ARGTYPE is not lltype.Void)
+
+ self.args_gv = [rgenop.placeholder(None)] * nb_args
+ self.args_gv.insert(0, rgenop.genconst(fnobj._as_ptr()))
+ self.gv_result_type = rgenop.constTYPE(FUNCTYPE.RESULT)
+ self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT)
+
+ if operation_name == 'newlist':
+ from pypy.jit.timeshifter.vlist import ListTypeDesc, oop_newlist
+ self.typedesc = ListTypeDesc(FUNCTYPE.RESULT.TO)
+ self.ll_handler = oop_newlist
+ else:
+ typename, method = operation_name.split('.')
+ method = 'oop_%s_%s' % (typename, method)
+ vmodule = __import__('pypy.jit.timeshifter.v%s' % (typename,),
+ None, None, [method])
+ self.ll_handler = getattr(vmodule, method)
+
+ def _freeze_(self):
+ return True
+
+ def residual_call(self, jitstate, argboxes):
+ args_gv = self.args_gv[:]
+ argpositions = self.argpositions
+ for i in range(len(argpositions)):
+ pos = argpositions[i]
+ if pos > 0:
+ gv_arg = argboxes[i].getgenvar(jitstate)
+ args_gv[pos] = gv_arg
+ gv_result = rgenop.genop(jitstate.curblock,
+ 'direct_call',
+ args_gv,
+ self.gv_result_type)
+ return self.redboxbuilder(self.gv_result_type, gv_result)
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Thu Jun 29 15:40:47 2006
@@ -207,23 +207,16 @@
fnobj = c_func.value._obj
if hasattr(fnobj._callable, 'oopspec'):
hop.r_s_popfirstarg()
- return self.handle_highlevel_operation(fnobj._callable, hop)
+ return self.handle_highlevel_operation(fnobj, hop)
else:
raise NotImplementedError("direct_call")
- def handle_highlevel_operation(self, ll_func, hop):
- # parse the oopspec and fill in the arguments
- class Index:
- def __init__(self, n):
- self.n = n
- operation_name, args = ll_func.oopspec.split('(', 1)
- assert args.endswith(')')
- args = args[:-1] + ',' # trailing comma to force tuple syntax
- argnames = ll_func.func_code.co_varnames[:hop.nb_args]
- d = dict(zip(argnames, [Index(n) for n in range(hop.nb_args)]))
- argtuple = eval(args, d)
+ def handle_highlevel_operation(self, fnobj, hop):
+ from pypy.jit.timeshifter.oop import OopSpecDesc, Index
+ oopspecdesc = OopSpecDesc(fnobj)
+
args_v = []
- for obj in argtuple:
+ for obj in oopspecdesc.argtuple:
if isinstance(obj, Index):
hs = hop.args_s[obj.n]
r_arg = self.getredrepr(originalconcretetype(hs))
@@ -231,7 +224,6 @@
else:
v = hop.inputconst(self.getredrepr(lltype.typeOf(obj)), obj)
args_v.append(v)
- # end of rather XXX'edly hackish parsing
ts = self.timeshifter
args_s = [ts.s_RedBox] * len(args_v)
@@ -241,26 +233,15 @@
else:
s_result = ts.s_RedBox
- if operation_name == 'newlist':
- from pypy.jit.timeshifter.vlist import ListTypeDesc, oop_newlist
- typedesc = ListTypeDesc(RESULT.TO)
- c_typedesc = inputconst(lltype.Void, typedesc)
- s_typedesc = ts.rtyper.annotator.bookkeeper.immutablevalue(typedesc)
- args_v.insert(0, c_typedesc)
- args_s.insert(0, s_typedesc)
- ll_handler = oop_newlist
- else:
- typename, method = operation_name.split('.')
- method = 'oop_%s_%s' % (typename, method)
- vmodule = __import__('pypy.jit.timeshifter.v%s' % (typename,),
- None, None, [method])
- ll_handler = getattr(vmodule, method)
+ c_oopspecdesc = hop.inputconst(lltype.Void, oopspecdesc)
+ s_oopspecdesc = ts.rtyper.annotator.bookkeeper.immutablevalue(
+ oopspecdesc)
v_jitstate = hop.llops.getjitstate()
- return hop.llops.genmixlevelhelpercall(ll_handler,
- [ts.s_JITState] + args_s,
- [v_jitstate] + args_v,
- s_result)
+ return hop.llops.genmixlevelhelpercall(oopspecdesc.ll_handler,
+ [ts.s_JITState, s_oopspecdesc] + args_s,
+ [v_jitstate, c_oopspecdesc] + args_v,
+ s_result)
class HintLowLevelOpList(LowLevelOpList):
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Jun 29 15:40:47 2006
@@ -63,6 +63,23 @@
# XXX what about long longs?
return IntRedBox
+def redboxbuilder_void(gv_type, gv_value):return None
+def redboxbuilder_int(gv_ptr, gv_value): return IntRedBox(gv_ptr, gv_value)
+def redboxbuilder_dbl(gv_ptr, gv_value): return DoubleRedBox(gv_ptr, gv_value)
+def redboxbuilder_ptr(gv_ptr, gv_value): return PtrRedBox(gv_ptr, gv_value)
+
+def ll_redboxbuilder(TYPE):
+ if TYPE is lltype.Void:
+ return redboxbuilder_void
+ elif isinstance(TYPE, lltype.Ptr):
+ return redboxbuilder_ptr
+ elif TYPE is lltype.Float:
+ return redboxbuilder_dbl
+ else:
+ assert isinstance(TYPE, lltype.Primitive)
+ # XXX what about long longs?
+ return redboxbuilder_int
+
def ll_fromvalue(value):
"Make a constant RedBox from a low-level value."
T = lltype.typeOf(value)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_vlist.py Thu Jun 29 15:40:47 2006
@@ -60,3 +60,15 @@
insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC)
assert res == 131
assert insns == {'int_is_true': 1}
+
+def test_force():
+ def ll_function(n):
+ lst = []
+ lst.append(n)
+ if n:
+ lst.append(12)
+ return lst[-1]
+ insns, res = timeshift(ll_function, [6], [], policy=P_OOPSPEC)
+ assert res == 12
+ insns, res = timeshift(ll_function, [0], [], policy=P_OOPSPEC)
+ assert res == 0
Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jun 29 15:40:47 2006
@@ -12,6 +12,8 @@
self.LISTPTR = lltype.Ptr(LIST)
self.gv_type = rgenop.constTYPE(self.LIST)
self.gv_ptrtype = rgenop.constTYPE(self.LISTPTR)
+ self.build_newlist = LIST.list_builder.build_newlist
+ self.build_setitem = LIST.list_builder.build_setitem
def _freeze_(self):
return True
@@ -73,7 +75,16 @@
box.enter_block(newblock, incoming, memo)
def force_runtime_container(self, jitstate):
- assert 0
+ typedesc = self.typedesc
+ boxes = self.item_boxes
+ self.item_boxes = None
+ llops = rgenop.LowLevelOpBuilder(jitstate.curblock)
+ gv_list = typedesc.build_newlist(llops, len(boxes))
+ self.ownbox.genvar = gv_list
+ self.ownbox.content = None
+ for i in range(len(boxes)):
+ gv_item = boxes[i].getgenvar(jitstate)
+ typedesc.build_setitem(llops, gv_list, i, gv_item)
def freeze(self, memo):
contmemo = memo.containers
@@ -105,18 +116,21 @@
self.ownbox = self.ownbox.replace(memo)
-def oop_newlist(jitstate, typedesc, lengthbox):
+def oop_newlist(jitstate, oopspecdesc, lengthbox):
assert lengthbox.is_constant()
length = rvalue.ll_getvalue(lengthbox, lltype.Signed)
assert length == 0
- return typedesc.ll_factory()
+ return oopspecdesc.typedesc.ll_factory()
-def oop_list_append(jitstate, selfbox, itembox):
- assert isinstance(selfbox.content, VirtualList)
- selfbox.content.item_boxes.append(itembox)
-
-def oop_list_getitem(jitstate, selfbox, indexbox):
- assert isinstance(selfbox.content, VirtualList)
- assert indexbox.is_constant()
- index = rvalue.ll_getvalue(indexbox, lltype.Signed)
- return selfbox.content.item_boxes[index]
+def oop_list_append(jitstate, oopspecdesc, selfbox, itembox):
+ if isinstance(selfbox.content, VirtualList):
+ selfbox.content.item_boxes.append(itembox)
+ else:
+ oopspecdesc.residual_call(jitstate, [selfbox, itembox])
+
+def oop_list_getitem(jitstate, oopspecdesc, selfbox, indexbox):
+ if isinstance(selfbox.content, VirtualList) and indexbox.is_constant():
+ index = rvalue.ll_getvalue(indexbox, lltype.Signed)
+ return selfbox.content.item_boxes[index]
+ else:
+ return oopspecdesc.residual_call(jitstate, [selfbox, indexbox])
Modified: pypy/dist/pypy/rpython/lltypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rlist.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rlist.py Thu Jun 29 15:40:47 2006
@@ -106,32 +106,41 @@
self.LISTPTR = LISTPTR
argtypes = [Signed]
- fnptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist, argtypes)
- self.newlist_ptr = fnptr
+ newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist,
+ argtypes)
bk = list_repr.rtyper.annotator.bookkeeper
argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
- fnptr = list_repr.rtyper.annotate_helper_fn(ll_setitem_nonneg, argtypes)
- self.setitem_nonneg_ptr = fnptr
+ setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn(
+ ll_setitem_nonneg, argtypes)
#self.c_dum_nocheck = inputconst(Void, dum_nocheck)
#self.c_LIST = inputconst(Void, self.LIST)
- def build(self, llops, items_v):
- """Make the operations that would build a list containing the
- provided items."""
- c_newlist = llops.genconst(self.newlist_ptr)
- c_len = llops.genconst(len(items_v))
- c_LIST = llops.genvoidconst(self.LIST)
- v_result = llops.genop('direct_call',
+ def build_newlist(llops, length):
+ c_newlist = llops.genconst(newlist_ptr)
+ c_len = llops.genconst(length)
+ c_LIST = llops.genvoidconst(LIST)
+ return llops.genop('direct_call',
[c_newlist, c_LIST, c_len],
- self.LISTPTR)
- c_setitem_nonneg = llops.genconst(self.setitem_nonneg_ptr)
- for i in range(len(items_v)):
- c_i = llops.genconst(i)
+ LISTPTR)
+
+ def build_setitem(llops, v_list, index, v_item):
+ c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr)
+ c_i = llops.genconst(index)
llops.genop('direct_call', [c_setitem_nonneg,
llops.genvoidconst(dum_nocheck),
- v_result, c_i, items_v[i]])
- return v_result
+ v_list, c_i, v_item])
+
+ self.build_newlist = build_newlist
+ self.build_setitem = build_setitem
+
+ def build(self, llops, items_v):
+ """Make the operations that would build a list containing the
+ provided items."""
+ v_list = self.build_newlist(llops, len(items_v))
+ for i, v in enumerate(items_v):
+ self.build_setitem(llops, v_list, i, v)
+ return v_list
def getlistptr(self):
list_repr = self.tmp_list_repr
Modified: pypy/dist/pypy/rpython/rgenop.py
==============================================================================
--- pypy/dist/pypy/rpython/rgenop.py (original)
+++ pypy/dist/pypy/rpython/rgenop.py Thu Jun 29 15:40:47 2006
@@ -311,3 +311,18 @@
setannotation(constFieldName, s_ConstOrVar, specialize_as_constant=True)
setannotation(constTYPE, s_ConstOrVar, specialize_as_constant=True)
setannotation(placeholder, s_ConstOrVar, specialize_as_constant=True)
+
+# ____________________________________________________________
+
+class LowLevelOpBuilder(object):
+
+ def __init__(self, block):
+ self.block = block
+
+ genconst = staticmethod(genconst)
+ genvoidconst = staticmethod(placeholder)
+
+ def genop(self, opname, args_gv, RESULTTYPE=lltype.Void):
+ gv_result_type = constTYPE(RESULTTYPE)
+ return genop(self.block, opname, args_gv, gv_result_type)
+ genop._annspecialcase_ = 'specialize:arg(3)'
More information about the Pypy-commit
mailing list