[pypy-svn] r37006 - in pypy/dist/pypy/jit: codegen/llgraph timeshifter timeshifter/test
pedronis at codespeak.net
pedronis at codespeak.net
Fri Jan 19 16:38:35 CET 2007
Author: pedronis
Date: Fri Jan 19 16:38:09 2007
New Revision: 37006
Modified:
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
pypy/dist/pypy/jit/timeshifter/transform.py
Log:
(arre, pedronis) progress on virtualizable: first test with outside-the-jit code forcing a virtual struct and checking that returning in the jit code
takes that into account generating code that matches the forced state of the structure.
quite a bit of xxx for now and cleanups needed.
We need to start thinking about the problems from the PyPy and rtyping side of things, to know which issues need a solution and which can wait longer.
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Fri Jan 19 16:38:09 2007
@@ -123,11 +123,16 @@
TYPE = from_opaque_object(gv_TYPE).value
v = from_opaque_object(gv_var)
if TYPE != v.concretetype:
- assert v.concretetype == lltype.erasedType(TYPE)
+ if TYPE is llmemory.GCREF or v.concretetype is llmemory.GCREF:
+ lltype.cast_opaque_ptr(TYPE, v.concretetype._defl()) # sanity check
+ opname = 'cast_opaque_ptr'
+ else:
+ assert v.concretetype == lltype.erasedType(TYPE)
+ opname = 'cast_pointer'
block = from_opaque_object(block)
v2 = flowmodel.Variable()
v2.concretetype = TYPE
- op = flowmodel.SpaceOperation('cast_pointer', [v], v2)
+ op = flowmodel.SpaceOperation(opname, [v], v2)
block.operations.append(op)
v = v2
return to_opaque_object(v)
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Fri Jan 19 16:38:09 2007
@@ -156,15 +156,17 @@
self.v_queue = varoftype(self.r_Queue.lowleveltype, 'queue')
#self.void_red_repr = VoidRedRepr(self)
+ # XXX use helpers, factor out perhaps?
annhelper = self.annhelper
- def make_vinfo():
- vinfo = rcontainer.VirtualInfo(RGenOp)
+ def make_vinfo(bitmask):
+ vinfo = rcontainer.VirtualInfo(RGenOp, bitmask)
return cast_instance_to_base_ptr(vinfo)
s_vableinfoptr = annmodel.lltype_to_annotation(rcontainer.VABLEINFOPTR)
- s_info = annmodel.lltype_to_annotation(llmemory.GCREF)
+ s_gcref = annmodel.lltype_to_annotation(llmemory.GCREF)
+ s_info = s_gcref
- make_vinfo_ptr = annhelper.delayedfunction(make_vinfo, [],
+ make_vinfo_ptr = annhelper.delayedfunction(make_vinfo, [annmodel.SomeInteger()],
s_vableinfoptr,
needtype=True)
self.gv_make_vinfo_ptr = RGenOp.constPrebuiltGlobal(make_vinfo_ptr)
@@ -215,9 +217,51 @@
vinfo_skip_vinfo_ptr)
self.vinfo_skip_vinfo_token = RGenOp.sigToken(
lltype.typeOf(vinfo_skip_vinfo_ptr).TO)
-
+
+ def vinfo_get_shape(vinfo):
+ vinfo = cast_base_ptr_to_instance(rcontainer.VirtualInfo,
+ vinfo)
+ return vinfo.get_shape()
+ vinfo_get_shape_ptr = annhelper.delayedfunction(vinfo_get_shape,
+ [s_vableinfoptr],
+ annmodel.SomeInteger(),
+ needtype=True)
+ self.gv_vinfo_get_shape_ptr = RGenOp.constPrebuiltGlobal(
+ vinfo_get_shape_ptr)
+ self.vinfo_get_shape_token = RGenOp.sigToken(
+ lltype.typeOf(vinfo_get_shape_ptr).TO)
+ def vinfo_get_vinfo(vinfo, index):
+ vinfo = cast_base_ptr_to_instance(rcontainer.VirtualInfo,
+ vinfo)
+ childvinfo = vinfo.vinfos[index]
+ return cast_instance_to_base_ptr(childvinfo)
+
+ vinfo_get_vinfo_ptr = annhelper.delayedfunction(vinfo_get_vinfo,
+ [s_vableinfoptr, annmodel.SomeInteger()],
+ s_vableinfoptr,
+ needtype=True)
+ self.gv_vinfo_get_vinfo_ptr = RGenOp.constPrebuiltGlobal(
+ vinfo_get_vinfo_ptr)
+ self.vinfo_get_vinfo_token = RGenOp.sigToken(
+ lltype.typeOf(vinfo_get_vinfo_ptr).TO)
+
+ def vinfo_read_forced(vinfo):
+ vinfo = cast_base_ptr_to_instance(rcontainer.VirtualInfo,
+ vinfo)
+ return vinfo.read_forced()
+
+ vinfo_read_forced_ptr = annhelper.delayedfunction(vinfo_read_forced,
+ [s_vableinfoptr],
+ s_gcref,
+ needtype=True)
+ self.gv_vinfo_read_forced_ptr = RGenOp.constPrebuiltGlobal(
+ vinfo_read_forced_ptr)
+ self.vinfo_read_forced_token = RGenOp.sigToken(
+ lltype.typeOf(vinfo_read_forced_ptr).TO)
+
+
def specialize(self, origportalgraph=None, view=False):
"""
Driver for running the timeshifter.
@@ -1397,6 +1441,28 @@
def translate_op_residual_gray_call(self, hop):
self.translate_op_residual_red_call(hop, color='gray')
+ def translate_op_prepare_residual_call(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(rtimeshift.prepare_residual_call,
+ [self.s_JITState],
+ [v_jitstate],
+ annmodel.s_None)
+
+ def translate_op_after_residual_call(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(rtimeshift.after_residual_call,
+ [self.s_JITState],
+ [v_jitstate],
+ self.s_RedBox)
+
+ def translate_op_reshape(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ v_shape, = hop.inputargs(self.getredrepr(lltype.Signed))
+ return hop.llops.genmixlevelhelpercall(rtimeshift.reshape,
+ [self.s_JITState, self.s_RedBox],
+ [v_jitstate , v_shape ],
+ annmodel.s_None)
+
def translate_op_reverse_split_queue(self, hop):
hop.llops.genmixlevelhelpercall(rtimeshift.reverse_split_queue,
[self.s_Queue],
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Fri Jan 19 16:38:09 2007
@@ -156,6 +156,7 @@
self.materialize = materialize
+ # xxx
self.gv_make_vinfo_ptr = hrtyper.gv_make_vinfo_ptr
self.make_vinfo_token = hrtyper.make_vinfo_token
@@ -165,6 +166,15 @@
self.vinfo_append_vinfo_token = hrtyper.vinfo_append_vinfo_token
self.gv_vinfo_skip_vinfo_ptr = hrtyper.gv_vinfo_skip_vinfo_ptr
self.vinfo_skip_vinfo_token = hrtyper.vinfo_skip_vinfo_token
+
+ self.gv_vinfo_get_vinfo_ptr = hrtyper.gv_vinfo_get_vinfo_ptr
+ self.vinfo_get_vinfo_token = hrtyper.vinfo_get_vinfo_token
+
+ self.gv_vinfo_get_shape_ptr = hrtyper.gv_vinfo_get_shape_ptr
+ self.vinfo_get_shape_token = hrtyper.vinfo_get_shape_token
+
+ self.gv_vinfo_read_forced_ptr = hrtyper.gv_vinfo_read_forced_ptr
+ self.vinfo_read_forced_token = hrtyper.vinfo_read_forced_token
def getfielddesc(self, name):
return self.fielddesc_by_name[name]
@@ -434,9 +444,11 @@
typedesc = self.typedesc
assert typedesc is not None
builder = jitstate.curbuilder
+ gv_bitmask = builder.rgenop.genconst(1<<memo.bitcount)
+ memo.bitcount += 1
gv_vinfo = builder.genop_call(typedesc.make_vinfo_token,
typedesc.gv_make_vinfo_ptr,
- [])
+ [gv_bitmask])
memo.containers[self] = gv_vinfo
vars_gv = []
for box in self.content_boxes:
@@ -463,12 +475,45 @@
[gv_vinfo, gv_info])
return gv_vinfo
+
+ def reshape(self, jitstate, gv_vinfo, shapemask, memo):
+ if self in memo.containers:
+ return
+ typedesc = self.typedesc
+ assert typedesc is not None
+ builder = jitstate.curbuilder
+ memo.containers[self] = None
+ bitmask = 1<<memo.bitcount
+ memo.bitcount += 1
+ boxes = self.content_boxes
+ if bitmask&shapemask:
+ gv_ptr = builder.genop_call(typedesc.vinfo_read_forced_token,
+ typedesc.gv_vinfo_read_forced_ptr,
+ [gv_vinfo])
+ self.content_boxes = None
+ self.ownbox.genvar = gv_ptr
+ self.ownbox.content = None
+
+ for i in range(len(boxes)): # xxx duplication
+ box = boxes[i]
+ if not box.genvar:
+ gv_vinfo1 = builder.genop_call(typedesc.vinfo_get_vinfo_token,
+ typedesc.gv_vinfo_get_vinfo_ptr,
+ [gv_vinfo, builder.rgenop.genconst(i)])
+ assert isinstance(box, rvalue.PtrRedBox)
+ content = box.content
+ assert isinstance(content, VirtualStruct) # xxx for now
+ content.reshape(jitstate, gv_vinfo1, shapemask, memo)
+
+
+
class VirtualInfo(object):
- def __init__(self, RGenOp):
+ def __init__(self, RGenOp, bitmask):
self.RGenOp = RGenOp
self.vinfos = []
self.s = lltype.nullptr(llmemory.GCREF.TO)
+ self.bitmask = bitmask
def read_field(self, fielddesc, base, index):
T = fielddesc.RESTYPE
@@ -491,7 +536,16 @@
fielddesc.fill_into(s, base, self)
return s
get_forced._annspecialcase_ = "specialize:arg(1)"
-
+
+ def read_forced(self):
+ assert self.s
+ return self.s
+
+ def get_shape(self):
+ if self.s:
+ return self.bitmask
+ else:
+ return 0
class VirtualizableStruct(VirtualStruct):
@@ -543,9 +597,10 @@
boxes = self.content_boxes
vars_gv = []
n = len(boxes)
+ gv_zeromask = builder.rgenop.genconst(0)
gv_vinfo = builder.genop_call(typedesc.make_vinfo_token,
typedesc.gv_make_vinfo_ptr,
- [])
+ [gv_zeromask])
memo.containers[self] = gv_vinfo
for i in range(NVABLEFIELDS, n-1):
@@ -589,12 +644,38 @@
info_token = typedesc.info_desc.fieldtoken
access_token = typedesc.access_desc.fieldtoken
gv_base_null = typedesc.base_desc.gv_default
- gv_info_null = typedesc.info_desc.gv_default
gv_access_null = typedesc.access_desc.gv_default
builder.genop_setfield(base_token, gv_outside, gv_base_null)
- builder.genop_setfield(info_token, gv_outside, gv_info_null)
builder.genop_setfield(access_token, gv_outside, gv_access_null)
-
+
+ def reshape(self, jitstate, gv_vinfo, shapemask, memo):
+ typedesc = self.typedesc
+ builder = jitstate.curbuilder
+ gv_outside = self.content_boxes[-1].genvar
+ if gv_outside is not typedesc.gv_null:
+ info_desc = typedesc.info_desc
+ assert info_desc is not None
+ if self in memo.containers:
+ return
+ # xxx we can avoid traversing the full tree
+ memo.containers[self] = None
+
+ assert gv_vinfo is None # xxx
+ info_token = info_desc.fieldtoken
+ gv_vinfo = builder.genop_getfield(info_token, gv_outside)
+ boxes = self.content_boxes
+ n = len(boxes)
+ for i in range(NVABLEFIELDS, n-1):
+ box = boxes[i]
+ if not box.genvar:
+ gv_vinfo1 = builder.genop_call(typedesc.vinfo_get_vinfo_token,
+ typedesc.gv_vinfo_get_vinfo_ptr,
+ [gv_vinfo, builder.rgenop.genconst(i-NVABLEFIELDS)])
+ assert isinstance(box, rvalue.PtrRedBox)
+ content = box.content
+ assert isinstance(content, VirtualStruct) # xxx for now
+ content.reshape(jitstate, gv_vinfo1, shapemask, memo)
+
# ____________________________________________________________
class FrozenPartialDataStruct(AbstractContainer):
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Fri Jan 19 16:38:09 2007
@@ -463,14 +463,22 @@
def ll_gen_residual_call(jitstate, calldesc, funcbox):
builder = jitstate.curbuilder
- jitstate.prepare_for_residual_call()
gv_funcbox = funcbox.getgenvar(jitstate)
argboxes = jitstate.frame.local_boxes
args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes]
gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv)
- jitstate.after_residual_call()
return calldesc.redboxbuilder(calldesc.result_kind, gv_result)
+def prepare_residual_call(jitstate):
+ jitstate.prepare_for_residual_call()
+
+def after_residual_call(jitstate):
+ return jitstate.after_residual_call()
+
+def reshape(jitstate, shapebox):
+ shapemask = rvalue.ll_getvalue(shapebox, lltype.Signed)
+ jitstate.reshape(shapemask)
+
class ResumingInfo(object):
def __init__(self, promotion_point, gv_value, path):
@@ -895,20 +903,47 @@
builder = self.curbuilder
gv_base = builder.get_frame_base()
memo = rvalue.make_vinfo_memo()
+ memo.bitcount = 0
for virtualizable_box in virtualizables:
content = virtualizable_box.content
assert isinstance(content, rcontainer.VirtualizableStruct)
content.prepare_for_residual_call(self, gv_base, memo)
+ assert memo.bitcount < 32
+ self.make_vinfo_memo = memo
def after_residual_call(self):
virtualizables = self.virtualizables
+ builder = self.curbuilder
+ gv_shape = builder.rgenop.genconst(0)
if virtualizables:
- builder = self.curbuilder
for virtualizable_box in virtualizables:
content = virtualizable_box.content
assert isinstance(content, rcontainer.VirtualizableStruct)
content.after_residual_call(self)
+ memo = self.make_vinfo_memo
+ self.make_vinfo_memo = None
+ for container, gv_vinfo in memo.containers.iteritems():
+ if isinstance(container, rcontainer.VirtualizableStruct):
+ continue
+ assert isinstance(container, rcontainer.VirtualStruct)
+ typedesc = container.typedesc # xxx
+ gv_new_shape = builder.genop_call(typedesc.vinfo_get_shape_token,
+ typedesc.gv_vinfo_get_shape_ptr,
+ [gv_vinfo])
+ gv_shape = builder.genop2('int_or', gv_shape, gv_new_shape)
+ return rvalue.IntRedBox(builder.rgenop.kindToken(lltype.Signed), gv_shape)
+ def reshape(self, shapemask):
+ virtualizables = self.virtualizables
+ builder = self.curbuilder
+ if virtualizables and shapemask:
+ memo = rvalue.make_vinfo_memo()
+ memo.bitcount = 0
+ for virtualizable_box in virtualizables:
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.reshape(self, None, shapemask, memo) # xxx gv_vinfo argument
+
def freeze(self, memo):
result = FrozenJITState()
result.fz_frame = self.frame.freeze(memo)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Fri Jan 19 16:38:09 2007
@@ -1126,7 +1126,29 @@
res = self.timeshift(f, [0, 2], [0], policy=P_NOVIRTUAL)
assert res == 42
- self.check_insns({'int_mul': 1})
+ self.check_insns({'int_mul': 1})
+
+ def test_simple_red_meth_vars_around(self):
+ class Base(object):
+ def m(self, n):
+ raise NotImplementedError
+ pass # for inspect.getsource() bugs
+
+ class Concrete(Base):
+ def m(self, n):
+ return 21*n
+ pass # for inspect.getsource() bugs
+
+ def f(flag, x, y, z):
+ if flag:
+ o = Base()
+ else:
+ o = Concrete()
+ return (o.m(x)+y)-z
+
+ res = self.timeshift(f, [0, 2, 7, 5], [0], policy=P_NOVIRTUAL)
+ assert res == 44
+ self.check_insns({'int_mul': 1, 'int_add': 1, 'int_sub': 1})
def test_compile_time_const_tuple(self):
d = {(4, 5): 42, (6, 7): 12}
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Fri Jan 19 16:38:09 2007
@@ -2,6 +2,7 @@
from pypy.jit.timeshifter.test.test_portal import PortalTest, P_NOVIRTUAL
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.timeshifter.rcontainer import VABLEINFOPTR
+from pypy.rlib.objectmodel import hint
import py
S = lltype.GcStruct('s', ('a', lltype.Signed), ('b', lltype.Signed))
@@ -502,6 +503,7 @@
e.w = y
def f(e):
+ hint(None, global_merge_point=True)
xy = e.xy
xy_access = xy.vable_access
if xy_access:
@@ -553,6 +555,7 @@
e.w = y
def f(e):
+ hint(None, global_merge_point=True)
xy = e.xy
xy_access = xy.vable_access
if xy_access:
@@ -610,6 +613,7 @@
e.w = p.a + p.b + x
def f(e, a, b):
+ hint(None, global_merge_point=True)
xp = e.xp
s = lltype.malloc(S)
s.a = a
@@ -674,6 +678,7 @@
e.w = int(p1 == p2)
def f(e, a, b):
+ hint(None, global_merge_point=True)
xp = e.xp
s = lltype.malloc(S)
s.a = a
@@ -747,6 +752,7 @@
e.w = int(p != q)
def f(e, a, b):
+ hint(None, global_merge_point=True)
pq = e.pq
s = lltype.malloc(S)
s.a = a
@@ -816,6 +822,7 @@
e.w = int(p == q)
def f(e, a, b):
+ hint(None, global_merge_point=True)
pq = e.pq
s = lltype.malloc(S)
s.a = a
@@ -858,3 +865,72 @@
res = self.timeshift_from_portal(main, f, [2, 20, 10],
policy=StopAtGPolicy())
assert res == 1
+
+ def test_explicit_force_in_residual_red_call_with_more_use(self):
+ def g(e):
+ xp = e.xp
+ xp_access = xp.vable_access
+ if xp_access:
+ p = xp_access.get_p(xp)
+ else:
+ p = xp.p
+ xp_access = xp.vable_access
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ e.w = p.a + p.b + x
+ p.b, p.a = p.a, p.b
+
+ def f(e, a, b):
+ hint(None, global_merge_point=True)
+ xp = e.xp
+ s = lltype.malloc(S)
+ s.a = a
+ s.b = b
+ xp_access = xp.vable_access
+ if xp_access:
+ xp_access.set_p(xp, s)
+ else:
+ xp.p = s
+ xp_access = xp.vable_access
+
+ xp_access = xp.vable_access
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ xp_access = xp.vable_access
+ newx = 2*x
+ if xp_access:
+ xp_access.set_x(xp, newx)
+ else:
+ xp.x = newx
+ g(e)
+ s.a = s.a*7
+ s.b = s.b*5
+ return xp.x
+
+ def main(a, b, x):
+ xp = lltype.malloc(XP)
+ xp.vable_access = lltype.nullptr(XP_ACCESS)
+ xp.x = x
+ xp.p = lltype.nullptr(S)
+ e = lltype.malloc(E2)
+ e.xp = xp
+ f(e, a, b)
+ return e.w + xp.p.a + xp.p.b
+
+
+ class StopAtGPolicy(HintAnnotatorPolicy):
+ def __init__(self):
+ HintAnnotatorPolicy.__init__(self, novirtualcontainer=True)
+
+ def look_inside_graph(self, graph):
+ if graph.name == 'g':
+ return False
+ return True
+
+ res = self.timeshift_from_portal(main, f, [2, 20, 10],
+ policy=StopAtGPolicy())
+ assert res == 42 + 140 + 10
Modified: pypy/dist/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py (original)
+++ pypy/dist/pypy/jit/timeshifter/transform.py Fri Jan 19 16:38:09 2007
@@ -151,12 +151,15 @@
# __________ helpers __________
- def genop(self, block, opname, args, resulttype=None, result_like=None):
+ def genop(self, block, opname, args, resulttype=None, result_like=None, red=False):
# 'result_like' can be a template variable whose hintannotation is
# copied
if resulttype is not None:
v_res = varoftype(resulttype)
- hs = hintmodel.SomeLLAbstractConstant(resulttype, {})
+ if red:
+ hs = hintmodel.SomeLLAbstractVariable(resulttype)
+ else:
+ hs = hintmodel.SomeLLAbstractConstant(resulttype, {})
self.hannotator.setbinding(v_res, hs)
elif result_like is not None:
v_res = copyvar(self.hannotator, result_like)
@@ -615,19 +618,15 @@
postconstantblock.recloseblock(Link([], resumeblock))
if nonconstantblock is not None:
- args_v = op.args[1:]
- if op.opname == 'indirect_call':
- del args_v[-1]
- # pseudo-obscure: the arguments for the call go in save_locals
- args_v = [v for v in args_v if v.concretetype is not lltype.Void]
- self.genop(nonconstantblock, 'save_locals', args_v)
- v_res = self.genop(nonconstantblock, 'residual_%s_call' % (color,),
- [op.args[0]], result_like = op.result)
+ v_res, nonconstantblock2 = self.handle_residual_call_details(nonconstantblock, 0,
+ op, color,
+ preserve_res = False)
if color == 'red':
linkargs[0] = v_res
-
- nonconstantblock.closeblock(Link(linkargs, nextblock))
+
+ blockset[nonconstantblock2] = False
+ nonconstantblock2.recloseblock(Link(linkargs, nextblock))
blockset[block] = True # reachable from outside
blockset[nextblock] = True # reachable from outside
@@ -700,25 +699,49 @@
postblock: False}, self.hannotator)
def handle_residual_call(self, block, pos):
- op = block.operations[pos]
+ op = block.operations[pos]
+ if op.result.concretetype is lltype.Void:
+ color = 'gray'
+ else:
+ color = 'red'
+ v_res, _ = self.handle_residual_call_details(block, pos, op, color)
+ return v_res
+
+ def handle_residual_call_details(self, block, pos, op, color, preserve_res=True):
if op.opname == 'direct_call':
args_v = op.args[1:]
elif op.opname == 'indirect_call':
args_v = op.args[1:-1]
else:
raise AssertionError(op.opname)
- if op.result.concretetype is lltype.Void:
- color = 'gray'
- else:
- color = 'red'
newops = []
# pseudo-obscure: the arguments for the call go in save_locals
args_v = [v for v in args_v if v.concretetype is not lltype.Void]
self.genop(newops, 'save_locals', args_v)
- self.genop(newops, 'residual_%s_call' % (color,),
- [op.args[0]], result_like = op.result)
- newops[-1].result = op.result
+ self.genop(newops, 'prepare_residual_call', [])
+ call_index = len(newops)
+ v_res = self.genop(newops, 'residual_%s_call' % (color,),
+ [op.args[0]], result_like = op.result)
+ v_shape = self.genop(newops, 'after_residual_call', [], resulttype=lltype.Signed, red=True)
+ reshape_index = len(newops)
+ self.genop(newops, 'reshape', [v_shape])
+ reshape_pos = pos+reshape_index
block.operations[pos:pos+1] = newops
+ if preserve_res:
+ v_res = newops[call_index].result = op.result
+
+ link = split_block(self.hannotator, block, reshape_pos)
+ nextblock = link.target
+
+ reds, greens = self.sort_by_color(link.args)
+ self.genop(block, 'save_locals', reds)
+ v_finished_flag = self.genop(block, 'promote', [v_shape],
+ resulttype = lltype.Bool)
+ self.go_to_dispatcher_if(block, v_finished_flag)
+
+
+ return v_res, nextblock
+
# __________ hints __________
@@ -764,7 +787,6 @@
block.operations[i] = newop
link = split_block(self.hannotator, block, i)
- nextblock = link.target
reds, greens = self.sort_by_color(link.args)
self.genop(block, 'save_locals', reds)
More information about the Pypy-commit
mailing list