[pypy-svn] r23427 - in pypy/dist/pypy/jit: . test
ac at codespeak.net
ac at codespeak.net
Thu Feb 16 21:05:01 CET 2006
Author: ac
Date: Thu Feb 16 21:05:00 2006
New Revision: 23427
Modified:
pypy/dist/pypy/jit/hinttimeshift.py
pypy/dist/pypy/jit/rtimeshift.py
pypy/dist/pypy/jit/test/test_hint_timeshift.py
Log:
(pedronis, arre)
- Initial work thowards supporting spliting on a red exitswitch.
Inserted special dispatch and return blocks. The latter collects all returning
links and their return value. The former closes the returnlinks into a final
block and merges their values to fill a final proper jitstate.
Modified: pypy/dist/pypy/jit/hinttimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/hinttimeshift.py (original)
+++ pypy/dist/pypy/jit/hinttimeshift.py Thu Feb 16 21:05:00 2006
@@ -2,7 +2,7 @@
from pypy.objspace.flow import model as flowmodel
from pypy.annotation import model as annmodel
from pypy.annotation import listdef, dictdef
-from pypy.jit.rtimeshift import STATE_PTR, REDBOX_PTR, VARLIST
+from pypy.jit.rtimeshift import STATE, STATE_PTR, REDBOX_PTR, VARLIST
from pypy.jit.rtimeshift import make_types_const
from pypy.rpython import rmodel, rtuple, rlist, rdict, rgenop
from pypy.jit import rtimeshift
@@ -18,6 +18,55 @@
self.rtyper = rtyper
self.hrtyper = HintRTyper(hannotator, self)
+
+ # XXX refactor this more nicely
+ s_return_info = annmodel.SomeTuple([annmodel.SomePtr(rgenop.LINK),
+ annmodel.SomePtr(REDBOX_PTR)])
+
+ returrn_queue_def = listdef.ListDef(None,
+ s_return_info)
+ returrn_queue_def.resize()
+ returrn_queue_def.mutate()
+
+ s_return_queue = annmodel.SomeList(returrn_queue_def)
+
+ r_return_queue = rtyper.getrepr(s_return_queue)
+ r_return_queue.setup()
+ RETURN_QUEUE = r_return_queue.lowleveltype
+
+ def ll_get_return_queue(questate):
+ pass
+ def _ll_get_return_queue(questate):
+ return questate.return_queue
+
+ llgetq = ll_get_return_queue
+
+ def ll_get_return_queue_annotation(queustate_s):
+ return s_return_queue
+
+ llgetq.compute_result_annotation = ll_get_return_queue_annotation
+
+ def ll_get_return_queue_specialize(hop):
+ return hop.gendirectcall(_ll_get_return_queue, hop.args_v[0])
+
+ llgetq.specialize = ll_get_return_queue_specialize
+
+ def ll_newstate():
+ questate = lltype.malloc(QUESTATE)
+ questate.return_queue = RETURN_QUEUE.TO.ll_newlist(0)
+ return questate
+
+ QUESTATE = lltype.GcStruct("quejistate",
+ ('basestate', STATE),
+ ("return_queue", RETURN_QUEUE),
+ adtmeths = {
+ 'll_get_return_queue': ll_get_return_queue,
+ 'll_newstate': ll_newstate,
+ 'll_basestate': lambda questate: questate.basestate})
+
+ self.s_return_queue = s_return_queue # for the test
+ self.QUESTATE_PTR = lltype.Ptr(QUESTATE)
+
def timeshift(self):
for graph in self.hannotator.translator.graphs:
self.timeshift_graph(graph)
@@ -31,7 +80,11 @@
originalblocks = list(graph.iterblocks())
returnblock = graph.returnblock
# we need to get the jitstate to the before block of the return block
- before_returnblock = self.insert_before_block(returnblock, entering_links[returnblock])
+ self.dispatchblock = flowmodel.Block([])
+ self.pre_process_block(self.dispatchblock)
+ before_returnblock = self.insert_before_block(returnblock,
+ entering_links[returnblock],
+ closeblock=False)
self.pre_process_block(before_returnblock)
for block in originalblocks:
self.pre_process_block(block)
@@ -49,8 +102,12 @@
self.hrtyper.setup_block_entry(before_returnblock)
self.hrtyper.insert_link_conversions(before_returnblock)
# add booking logic
- self.insert_bookkeeping_enter(returnblock, before_returnblock,
- len(entering_links[returnblock]))
+ self.insert_return_bookkeeping(before_returnblock)
+
+ # fix its concretetypes
+ self.hrtyper.setup_block_entry(self.dispatchblock)
+ self.insert_dispatch_logic(returnblock)
+
def pre_process_block(self, block):
# pass 'jitstate' as an extra argument around the whole graph
@@ -61,14 +118,13 @@
for link in block.exits:
if link.target.operations != ():
link.args.insert(0, v_jitstate)
- elif len(link.args) == 1: # pass the jitstate instead of the return value
- # to the return block!
+ elif len(link.args) == 1:
link.args[0] = v_jitstate
- v_returnjitstate = flowmodel.Variable('jitstate')
+ v_returnjitstate = flowmodel.Variable('jitstate')
self.hannotator.bindings[v_returnjitstate] = s_JITState
link.target.inputargs = [v_returnjitstate]
- def insert_before_block(self, block, entering_links):
+ def insert_before_block(self, block, entering_links, closeblock=True):
newinputargs = []
for var in block.inputargs:
newvar = flowmodel.Variable(var)
@@ -83,9 +139,10 @@
else:
for link in entering_links:
link.settarget(newblock)
-
- bridge = flowmodel.Link(newinputargs, block)
- newblock.closeblock(bridge)
+
+ if closeblock:
+ bridge = flowmodel.Link(newinputargs, block)
+ newblock.closeblock(bridge)
return newblock
def insert_bookkeeping_enter(self, block, before_block, nentrylinks):
@@ -285,6 +342,66 @@
newblock.operations[:] = llops
+ def insert_return_bookkeeping(self, before_returnblock):
+ v_jitstate, v_value = before_returnblock.inputargs
+ r_value = self.hrtyper.bindingrepr(v_value)
+ llops = HintLowLevelOpList(self, None)
+ if isinstance(r_value, GreenRepr):
+ v_value = llops.gendirectcall(rtimeshift.REDBOX.ll_make_from_const,
+ v_value)
+
+ v_quejitstate = llops.genop('cast_pointer', [v_jitstate],
+ resulttype=self.QUESTATE_PTR)
+
+ llops.genmixlevelhelpercall(rtimeshift.schedule_return,
+ [annmodel.SomePtr(self.QUESTATE_PTR),
+ annmodel.SomePtr(REDBOX_PTR)],
+ [v_quejitstate, v_value])
+
+ before_returnblock.operations[:] = llops
+ bridge = flowmodel.Link([v_jitstate], self.dispatchblock)
+ before_returnblock.closeblock(bridge)
+
+ def insert_dispatch_logic(self, returnblock):
+ dispatchblock = self.dispatchblock
+ [v_jitstate] = dispatchblock.inputargs
+ llops = HintLowLevelOpList(self, None)
+ s_box_list = annmodel.SomeList(listdef.ListDef(None,
+ annmodel.SomePtr(REDBOX_PTR)))
+ getrepr = self.rtyper.getrepr
+
+ r_box_list = getrepr(s_box_list)
+ r_box_list.setup()
+ v_boxes = rlist.newlist(llops, r_box_list, [])
+
+ v_quejitstate = llops.genop('cast_pointer', [v_jitstate],
+ resulttype=self.QUESTATE_PTR)
+
+ v_next = llops.genmixlevelhelpercall(rtimeshift.dispatch_next,
+ [annmodel.SomePtr(self.QUESTATE_PTR), s_box_list],
+ [v_quejitstate, v_boxes])
+
+ dispatchblock.operations[:] = llops
+
+ dispatch_to = []
+ finishedlink = flowmodel.Link([v_jitstate], returnblock)
+ dispatch_to.append(('default', finishedlink))
+
+ if len(dispatch_to) == 1:
+ dispatchblock.closeblock(finishedlink)
+ else:
+ dispatchblock.exitswitch = v_next
+ exitlinks = []
+ for case, link in dispatch_to:
+ link.exitcase = link.llexitcase = case
+ exitlinks.append(link)
+ dispatchblock.closeblock(*exitlinks)
+
+ v_returnjitstate = flowmodel.Variable('jitstate')
+ returnblock.inputargs = [v_returnjitstate]
+ v_returnjitstate.concretetype = STATE_PTR
+
+
def timeshift_block(self, block):
self.hrtyper.specialize_block(block)
Modified: pypy/dist/pypy/jit/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/rtimeshift.py Thu Feb 16 21:05:00 2006
@@ -56,7 +56,6 @@
('basebox', REDBOX),
("value", lltype.Signed))
REDBOX_FOR_SIGNED_PTR = lltype.Ptr(REDBOX_FOR_SIGNED)
-
STATE = lltype.GcStruct("jitstate", ("curblock", rgenop.BLOCK),
("curoutgoinglink", rgenop.LINK),
("curvalue", REDBOX_PTR))
@@ -227,8 +226,47 @@
jitstate.curoutgoinglink = rgenop.closeblock1(jitstate.curblock)
return jitstate
-def ll_setup_jitstate():
- jitstate = lltype.malloc(STATE)
+def schedule_return(jitstate, redbox):
+ return_queue = jitstate.ll_get_return_queue()
+ curoutgoinglink = jitstate.ll_basestate().curoutgoinglink
+ return_queue.append((curoutgoinglink, redbox))
+
+novars = lltype.malloc(VARLIST.TO, 0)
+
+def dispatch_next(jitstate, outredboxes):
+ return_queue = jitstate.ll_get_return_queue()
+ basestate = jitstate.ll_basestate()
+ first_redbox = return_queue[0][1]
+ finalblock = rgenop.newblock()
+ basestate.curblock = finalblock
+ if not first_redbox.isvar:
+ for link, redbox in return_queue:
+ if (redbox.isvar or
+ redbox.ll_getvalue(lltype.Signed) !=
+ first_redbox.ll_getvalue(lltype.Signed)):
+ break
+ else:
+ for link, _ in return_queue:
+ rgenop.closelink(link, novars, finalblock)
+ finallink = rgenop.closeblock1(finalblock)
+ basestate.curoutgoinglink = finallink
+ basestate.curvalue = first_redbox
+ return -1
+
+ finalvar = rgenop.geninputarg(finalblock,
+ rgenop.constTYPE(lltype.Signed))
+ for link, redbox in return_queue:
+ gvar = ll_gvar_from_redbox(jitstate, redbox, lltype.Signed)
+ rgenop.closelink(link, [gvar], finalblock)
+ finallink = rgenop.closeblock1(finalblock)
+ basestate.curoutgoinglink = finallink
+ basestate.curvalue = REDBOX.ll_make_for_gvar(finalvar)
+ return -1
+
+
+def ll_setup_jitstate(EXT_STATE_PTR):
+ jitstate = EXT_STATE_PTR.TO.ll_newstate()
+ jitstate = lltype.cast_pointer(STATE_PTR, jitstate)
jitstate.curblock = rgenop.newblock()
return jitstate
@@ -236,8 +274,7 @@
jitstate.curoutgoinglink = rgenop.closeblock1(jitstate.curblock)
def ll_close_jitstate(final_jitstate, return_gvar):
- link = rgenop.closeblock1(final_jitstate.curblock)
- rgenop.closereturnlink(link, return_gvar)
+ rgenop.closereturnlink(final_jitstate.curoutgoinglink, return_gvar)
def ll_input_redbox(jitstate, TYPE):
genvar = rgenop.geninputarg(jitstate.curblock,
Modified: pypy/dist/pypy/jit/test/test_hint_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_timeshift.py (original)
+++ pypy/dist/pypy/jit/test/test_hint_timeshift.py Thu Feb 16 21:05:00 2006
@@ -46,7 +46,7 @@
t.view()
# run the time-shifted graph-producing graphs
graph1 = ha.translator.graphs[0]
- jitstate = rtimeshift.ll_setup_jitstate()
+ jitstate = rtimeshift.ll_setup_jitstate(htshift.QUESTATE_PTR)
graph1args = [jitstate]
residual_graph_args = []
assert len(graph1.getargs()) == 1 + len(values)
@@ -80,6 +80,35 @@
viewbefore = conftest.option.view)
return insns, res
+def test_ll_get_return_queue():
+ t = TranslationContext()
+ a = t.buildannotator()
+ rtyper = t.buildrtyper()
+ rtyper.specialize() # XXX
+
+ htshift = HintTimeshift(None, rtyper)
+
+ questate = htshift.QUESTATE_PTR.TO.ll_newstate()
+
+ def llf(questate):
+ return questate.ll_get_return_queue()
+
+ from pypy.rpython import annlowlevel
+
+ graph = annlowlevel.annotate_mixlevel_helper(rtyper, llf, [
+ annmodel.SomePtr(htshift.QUESTATE_PTR)])
+
+ s = a.binding(graph.getreturnvar())
+
+ assert s == htshift.s_return_queue
+
+ rtyper.specialize_more_blocks()
+
+ llinterp = LLInterpreter(rtyper)
+ rq = llinterp.eval_graph(graph, [questate])
+ assert lltype.typeOf(rq) == rtyper.getrepr(s).lowleveltype
+
+
def test_simple_fixed():
def ll_function(x, y):
return hint(x + y, concrete=True)
@@ -131,3 +160,15 @@
insns, res = timeshift(ll_function, [7, 2], [0, 1])
assert res == 14
assert insns == {}
+
+def test_loop_merging():
+ py.test.skip('Work in progress')
+ def ll_function(x, y):
+ tot = 0
+ while x:
+ tot += y
+ x -= 1
+ return tot
+ insns, res = timeshift(ll_function, [7, 2], [])
+ assert res == 14
+ # assert insns == {}
More information about the Pypy-commit
mailing list