[pypy-svn] r31450 - in pypy/dist/pypy/jit/timeshifter: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Aug 21 19:50:30 CEST 2006
Author: arigo
Date: Mon Aug 21 19:50:27 2006
New Revision: 31450
Modified:
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/timeshift.py
Log:
(pedronis, arre, arigo)
More support for calls: saving local variables around calls.
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Mon Aug 21 19:50:27 2006
@@ -145,10 +145,13 @@
# ____________________________________________________________
# other jitstate/graph level operations
-def enter_graph(builder):
- return builder.build_jitstate()
+def enter_graph(builder, backstate=None):
+ return builder.build_jitstate(backstate)
def retrieve_jitstate_for_merge(states_dic, jitstate, key, redboxes):
+ mylocalredboxes = redboxes
+ redboxes = list(redboxes)
+ jitstate.extend_with_parent_locals(redboxes)
if key not in states_dic:
memo = rvalue.freeze_memo()
frozens = [redbox.freeze(memo) for redbox in redboxes]
@@ -196,8 +199,9 @@
box = box.copy(replace_memo) # copy to avoid patching the original
box.genvar = rgenop.geninputarg(newblock, box.gv_type)
if replace_memo.boxes:
- for i in range(len(redboxes)):
- redboxes[i] = redboxes[i].replace(replace_memo)
+ for i in range(len(mylocalredboxes)):
+ newbox = redboxes[i].replace(replace_memo)
+ mylocalredboxes[i] = redboxes[i] = newbox
jitstate.curbuilder.leave_block()
jitstate.curbuilder.enter_block(linkargs, newblock)
memo = rvalue.freeze_memo()
@@ -207,15 +211,25 @@
retrieve_jitstate_for_merge._annspecialcase_ = "specialize:arglltype(2)"
def enter_block(jitstate, redboxes):
+ # 'redboxes' is a fixed-size list (s_box_list) of the current red boxes
newblock = rgenop.newblock()
incoming = []
memo = rvalue.enter_block_memo()
- for i in range(len(redboxes)):
- redboxes[i].enter_block(newblock, incoming, memo)
+ for redbox in redboxes:
+ redbox.enter_block(newblock, incoming, memo)
+ js = jitstate.backstate
+ while js is not None:
+ lrb = js.localredboxes
+ assert lrb is not None
+ for redbox in lrb:
+ redbox.enter_block(newblock, incoming, memo)
+ js = js.backstate
jitstate.curbuilder.enter_block(incoming, newblock)
return jitstate
def dyn_enter_block(jitstate, redboxes):
+ # 'redboxes' is a var-sized list (s_box_accum) of *all* the boxes
+ # including the ones from the callers' locals
newblock = rgenop.newblock()
incoming = []
memo = rvalue.enter_block_memo()
@@ -273,6 +287,9 @@
def ll_gvar_from_constant(ll_value):
return rgenop.genconst(ll_value)
+def save_locals(jitstate, redboxes):
+ jitstate.localredboxes = redboxes
+
def before_call(jitstate):
leave_block(jitstate)
return jitstate.curbuilder
@@ -289,8 +306,8 @@
self.outgoinglink = link
self.valuebox = None
- def build_jitstate(self):
- return JITState(self)
+ def build_jitstate(self, backstate=None):
+ return JITState(self, backstate)
def enter_block(self, linkargs, newblock):
rgenop.closelink(self.outgoinglink, linkargs, newblock)
@@ -343,10 +360,18 @@
class JITState(object):
# XXX obscure interface
+ localredboxes = None
- def __init__(self, builder):
+ def __init__(self, builder, backstate=None):
self.split_queue = []
self.return_queue = []
self.curbuilder = builder
+ self.backstate = backstate
-
+ def extend_with_parent_locals(self, redboxes):
+ js = self.backstate
+ while js is not None:
+ lrb = js.localredboxes
+ assert lrb is not None
+ redboxes.extend(lrb)
+ js = js.backstate
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Mon Aug 21 19:50:27 2006
@@ -234,8 +234,7 @@
args_v = hop.inputargs(*args_r)
fnptr = self.getcallable(graph)
self.timeshifter.schedule_graph(graph)
- args_v.insert(0, v_builder)
- args_v.insert(0, hop.llops.genconst(fnptr))
+ args_v[:0] = [hop.llops.genconst(fnptr), v_builder, v_jitstate]
v_newbuilder = hop.genop('direct_call', args_v,
ts.r_ResidualGraphBuilder.lowleveltype)
return hop.llops.genmixlevelhelpercall(rtimeshift.after_call,
@@ -243,6 +242,19 @@
[v_jitstate, v_newbuilder],
ts.s_RedBox)
+ def translate_op_save_locals(self, hop):
+ ts = self.timeshifter
+ v_jitstate = hop.llops.getjitstate()
+ boxes_v = []
+ for r, v in zip(hop.args_r, hop.args_v):
+ if isinstance(r, RedRepr):
+ boxes_v.append(v)
+ v_boxes = ts.build_box_list(hop.llops, boxes_v)
+ hop.llops.genmixlevelhelpercall(rtimeshift.save_locals,
+ [ts.s_JITState, ts.s_box_list],
+ [v_jitstate, v_boxes],
+ annmodel.s_None)
+
def handle_highlevel_operation(self, fnobj, hop):
from pypy.jit.timeshifter.oop import OopSpecDesc, Index
oopspecdesc = OopSpecDesc(fnobj)
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 Mon Aug 21 19:50:27 2006
@@ -80,10 +80,10 @@
graph1 = ha.translator.graphs[0]
llinterp = LLInterpreter(rtyper)
builder = llinterp.eval_graph(htshift.ll_make_builder_graph, [])
- graph1args = [builder]
+ graph1args = [builder, lltype.nullptr(htshift.r_JITState.lowleveltype.TO)]
residual_graph_args = []
- assert len(graph1.getargs()) == 1 + len(values)
- for i, (v, llvalue) in enumerate(zip(graph1.getargs()[1:], values)):
+ assert len(graph1.getargs()) == 2 + len(values)
+ for i, (v, llvalue) in enumerate(zip(graph1.getargs()[2:], values)):
r = htshift.hrtyper.bindingrepr(v)
residual_v = r.residual_values(llvalue)
if len(residual_v) == 0:
@@ -569,3 +569,12 @@
insns, res = timeshift(ll_function, [5], [], policy=P_NOVIRTUAL)
assert res == 6
assert insns == {'int_add': 1}
+
+def test_call_2():
+ def ll_add_one(x):
+ return x + 1
+ def ll_function(y):
+ return ll_add_one(y) + y
+ insns, res = timeshift(ll_function, [5], [], policy=P_NOVIRTUAL)
+ assert res == 11
+ assert insns == {'int_add': 2}
Modified: pypy/dist/pypy/jit/timeshifter/timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/timeshift.py Mon Aug 21 19:50:27 2006
@@ -225,15 +225,16 @@
def insert_start_setup(self):
newstartblock = self.insert_before_block(self.graph.startblock, None, closeblock=True)
v_builder = varoftype(self.r_ResidualGraphBuilder.lowleveltype, 'builder')
+ v_backstate = varoftype(self.r_JITState.lowleveltype, 'backstate')
v_jitstate = newstartblock.inputargs[0]
- newstartblock.inputargs[0] = v_builder
+ newstartblock.inputargs[:1] = [v_builder, v_backstate]
llops = HintLowLevelOpList(self, None)
llops.genop('direct_call', [self.c_ll_clearcaches_ptr])
v_jitstate1 = llops.genmixlevelhelpercall(rtimeshift.enter_graph,
- [self.s_ResidualGraphBuilder],
- [v_builder],
- self.s_JITState)
+ [self.s_ResidualGraphBuilder, self.s_JITState],
+ [v_builder, v_backstate],
+ self.s_JITState)
llops.append(flowmodel.SpaceOperation('same_as', [v_jitstate1], v_jitstate))
newstartblock.operations = list(llops)
@@ -691,6 +692,20 @@
if op.opname == 'direct_call':
link = support.split_block_with_keepalive(block, i+1,
annotator=self.hannotator)
+
+ # the 'save_locals' pseudo-operation is used to save all
+ # alive local variables into the current JITState
+ args = list(link.args)
+ while op.result in args:
+ args.remove(op.result)
+ assert op is block.operations[i]
+ v_dummy = varoftype(lltype.Void)
+ self.hannotator.setbinding(v_dummy, annmodel.s_ImpossibleValue)
+ extraop = flowmodel.SpaceOperation('save_locals',
+ args,
+ v_dummy)
+ block.operations.insert(i, extraop)
+
block = link.target
entering_links[block] = [link]
blocks.append(block)
More information about the Pypy-commit
mailing list