[pypy-svn] r32543 - in pypy/branch/timeshift-refactoring/pypy/jit/timeshifter: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 20 20:18:40 CEST 2006
Author: arigo
Date: Wed Sep 20 20:18:39 2006
New Revision: 32543
Modified:
pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py
pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/test/test_timeshift.py
pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py
Log:
(arre, arigo)
Yellow calls! The first real progress of the week, but it was worth the
effort.
Turned the dispatch_queue's lists of jitstates into chains (linked lists)
to make it easier to give a type to "list of jitstates": it's the same as
"jitstate". (It's also more efficient, and less readable.)
Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtimeshift.py Wed Sep 20 20:18:39 2006
@@ -234,10 +234,26 @@
later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
jitstate.split(later_builder, resumepoint, list(greens_gv))
+def collect_split(jitstate_chain, resumepoint, *greens_gv):
+ greens_gv = list(greens_gv)
+ pending = jitstate_chain
+ while True:
+ jitstate = pending
+ pending = pending.next
+ jitstate.greens.extend(greens_gv) # item 0 is the return value
+ jitstate.resumepoint = resumepoint
+ if pending is None:
+ break
+ dispatch_queue = jitstate_chain.frame.dispatch_queue
+ jitstate.next = dispatch_queue.split_chain
+ dispatch_queue.split_chain = jitstate_chain.next
+ # XXX obscurity++ above
+
def dispatch_next(oldjitstate):
- split_queue = oldjitstate.frame.dispatch_queue.split_queue
- if split_queue:
- jitstate = split_queue.pop()
+ dispatch_queue = oldjitstate.frame.dispatch_queue
+ if dispatch_queue.split_chain is not None:
+ jitstate = dispatch_queue.split_chain
+ dispatch_queue.split_chain = jitstate.next
enter_block(jitstate)
return jitstate
else:
@@ -252,6 +268,9 @@
assert None not in redboxes
jitstate.frame.local_boxes = redboxes
+def save_greens(jitstate, *greens_gv):
+ jitstate.greens = list(greens_gv)
+
def getlocalbox(jitstate, i):
return jitstate.frame.local_boxes[i]
@@ -274,7 +293,10 @@
jitstate.exc_value_box = box
def save_return(jitstate):
- jitstate.frame.dispatch_queue.return_queue.append(jitstate)
+ # add 'jitstate' to the chain of return-jitstates
+ dispatch_queue = jitstate.frame.dispatch_queue
+ jitstate.next = dispatch_queue.return_chain
+ dispatch_queue.return_chain = jitstate
##def ll_gvar_from_redbox(jitstate, redbox):
## return redbox.getgenvar(jitstate.curbuilder)
@@ -286,8 +308,8 @@
class BaseDispatchQueue(object):
def __init__(self):
- self.split_queue = [] # XXX could be turned into a linked list
- self.return_queue = [] # XXX could be turned into a linked list
+ self.split_chain = None
+ self.return_chain = None
def build_dispatch_subclass(attrnames):
if len(attrnames) == 0:
@@ -387,6 +409,7 @@
class JITState(object):
returnbox = None
+ next = None # for linked lists
def __init__(self, builder, frame, exc_type_box, exc_value_box,
resumepoint=-1, newgreens=[]):
@@ -405,7 +428,10 @@
self.exc_value_box.copy(memo),
newresumepoint,
newgreens)
- self.frame.dispatch_queue.split_queue.append(later_jitstate)
+ # add the later_jitstate to the chain of pending-for-dispatch_next()
+ dispatch_queue = self.frame.dispatch_queue
+ later_jitstate.next = dispatch_queue.split_chain
+ dispatch_queue.split_chain = later_jitstate
def enter_block(self, incoming, memo):
self.frame.enter_block(incoming, memo)
@@ -431,17 +457,25 @@
# XXX is that too many specializations? ^^^
def merge_returning_jitstates(jitstate):
- return_queue = jitstate.frame.dispatch_queue.return_queue
+ return_chain = jitstate.frame.dispatch_queue.return_chain
return_cache = {}
- still_pending = []
- for jitstate in return_queue:
+ still_pending = None
+ while return_chain is not None:
+ jitstate = return_chain
+ return_chain = return_chain.next
res = retrieve_jitstate_for_merge(return_cache, jitstate, ())
if res is False: # not finished
- still_pending.append(jitstate)
- for jitstate in still_pending[:-1]:
+ jitstate.next = still_pending
+ still_pending = jitstate
+ assert still_pending is not None
+ most_general_jitstate = still_pending
+ still_pending = still_pending.next
+ while still_pending is not None:
+ jitstate = still_pending
+ still_pending = still_pending.next
res = retrieve_jitstate_for_merge(return_cache, jitstate, ())
assert res is True # finished
- return still_pending[-1]
+ return most_general_jitstate
def leave_graph_red(jitstate):
jitstate = merge_returning_jitstates(jitstate)
@@ -456,3 +490,11 @@
myframe = jitstate.frame
jitstate.frame = myframe.backframe
return jitstate
+
+def leave_graph_yellow(jitstate):
+ return_chain = jitstate.frame.dispatch_queue.return_chain
+ jitstate = return_chain
+ while jitstate is not None:
+ jitstate.frame = jitstate.frame.backframe
+ jitstate = jitstate.next
+ return return_chain # a jitstate, which is the head of the chain
Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/rtyper.py Wed Sep 20 20:18:39 2006
@@ -577,6 +577,14 @@
self.s_JITState)
hop.llops.setjitstate(v_newjs)
+ def translate_op_leave_graph_yellow(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ v_njs = hop.llops.genmixlevelhelpercall(rtimeshift.leave_graph_yellow,
+ [self.s_JITState],
+ [v_jitstate ],
+ self.s_JITState)
+ hop.llops.setjitstate(v_njs)
+
def translate_op_save_locals(self, hop):
v_jitstate = hop.llops.getjitstate()
boxes_r = [self.getredrepr(originalconcretetype(hs))
@@ -588,6 +596,15 @@
[v_jitstate ] + boxes_v,
annmodel.s_None)
+ def translate_op_save_greens(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ greens_v = list(self.wrap_green_vars(hop.llops, hop.args_v))
+ greens_s = [self.s_ConstOrVar] * len(greens_v)
+ return hop.llops.genmixlevelhelpercall(rtimeshift.save_greens,
+ [self.s_JITState] + greens_s,
+ [v_jitstate ] + greens_v,
+ annmodel.s_None)
+
def translate_op_enter_block(self, hop):
v_jitstate = hop.llops.getjitstate()
hop.llops.genmixlevelhelpercall(rtimeshift.enter_block,
@@ -677,6 +694,24 @@
hop.llops.genmixlevelhelpercall(rtimeshift.split, args_s, args_v,
annmodel.s_None)
+ def translate_op_collect_split(self, hop):
+ GREENS = [v.concretetype for v in hop.args_v[1:]]
+ greens_r = [self.getgreenrepr(TYPE) for TYPE in GREENS]
+ vlist = hop.inputargs(lltype.Signed, *greens_r)
+
+ v_jitstate = hop.llops.getjitstate()
+ c_resumepoint = vlist[0]
+ greens_v = list(self.wrap_green_vars(hop.llops, vlist[1:]))
+
+ s_Int = annmodel.SomeInteger(nonneg=True)
+ args_s = [self.s_JITState, s_Int]
+ args_s += [self.s_ConstOrVar] * len(greens_v)
+ args_v = [v_jitstate, c_resumepoint]
+ args_v += greens_v
+ hop.llops.genmixlevelhelpercall(rtimeshift.collect_split,
+ args_s, args_v,
+ annmodel.s_None)
+
def translate_op_merge_point(self, hop):
mpfamily = hop.args_v[0].value
attrname = hop.args_v[1].value
@@ -800,6 +835,8 @@
v_newjitstate = hop.genop('direct_call', args_v, RESULT)
hop.llops.setjitstate(v_newjitstate)
+ translate_op_yellow_call = translate_op_red_call
+
class HintLowLevelOpList(LowLevelOpList):
"""Warning: the HintLowLevelOpList's rtyper is the *original*
Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/test/test_timeshift.py Wed Sep 20 20:18:39 2006
@@ -900,7 +900,6 @@
self.check_insns({})
def test_split_on_green_return(self):
- py.test.skip("in-progress")
def ll_two(x):
if x > 0:
return 17
@@ -908,7 +907,7 @@
return 22
def ll_function(x):
n = ll_two(x)
- return n+1
+ return hint(n+1, variable=True)
res = self.timeshift(ll_function, [-70], [])
assert res == 23
self.check_insns({'int_gt': 1})
Modified: pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/timeshifter/transform.py Wed Sep 20 20:18:39 2006
@@ -8,6 +8,7 @@
from pypy.translator.unsimplify import varoftype, copyvar
from pypy.translator.unsimplify import split_block, split_block_at_start
from pypy.translator.backendopt.ssa import SSA_to_SSI
+from pypy.translator.backendopt import support
class MergePointFamily(object):
@@ -22,6 +23,7 @@
class HintGraphTransformer(object):
+ c_dummy = inputconst(lltype.Void, None)
def __init__(self, hannotator, graph):
self.hannotator = hannotator
@@ -128,7 +130,7 @@
split_block(self.hannotator, block, 0)
[link] = block.exits
assert len(link.args) == 0
- link.args = [inputconst(lltype.Void, None)]
+ link.args = [self.c_dummy]
link.target.inputargs = [self.new_void_var('dummy')]
self.graph.returnblock = link.target
self.graph.returnblock.operations = ()
@@ -183,9 +185,9 @@
constant_block : False,
nonconstant_block: False}, self.hannotator)
- def get_resume_point(self, block):
+ def get_resume_point_link(self, block):
try:
- reenter_link = self.resumepoints[block]
+ return self.resumepoints[block]
except KeyError:
resumeblock = Block([])
redcount = 0
@@ -209,7 +211,10 @@
N = len(self.resumepoints)
reenter_link.exitcase = N
self.resumepoints[block] = reenter_link
- return reenter_link.exitcase
+ return reenter_link
+
+ def get_resume_point(self, block):
+ return self.get_resume_point_link(block).exitcase
def insert_merge(self, block):
reds, greens = self.sort_by_color(block.inputargs)
@@ -223,7 +228,7 @@
result_type = lltype.Bool)
block.exitswitch = v_finished_flag
[link_f] = block.exits
- link_t = Link([inputconst(lltype.Void, None)], self.graph.returnblock)
+ link_t = Link([self.c_dummy], self.graph.returnblock)
link_f.exitcase = False
link_t.exitcase = True
block.recloseblock(link_f, link_t)
@@ -261,6 +266,9 @@
if originalconcretetype(hs_retbox) is lltype.Void:
self.leave_graph_opname = 'leave_graph_void'
self.genop(block, 'save_locals', [])
+ elif hs_retbox.is_green():
+ self.leave_graph_opname = 'leave_graph_yellow'
+ self.genop(block, 'save_greens', [v_retbox])
else:
self.leave_graph_opname = 'leave_graph_red'
self.genop(block, 'save_locals', [v_retbox])
@@ -359,3 +367,32 @@
op = block.operations[pos]
assert op.opname == 'direct_call'
op.opname = 'green_call'
+
+ def handle_yellow_call(self, block, pos):
+ link = support.split_block_with_keepalive(block, pos+1,
+ annotator=self.hannotator)
+ op = block.operations.pop(pos)
+ assert len(block.operations) == pos
+ nextblock = link.target
+ varsalive = link.args
+ try:
+ index = varsalive.index(op.result)
+ except ValueError:
+ XXX-later
+
+ del varsalive[index]
+ v_result = nextblock.inputargs.pop(index)
+ nextblock.inputargs.insert(0, v_result)
+
+ reds, greens = self.sort_by_color(varsalive)
+ self.genop(block, 'save_locals', reds)
+ self.genop(block, 'yellow_call', op.args) # Void result, like red_call
+
+ resumepoint = self.get_resume_point(nextblock)
+ c_resumepoint = inputconst(lltype.Signed, resumepoint)
+ self.genop(block, 'collect_split', [c_resumepoint] + greens)
+ link.args = []
+ link.target = self.get_resume_point_link(nextblock).target
+
+ self.insert_merge(nextblock) # to merge some of the possibly many
+ # return jitstates
More information about the Pypy-commit
mailing list