[pypy-svn] r32528 - in pypy/branch/timeshift-refactoring/pypy/jit: hintannotator timeshifter
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 20 16:34:42 CEST 2006
Author: arigo
Date: Wed Sep 20 16:34:40 2006
New Revision: 32528
Modified:
pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/bookkeeper.py
pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/model.py
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/transform.py
Log:
(arre, arigo)
Red and void-returning calls pass again.
We had to compute and cache in the hintannotator, at fix-point, the
green-ness of the OriginFlags objects, because the graphs are now
modified before the hrtyper tries to do the caching. Should work
nicely, though.
Modified: pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/bookkeeper.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/bookkeeper.py Wed Sep 20 16:34:40 2006
@@ -110,6 +110,11 @@
return origin
def compute_at_fixpoint(self):
+ # compute and cache the green-ness of OriginFlags objects
+ # while we can do so (i.e. before the graphs are modified)
+ for origin in self.originflags.values():
+ if origin.spaceop is not None:
+ origin.greenargs_cached = origin.greenargs()
# compute and cache the signature of the graphs before they are
# modified by further code
ha = self.annotator
Modified: pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/model.py (original)
+++ pypy/branch/timeshift-refactoring/pypy/jit/hintannotator/model.py Wed Sep 20 16:34:40 2006
@@ -32,6 +32,7 @@
fixed = False
read_positions = None
+ greenargs_cached = None
def __init__(self, bookkeeper=None, spaceop=None):
self.bookkeeper = bookkeeper
@@ -61,6 +62,8 @@
def greenargs(self, frame=None):
annotator = self.bookkeeper.annotator
if frame is None:
+ if self.greenargs_cached is not None:
+ return self.greenargs_cached
frame = GreenHandlerFrame(annotator)
if self.spaceop.opname == 'direct_call': # ah haa
return frame.greencallresult(self.spaceop)
@@ -229,6 +232,12 @@
else:
return hs_v1
+def originalconcretetype(hs):
+ if isinstance(hs, annmodel.SomeImpossibleValue):
+ return lltype.Void
+ else:
+ return hs.concretetype
+
# ____________________________________________________________
# operations
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 16:34:40 2006
@@ -1,5 +1,6 @@
import operator, weakref
from pypy.rpython.lltypesystem import lltype, lloperation, llmemory
+from pypy.jit.hintannotator.model import originalconcretetype
from pypy.jit.timeshifter import rvalue
from pypy.rpython.unroll import unrolling_iterable
@@ -43,7 +44,6 @@
_opdesc_cache = {}
def make_opdesc(hop):
- from pypy.jit.timeshifter.rtyper import originalconcretetype
hrtyper = hop.rtyper
op_key = (hrtyper.RGenOp, hop.spaceop.opname,
tuple([originalconcretetype(s_arg) for s_arg in hop.args_s]),
@@ -276,11 +276,11 @@
def save_return(jitstate):
jitstate.frame.dispatch_queue.return_queue.append(jitstate)
-def ll_gvar_from_redbox(jitstate, redbox):
- return redbox.getgenvar(jitstate.curbuilder)
+##def ll_gvar_from_redbox(jitstate, redbox):
+## return redbox.getgenvar(jitstate.curbuilder)
-def ll_gvar_from_constant(jitstate, ll_value):
- return jitstate.curbuilder.rgenop.genconst(ll_value)
+##def ll_gvar_from_constant(jitstate, ll_value):
+## return jitstate.curbuilder.rgenop.genconst(ll_value)
# ____________________________________________________________
@@ -430,7 +430,7 @@
enter_graph._annspecialcase_ = 'specialize:arg(1)'
# XXX is that too many specializations? ^^^
-def leave_graph_red(jitstate):
+def merge_returning_jitstates(jitstate):
return_queue = jitstate.frame.dispatch_queue.return_queue
return_cache = {}
still_pending = []
@@ -441,10 +441,18 @@
for jitstate in still_pending[:-1]:
res = retrieve_jitstate_for_merge(return_cache, jitstate, ())
assert res is True # finished
- jitstate = still_pending[-1]
+ return still_pending[-1]
+
+def leave_graph_red(jitstate):
+ jitstate = merge_returning_jitstates(jitstate)
+ myframe = jitstate.frame
+ jitstate.returnbox = myframe.local_boxes[0]
+ # ^^^ fetched by a 'fetch_return' operation
+ jitstate.frame = myframe.backframe
+ return jitstate
+
+def leave_graph_void(jitstate):
+ jitstate = merge_returning_jitstates(jitstate)
myframe = jitstate.frame
- if myframe.local_boxes: # else it's a green Void return
- jitstate.returnbox = myframe.local_boxes[0]
- # ^^^ fetched by a 'fetch_return' operation
jitstate.frame = myframe.backframe
return jitstate
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 16:34:40 2006
@@ -10,6 +10,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.hintannotator import model as hintmodel
from pypy.jit.hintannotator import container as hintcontainer
+from pypy.jit.hintannotator.model import originalconcretetype
from pypy.jit.timeshifter import rtimeshift, rvalue, rcontainer, oop
from pypy.jit.timeshifter.transform import HintGraphTransformer
from pypy.jit.codegen import model as cgmodel
@@ -38,12 +39,6 @@
# ___________________________________________________________
-def originalconcretetype(hs):
- if isinstance(hs, annmodel.SomeImpossibleValue):
- return lltype.Void
- else:
- return hs.concretetype
-
class HintRTyper(RPythonTyper):
def __init__(self, hannotator, rtyper, RGenOp):
@@ -53,7 +48,7 @@
self.RGenOp = RGenOp
self.green_reprs = PRECOMPUTED_GREEN_REPRS.copy()
self.red_reprs = {}
- self.color_cache = {}
+ #self.color_cache = {}
self.annhelper = annlowlevel.MixLevelHelperAnnotator(rtyper)
self.timeshift_mapping = {}
@@ -216,16 +211,16 @@
self.red_reprs[lowleveltype] = r
return r
- def gethscolor(self, hs):
- try:
- return self.color_cache[id(hs)]
- except KeyError:
- if hs.is_green():
- color = "green"
- else:
- color = "red"
- self.color_cache[id(hs)] = color
- return color
+## def gethscolor(self, hs):
+## try:
+## return self.color_cache[id(hs)]
+## except KeyError:
+## if hs.is_green():
+## color = "green"
+## else:
+## color = "red"
+## self.color_cache[id(hs)] = color
+## return color
def get_dispatch_subclass(self, mergepointfamily):
try:
@@ -236,6 +231,20 @@
self.dispatchsubclasses[mergepointfamily] = subclass
return subclass
+ def get_timeshifted_fnptr(self, graph, specialization_key):
+ bk = self.annotator.bookkeeper
+ tsgraph = bk.get_graph_by_key(graph, specialization_key)
+ args_hs, hs_res = self.get_sig_hs(tsgraph)
+ args_r = [self.getrepr(hs_arg) for hs_arg in args_hs]
+ ARGS = [self.r_JITState.lowleveltype]
+ ARGS += [r.lowleveltype for r in args_r]
+ RESULT = self.r_JITState.lowleveltype
+ fnptr = lltype.functionptr(lltype.FuncType(ARGS, RESULT),
+ tsgraph.name,
+ graph=tsgraph,
+ _callable = graph.func)
+ return fnptr, args_r
+
def insert_v_jitstate_everywhere(self, graph):
from pypy.translator.unsimplify import varoftype
for block in graph.iterblocks():
@@ -511,33 +520,8 @@
return self.translate_op_ptr_nonzero(hop, reverse=True)
- def guess_call_kind(self, spaceop):
- if spaceop.opname == 'indirect_call':
- return 'red' # for now
- assert spaceop.opname == 'direct_call'
- c_func = spaceop.args[0]
- fnobj = c_func.value._obj
- s_result = self.annotator.binding(spaceop.result)
- r_result = self.getrepr(s_result)
- if hasattr(fnobj._callable, 'oopspec'):
- return 'oopspec'
- elif (originalconcretetype(s_result) is not lltype.Void and
- isinstance(r_result, GreenRepr)):
- for v in spaceop.args:
- s_arg = self.annotator.binding(v)
- r_arg = self.getrepr(s_arg)
- if not isinstance(r_arg, GreenRepr):
- return 'yellow'
- return 'green'
- else:
- return 'red'
-
- def translate_op_direct_call(self, hop):
- kind = self.guess_call_kind(hop.spaceop)
- meth = getattr(self, 'handle_%s_call' % (kind,))
- return meth(hop)
-
def translate_op_indirect_call(self, hop):
+ XXX
bk = self.annotator.bookkeeper
ts = self
v_jitstate = hop.llops.getjitstate()
@@ -585,6 +569,14 @@
self.s_JITState)
hop.llops.setjitstate(v_newjs)
+ def translate_op_leave_graph_void(self, hop):
+ v_jitstate = hop.llops.getjitstate()
+ v_newjs = hop.llops.genmixlevelhelpercall(rtimeshift.leave_graph_void,
+ [self.s_JITState],
+ [v_jitstate ],
+ self.s_JITState)
+ hop.llops.setjitstate(v_newjs)
+
def translate_op_save_locals(self, hop):
v_jitstate = hop.llops.getjitstate()
boxes_r = [self.getredrepr(originalconcretetype(hs))
@@ -697,9 +689,17 @@
return rtimeshift.retrieve_jitstate_for_merge(states_dic,
jitstate, key)
- greens_v = hop.args_v[2:]
- greens_s = [annmodel.lltype_to_annotation(originalconcretetype(hs))
- for hs in hop.args_s[2:]]
+ greens_v = []
+ greens_s = []
+ for r, v in zip(hop.args_r[2:], hop.args_v[2:]):
+ s_precise_type = r.annotation()
+ s_erased_type = r.erased_annotation()
+ r_precise_type = self.rtyper.getrepr(s_precise_type)
+ r_erased_type = self.rtyper.getrepr(s_erased_type)
+ greens_v.append(hop.llops.convertvar(v, r_precise_type,
+ r_erased_type))
+ greens_s.append(s_erased_type)
+
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(merge_point,
[self.s_JITState] + greens_s,
@@ -784,7 +784,7 @@
v = hop.genop('direct_call', hop.args_v, hop.r_result.lowleveltype)
return v
- def handle_red_call(self, hop):
+ def translate_op_red_call(self, hop):
bk = self.annotator.bookkeeper
ts = self
v_jitstate = hop.llops.getjitstate()
@@ -855,14 +855,14 @@
class __extend__(pairtype(HintTypeSystem, hintmodel.SomeLLAbstractValue)):
def rtyper_makerepr((ts, hs_c), hrtyper):
- if hrtyper.gethscolor(hs_c) == 'green':
+ if hs_c.is_green():
return hrtyper.getgreenrepr(hs_c.concretetype)
else:
return hrtyper.getredrepr(hs_c.concretetype)
def rtyper_makekey((ts, hs_c), hrtyper):
- color = hrtyper.gethscolor(hs_c)
- return hs_c.__class__, color, hs_c.concretetype
+ is_green = hs_c.is_green()
+ return hs_c.__class__, is_green, hs_c.concretetype
class __extend__(pairtype(HintTypeSystem, hintmodel.SomeLLAbstractContainer)):
@@ -909,13 +909,13 @@
self.lowleveltype = hrtyper.r_RedBox.lowleveltype
self.hrtyper = hrtyper
- def get_genop_var(self, v, llops):
- ts = self.hrtyper
- v_jitstate = hop.llops.getjitstate()
- return llops.genmixlevelhelpercall(rtimeshift.ll_gvar_from_redbox,
- [ts.s_JITState, llops.hrtyper.s_RedBox],
- [v_jitstate, v],
- ts.s_ConstOrVar)
+## def get_genop_var(self, v, llops):
+## ts = self.hrtyper
+## v_jitstate = hop.llops.getjitstate()
+## return llops.genmixlevelhelpercall(rtimeshift.ll_gvar_from_redbox,
+## [ts.s_JITState, llops.hrtyper.s_RedBox],
+## [v_jitstate, v],
+## ts.s_ConstOrVar)
def convert_const(self, ll_value):
RGenOp = self.hrtyper.RGenOp
@@ -963,13 +963,13 @@
else:
return annmodel.SomeInteger()
- def get_genop_var(self, v, llops):
- ts = self.hrtyper
- v_jitstate = hop.llops.getjitstate()
- return llops.genmixlevelhelpercall(rtimeshift.ll_gvar_from_constant,
- [ts.s_JITState, self.annotation()],
- [v_jitstate, v],
- ts.s_ConstOrVar)
+## def get_genop_var(self, v, llops):
+## ts = self.hrtyper
+## v_jitstate = hop.llops.getjitstate()
+## return llops.genmixlevelhelpercall(rtimeshift.ll_gvar_from_constant,
+## [ts.s_JITState, self.annotation()],
+## [v_jitstate, v],
+## ts.s_ConstOrVar)
def convert_const(self, ll_value):
return ll_value
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 16:34:40 2006
@@ -2,6 +2,7 @@
from pypy.objspace.flow.model import SpaceOperation, mkentrymap
from pypy.annotation import model as annmodel
from pypy.jit.hintannotator import model as hintmodel
+from pypy.jit.hintannotator.model import originalconcretetype
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.rmodel import inputconst
from pypy.translator.unsimplify import varoftype, copyvar
@@ -35,6 +36,7 @@
self.insert_splits()
for block in mergepoints:
self.insert_merge(block)
+ self.split_after_calls()
self.insert_dispatcher()
self.insert_enter_graph()
self.insert_leave_graph()
@@ -47,20 +49,17 @@
# __________ helpers __________
- def genop(self, block, opname, args, result_type=None):
+ def genop(self, block, opname, args, result_type=None, result_like=None):
# 'result_type' can be a LowLevelType (for green returns)
# or a template variable whose hintannotation is copied
- if result_type is None:
- v_res = self.new_void_var()
- elif isinstance(result_type, lltype.LowLevelType):
+ if result_type is not None:
v_res = varoftype(result_type)
hs = hintmodel.SomeLLAbstractConstant(result_type, {})
self.hannotator.setbinding(v_res, hs)
- elif isinstance(result_type, Variable):
- var = result_type
- v_res = copyvar(self.hannotator, var)
+ elif result_like is not None:
+ v_res = copyvar(self.hannotator, result_like)
else:
- raise TypeError("result_type=%r" % (result_type,))
+ v_res = self.new_void_var()
spaceop = SpaceOperation(opname, args, v_res)
if isinstance(block, list):
@@ -100,6 +99,19 @@
block.recloseblock(Link([], newblock))
return newblock
+ def variables_alive(self, block, before_position):
+ created_before = dict.fromkeys(block.inputargs)
+ for op in block.operations[:before_position]:
+ created_before[op.result] = True
+ used = {}
+ for op in block.operations[before_position:]:
+ for v in op.args:
+ used[v] = True
+ for link in block.exits:
+ for v in link.args:
+ used[v] = True
+ return [v for v in used if v in created_before]
+
def sort_by_color(self, vars):
reds = []
greens = []
@@ -183,12 +195,12 @@
if self.hannotator.binding(v).is_green():
c = inputconst(lltype.Signed, greencount)
v1 = self.genop(resumeblock, 'restore_green', [c],
- result_type = v)
+ result_like = v)
greencount += 1
else:
c = inputconst(lltype.Signed, redcount)
v1 = self.genop(resumeblock, 'restore_local', [c],
- result_type = v)
+ result_like = v)
redcount += 1
newvars.append(v1)
@@ -221,7 +233,7 @@
for i, v in enumerate(reds):
c = inputconst(lltype.Signed, i)
v1 = self.genop(restoreops, 'restore_local', [c],
- result_type = v)
+ result_like = v)
mapping[v] = v1
nextblock.renamevariables(mapping)
nextblock.operations[:0] = restoreops
@@ -245,7 +257,13 @@
def insert_save_return(self):
block = self.before_return_block()
[v_retbox] = block.inputargs
- self.genop(block, 'save_locals', [v_retbox])
+ hs_retbox = self.hannotator.binding(v_retbox)
+ if originalconcretetype(hs_retbox) is lltype.Void:
+ self.leave_graph_opname = 'leave_graph_void'
+ self.genop(block, 'save_locals', [])
+ else:
+ self.leave_graph_opname = 'leave_graph_red'
+ self.genop(block, 'save_locals', [v_retbox])
self.genop(block, 'save_return', [])
def insert_enter_graph(self):
@@ -258,4 +276,74 @@
def insert_leave_graph(self):
block = self.before_return_block()
- self.genop(block, 'leave_graph_red', [])
+ self.genop(block, self.leave_graph_opname, [])
+
+ # __________ handling of the various kinds of calls __________
+
+ def guess_call_kind(self, spaceop):
+ if spaceop.opname == 'indirect_call':
+ return 'red' # for now
+ assert spaceop.opname == 'direct_call'
+ c_func = spaceop.args[0]
+ fnobj = c_func.value._obj
+ s_result = self.hannotator.binding(spaceop.result)
+ if hasattr(fnobj._callable, 'oopspec'):
+ return 'oopspec'
+ elif (originalconcretetype(s_result) is not lltype.Void and
+ s_result.is_green()):
+ for v in spaceop.args:
+ s_arg = self.hannotator.binding(v)
+ if not s_arg.is_green():
+ return 'yellow'
+ return 'green'
+ else:
+ return 'red'
+
+ def split_after_calls(self):
+ for block in list(self.graph.iterblocks()):
+ for i in range(len(block.operations)-1, -1, -1):
+ op = block.operations[i]
+ if op.opname in ('direct_call', 'indirect_call'):
+ call_kind = self.guess_call_kind(op)
+ handler = getattr(self, 'handle_%s_call' % (call_kind,))
+ handler(block, i)
+
+ def handle_red_call(self, block, pos):
+ # the 'save_locals' pseudo-operation is used to save all
+ # alive local variables into the current JITState
+ beforeops = block.operations[:pos]
+ op = block.operations[pos]
+ afterops = block.operations[pos+1:]
+
+ varsalive = self.variables_alive(block, pos+1)
+ try:
+ varsalive.remove(op.result)
+ uses_retval = True # it will be restored by 'fetch_return'
+ except ValueError:
+ uses_retval = False
+ reds, greens = self.sort_by_color(varsalive)
+
+ newops = []
+ self.genop(newops, 'save_locals', reds)
+ self.genop(newops, 'red_call', op.args) # Void result,
+ # because the call doesn't return its redbox result, but only
+ # has the hidden side-effect of putting it in the jitstate
+ mapping = {}
+ for i, var in enumerate(reds):
+ c_index = Constant(i, concretetype=lltype.Signed)
+ newvar = self.genop(newops, 'restore_local', [c_index],
+ result_like = var)
+ mapping[var] = newvar
+
+ if uses_retval and not self.hannotator.binding(op.result).is_green():
+ var = op.result
+ newvar = self.genop(newops, 'fetch_return', [],
+ result_like = var)
+ mapping[var] = newvar
+
+ saved = block.inputargs
+ block.inputargs = [] # don't rename these!
+ block.operations = afterops
+ block.renamevariables(mapping)
+ block.inputargs = saved
+ block.operations[:0] = beforeops + newops
More information about the Pypy-commit
mailing list