[pypy-svn] r37932 - in pypy/branch/jit-virtual-world/pypy/jit: hintannotator hintannotator/test timeshifter timeshifter/test
arigo at codespeak.net
arigo at codespeak.net
Sun Feb 4 23:12:05 CET 2007
Author: arigo
Date: Sun Feb 4 23:12:02 2007
New Revision: 37932
Modified:
pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py
pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py
pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py
pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py
Log:
(pedronis, arigo)
* hint-annotation fixes for indirect yellow calls.
* refactor and try to unify a bit more red and yellow calls
in the transformer. The result is rather powerful (and
completely obscure in the transformer).
* deepfrozen lists in the oopspec timeshifting.
Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py Sun Feb 4 23:12:02 2007
@@ -317,7 +317,8 @@
graph = desc.specialize(args_hs, key=key, alt_name=alt_name)
return graph
- def graph_call(self, graph, fixed, args_hs, tsgraph_accum=None):
+ def graph_call(self, graph, fixed, args_hs,
+ tsgraph_accum=None, hs_callable=None):
input_args_hs = list(args_hs)
graph = self.get_graph_for_call(graph, fixed, input_args_hs)
if tsgraph_accum is not None:
@@ -337,27 +338,34 @@
input_args_hs)
# look on which input args the hs_res result depends on
if isinstance(hs_res, hintmodel.SomeLLAbstractConstant):
- deps_hs = []
- for hs_inputarg, hs_arg in zip(input_args_hs, args_hs):
- if isinstance(hs_inputarg, hintmodel.SomeLLAbstractConstant):
- assert len(hs_inputarg.origins) == 1
- [o] = hs_inputarg.origins.keys()
- if o in hs_res.origins:
- deps_hs.append(hs_arg)
- if fixed:
- deps_hs.append(hs_res)
- hs_res = hintmodel.reorigin(hs_res, *deps_hs)
+ if (hs_callable is not None and
+ not isinstance(hs_callable, hintmodel.SomeLLAbstractConstant)):
+ hs_res = hintmodel.variableoftype(hs_res.concretetype,
+ hs_res.deepfrozen)
+ else:
+ deps_hs = []
+ for hs_inputarg, hs_arg in zip(input_args_hs, args_hs):
+ if isinstance(hs_inputarg,
+ hintmodel.SomeLLAbstractConstant):
+ assert len(hs_inputarg.origins) == 1
+ [o] = hs_inputarg.origins.keys()
+ if o in hs_res.origins:
+ deps_hs.append(hs_arg)
+ if fixed:
+ deps_hs.append(hs_res)
+ hs_res = hintmodel.reorigin(hs_res, hs_callable, *deps_hs)
return hs_res
def graph_family_call(self, graph_list, fixed, args_hs,
- tsgraphs_accum=None):
+ tsgraphs_accum=None, hs_callable=None):
if tsgraphs_accum is None:
tsgraphs = []
else:
tsgraphs = tsgraphs_accum
results_hs = []
for graph in graph_list:
- results_hs.append(self.graph_call(graph, fixed, args_hs, tsgraphs))
+ results_hs.append(self.graph_call(graph, fixed, args_hs,
+ tsgraphs, hs_callable))
# put the tsgraphs in the same call family
call_families = self.tsgraph_maximal_call_families
_, rep, callfamily = call_families.find(tsgraphs[0])
Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py Sun Feb 4 23:12:02 2007
@@ -83,6 +83,11 @@
args = self.spaceop.args[1:]
elif self.spaceop.opname == 'indirect_call':
args = self.spaceop.args[1:-1]
+ # indirect_call with a red callable must return a red
+ # (see test_indirect_yellow_call)
+ v_callable = self.spaceop.args[0]
+ retdeps = greenorigindependencies.setdefault(self, [])
+ retdeps.append(v_callable)
else:
raise AssertionError(self.spaceop.opname)
@@ -182,11 +187,11 @@
for o in self.origins:
if not o.fixed:
return False
- return True
+ return self.concretetype is not lltype.Void
def is_green(self):
- return (self.is_fixed() or self.eager_concrete or
- self.concretetype is lltype.Void or
+ return (self.concretetype is lltype.Void or
+ self.is_fixed() or self.eager_concrete or
(self.myorigin is not None and self.myorigin.greenargs))
def annotationcolor(self):
@@ -349,7 +354,7 @@
fixed = myorigin.read_fixed()
tsgraphs_accum = []
hs_res = bookkeeper.graph_family_call(graph_list, fixed, args_hs,
- tsgraphs_accum)
+ tsgraphs_accum, hs_v1)
myorigin.any_called_graph = tsgraphs_accum[0]
if isinstance(hs_res, SomeLLAbstractConstant):
Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py Sun Feb 4 23:12:02 2007
@@ -728,3 +728,41 @@
hs = hannotate(ll_function, [int], policy=P_NOVIRTUAL)
assert hs.deepfrozen
+
+
+def test_concrete_fnptr_for_green_call():
+
+ def h1(n):
+ return n * 10
+
+ def h2(n):
+ return n + 20
+
+ lst = [h1, h2]
+
+ def ll_function(n, m):
+ h = hint(lst, deepfreeze=True)[m]
+ res = h(n)
+ hint(res, concrete=True) # so 'h' gets green, so 'm' gets green
+ return m
+
+ hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL)
+ assert hs.is_green()
+
+
+def test_indirect_yellow_call():
+
+ def h1(n):
+ return 123
+
+ def h2(n):
+ return 456
+
+ lst = [h1, h2]
+
+ def ll_function(n, m):
+ h = hint(lst, deepfreeze=True)[m]
+ return h(n)
+
+ hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL)
+ assert not hs.is_green()
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sun Feb 4 23:12:02 2007
@@ -198,6 +198,7 @@
assert self.portal_contains_global_mp, (
"No global merge point found. "
"Forgot 'hint(None, global_merge_point=True)'?")
+ #import pdb; pdb.set_trace()
# only keep the hint-annotated graphs that are really useful
self.annotator.translator.graphs = [graph
for graph in self.annotator.translator.graphs
@@ -1415,6 +1416,10 @@
def translate_op_residual_gray_noexc_call(self, hop):
self.translate_op_residual_red_call(hop, color='gray', exc=False)
+ translate_op_residual_yellow_call = translate_op_residual_red_call
+ translate_op_residual_yellow_noexc_call = (
+ translate_op_residual_red_noexc_call)
+
def translate_op_after_residual_call(self, hop):
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.after_residual_call,
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py Sun Feb 4 23:12:02 2007
@@ -441,3 +441,31 @@
res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL)
assert not res
+ def test_greenmethod_call_nonpromote(self):
+ class Base(object):
+ pass
+ class Int(Base):
+ def __init__(self, n):
+ self.n = n
+ def tag(self):
+ return 123
+ class Str(Base):
+ def __init__(self, s):
+ self.s = s
+ def tag(self):
+ return 456
+
+ def ll_main(n):
+ if n > 0:
+ o = Int(n)
+ else:
+ o = Str('123')
+ return ll_function(o)
+
+ def ll_function(o):
+ hint(None, global_merge_point=True)
+ return o.tag()
+
+ res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL)
+ assert res == 123
+ self.check_insns(indirect_call=1)
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Sun Feb 4 23:12:02 2007
@@ -1135,6 +1135,10 @@
assert res == 42
self.check_insns({})
+ res = self.timeshift(f, [0], [], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(indirect_call=0)
+
def test_simple_red_meth(self):
class Base(object):
def m(self, n):
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py Sun Feb 4 23:12:02 2007
@@ -1,5 +1,6 @@
from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.rlib.objectmodel import hint
P_OOPSPEC = HintAnnotatorPolicy(novirtualcontainer = True,
oopspec = True)
@@ -40,3 +41,22 @@
res = self.timeshift(ll_function, [], [], policy=P_OOPSPEC)
assert res == 39
self.check_insns({})
+
+ def test_dicts_deepfreeze(self):
+ d1 = {1: 123, 2: 54, 3:84}
+ d2 = {1: 831, 2: 32, 3:81}
+ def getdict(n):
+ if n:
+ return d1
+ else:
+ return d2
+ def ll_function(n, i):
+ d = getdict(n)
+ d = hint(d, deepfreeze=True)
+ res = d[i]
+ res = hint(res, variable=True)
+ return res
+
+ res = self.timeshift(ll_function, [3, 2], [0, 1], policy=P_OOPSPEC)
+ assert res == 54
+ self.check_insns({})
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py Sun Feb 4 23:12:02 2007
@@ -1,5 +1,6 @@
from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.rlib.objectmodel import hint
P_OOPSPEC = HintAnnotatorPolicy(novirtualcontainer=True, oopspec=True)
@@ -110,3 +111,21 @@
assert res == 9
self.check_insns({})
+ def test_lists_deepfreeze(self):
+ l1 = [1,2,3,4,5]
+ l2 = [6,7,8,9,10]
+ def getlist(n):
+ if n:
+ return l1
+ else:
+ return l2
+ def ll_function(n, i):
+ l = getlist(n)
+ l = hint(l, deepfreeze=True)
+ res = l[i]
+ res = hint(res, variable=True)
+ return res
+
+ res = self.timeshift(ll_function, [3, 4], [0, 1], policy=P_OOPSPEC)
+ assert res == 5
+ self.check_insns({})
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Sun Feb 4 23:12:02 2007
@@ -553,7 +553,8 @@
args_v = op.args[:1] + args_v + [c_targets]
hs_func = self.hannotator.binding(args_v[0])
if not hs_func.is_green():
- # XXX for now, assume that it will be a constant red box
+ # handle_red_call() has checked with is_constant that
+ # the hs_func is actually a constant red box
v_greenfunc = self.genop(block, 'revealconst', [args_v[0]],
resulttype = originalconcretetype(hs_func))
args_v[0] = v_greenfunc
@@ -574,8 +575,7 @@
linkargs = link.args
varsalive = list(linkargs)
- if color == 'red':
- assert not self.hannotator.binding(op.result).is_green()
+ if color != 'gray':
# the result will be either passed as an extra local 0
# by the caller, or restored by a restore_local
try:
@@ -622,10 +622,28 @@
blockset[postconstantblock] = False
self.make_call(constantblock, op, reds, color)
- resumepoint = self.get_resume_point(nextblock)
+ conversionblock = nextblock
+ if color == 'red':
+ assert not self.hannotator.binding(op.result).is_green()
+ elif color == 'yellow':
+ conversionblock = Block([copyvar(self.hannotator, v)
+ for v in nextblock.inputargs])
+ v0 = conversionblock.inputargs[0]
+ already_green = self.hannotator.binding(op.result).is_green()
+ assert already_green == self.hannotator.binding(v0).is_green()
+ if not already_green:
+ RESULT = self.hannotator.binding(v0).concretetype
+ hs = hintmodel.SomeLLAbstractConstant(RESULT, {})
+ self.hannotator.bindings[v0] = hs
+ conversionblock.closeblock(Link(conversionblock.inputargs,
+ nextblock))
+ # to merge some of the possibly many return jitstates
+ self.mergepoint_set[nextblock] = 'local'
+
+ resumepoint = self.get_resume_point(conversionblock)
c_resumepoint = inputconst(lltype.Signed, resumepoint)
self.genop(postconstantblock, 'collect_split', [c_resumepoint] + greens)
- resumeblock = self.get_resume_point_link(nextblock).target
+ resumeblock = self.get_resume_point_link(conversionblock).target
postconstantblock.recloseblock(Link([], resumeblock))
if nonconstantblock is not None:
@@ -633,7 +651,7 @@
v_res, nonconstantblock2 = self.handle_residual_call_details(
nonconstantblock, 0, op,
color, preserve_res =
- (color == 'red'))
+ (color != 'gray'))
#if color == 'red':
# linkargs[0] = v_res
@@ -683,55 +701,7 @@
op.opname = 'green_call'
def handle_yellow_call(self, block, pos):
- op = block.operations[pos]
- #if op.opname == 'direct_call':
- # f = open('LOG', 'a')
- # print >> f, 'handle_yellow_call', op.args[0].value
- # f.close()
- hs_result = self.hannotator.binding(op.result)
- if not hs_result.is_green():
- # yellow calls are supposed to return greens,
- # add an indirection if it's not the case
- # XXX a bit strange
- RESULT = originalconcretetype(hs_result)
- v_tmp = varoftype(RESULT)
- hs = hintmodel.SomeLLAbstractConstant(RESULT, {})
- self.hannotator.setbinding(v_tmp, hs)
- v_real_result = op.result
- op.result = v_tmp
- newop = SpaceOperation('same_as', [v_tmp], v_real_result)
- block.operations.insert(pos+1, newop)
-
- link = split_block(self.hannotator, block, pos+1)
- op1 = block.operations.pop(pos)
- assert op1 is op
- 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)
- postblock = self.naive_split_block(block, len(block.operations))
- self.make_call(block, op, reds, 'yellow')
-
- resumepoint = self.get_resume_point(nextblock)
- c_resumepoint = inputconst(lltype.Signed, resumepoint)
- self.genop(postblock, 'collect_split', [c_resumepoint] + greens)
- link.args = []
- link.target = self.get_resume_point_link(nextblock).target
-
- # to merge some of the possibly many return jitstates
- self.mergepoint_set[nextblock] = 'local'
-
- SSA_to_SSI({block: True,
- postblock: False}, self.hannotator)
+ self.handle_red_call(block, pos, color='yellow')
def handle_residual_call(self, block, pos, qualifiers=[]):
op = block.operations[pos]
Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Sun Feb 4 23:12:02 2007
@@ -288,19 +288,23 @@
else:
return oopspecdesc.residual_call(jitstate, [selfbox])
-def oop_list_len(jitstate, oopspecdesc, selfbox):
+def oop_list_len(jitstate, oopspecdesc, deepfrozen, selfbox):
content = selfbox.content
if isinstance(content, VirtualList):
return rvalue.ll_fromvalue(jitstate, len(content.item_boxes))
else:
- return oopspecdesc.residual_call(jitstate, [selfbox])
+ return oopspecdesc.residual_call(jitstate, [selfbox],
+ deepfrozen=deepfrozen)
+oop_list_len.couldfold = True
-def oop_list_nonzero(jitstate, oopspecdesc, selfbox):
+def oop_list_nonzero(jitstate, oopspecdesc, deepfrozen, selfbox):
content = selfbox.content
if isinstance(content, VirtualList):
return rvalue.ll_fromvalue(jitstate, bool(content.item_boxes))
else:
- return oopspecdesc.residual_call(jitstate, [selfbox])
+ return oopspecdesc.residual_call(jitstate, [selfbox],
+ deepfrozen=deepfrozen)
+oop_list_nonzero.couldfold = True
def oop_list_append(jitstate, oopspecdesc, selfbox, itembox):
content = selfbox.content
@@ -360,7 +364,7 @@
else:
oopspecdesc.residual_call(jitstate, [selfbox])
-def oop_list_getitem(jitstate, oopspecdesc, selfbox, indexbox):
+def oop_list_getitem(jitstate, oopspecdesc, deepfrozen, selfbox, indexbox):
content = selfbox.content
if isinstance(content, VirtualList) and indexbox.is_constant():
index = rvalue.ll_getvalue(indexbox, lltype.Signed)
@@ -369,7 +373,9 @@
except IndexError:
return oopspecdesc.residual_exception(jitstate, IndexError)
else:
- return oopspecdesc.residual_call(jitstate, [selfbox, indexbox])
+ return oopspecdesc.residual_call(jitstate, [selfbox, indexbox],
+ deepfrozen=deepfrozen)
+oop_list_getitem.couldfold = True
def oop_list_setitem(jitstate, oopspecdesc, selfbox, indexbox, itembox):
content = selfbox.content
More information about the pypy-svn
mailing list