[pypy-svn] r51938 - in pypy/branch/jit-refactoring/pypy/jit: rainbow rainbow/test timeshifter/test
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri Feb 29 11:19:22 CET 2008
Author: cfbolz
Date: Fri Feb 29 11:19:22 2008
New Revision: 51938
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py
pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py
Log:
some support for recursive portal calls
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py Fri Feb 29 11:19:22 2008
@@ -103,7 +103,9 @@
def make_bytecode(self, graph, is_portal=True):
remove_same_as(graph)
if is_portal:
- self.all_graphs[graph] = JitCode.__new__(JitCode)
+ bytecode = JitCode.__new__(JitCode)
+ bytecode.is_portal = True
+ self.all_graphs[graph] = bytecode
self.seen_blocks = {}
self.assembler = []
self.constants = []
@@ -795,11 +797,17 @@
assert len(targets) == 1
targetgraph, = targets.values()
graphindex = self.graph_position(targetgraph)
+ bytecode = self.all_graphs[targetgraph]
args = targetgraph.getargs()
emitted_args = self.args_of_call(op.args[1:], args)
- self.emit("red_direct_call")
- self.emit(*emitted_args)
- self.emit(graphindex)
+
+ if bytecode.is_portal:
+ self.emit("portal_call", *emitted_args)
+ else:
+ self.emit("red_direct_call")
+ self.emit(*emitted_args)
+ self.emit(graphindex)
+
if kind == "red":
self.register_redvar(op.result)
self.emit("red_after_direct_call")
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py Fri Feb 29 11:19:22 2008
@@ -17,6 +17,7 @@
green vars are positive indexes
green consts are negative indexes
"""
+ is_portal = False
def __init__(self, name, code, constants, typekinds, redboxclasses,
keydescs, structtypedescs, fielddescs, arrayfielddescs,
@@ -487,6 +488,10 @@
self.frame.local_green)
assert newjitstate is self.jitstate
+ @arguments("green_varargs", "red_varargs")
+ def opimpl_portal_call(self, greenargs, redargs):
+ self.portalstate.portal_reentry(greenargs, redargs)
+
@arguments("green", "calldesc", "green_varargs")
def opimpl_green_direct_call(self, fnptr_gv, calldesc, greenargs):
calldesc.green_call(self, fnptr_gv, greenargs)
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py Fri Feb 29 11:19:22 2008
@@ -42,11 +42,11 @@
concretetype = originalconcretetype(binding)
if binding.is_green():
ORIGARGS.append(concretetype)
- arg_spec = "green", None, None
+ arg_spec = "green", None, None, concretetype
else:
argdesc = self.getportalargdesc(concretetype)
arg_spec = ("red", argdesc.residual_args_collector(),
- argdesc.arg_redbox_maker())
+ argdesc.arg_redbox_maker(), concretetype)
ARGS.extend(argdesc.residual_argtypes())
args_specification.append(arg_spec)
self.args_specification = args_specification
@@ -124,7 +124,7 @@
def make_key(self, *args):
key = ()
i = 0
- for color, collect_residual_args, _ in args_specification:
+ for color, collect_residual_args, _, _ in args_specification:
if color == "green":
x = args[i]
if isinstance(lltype.typeOf(x), lltype.Ptr):
@@ -133,10 +133,26 @@
i = i + 1
return key
+ def make_key_from_genconsts(self, green_gv):
+ key = ()
+ i = 0
+ j = 0
+ for color, collect_residual_args, _, TYPE in args_specification:
+ if color == "green":
+ genconst = green_gv[j]
+ x = genconst.revealconst(TYPE)
+ if isinstance(TYPE, lltype.Ptr):
+ x = llmemory.cast_ptr_to_adr(x)
+ key = key + (x,)
+ j += 1
+ i = i + 1
+ return key
+
+
def make_residualargs(self, *args):
residualargs = ()
i = 0
- for color, collect_residual_args, _ in args_specification:
+ for color, collect_residual_args, _, _ in args_specification:
if color != "green":
residualargs = residualargs + collect_residual_args(args[i])
i = i + 1
@@ -162,6 +178,48 @@
else:
return fn(*residualargs)
+ def portal_reentry(self, greenargs, redargs):
+ jitstate = self.interpreter.jitstate
+ curbuilder = jitstate.curbuilder
+ rgenop = self.interpreter.rgenop
+ i = 0
+ cache = self.cache
+ key = self.make_key_from_genconsts(greenargs)
+ try:
+ gv_generated = cache[key]
+ except KeyError:
+ builder, gv_generated, inputargs_gv = rgenop.newgraph(sigtoken,
+ "generated")
+ self.cache[key] = gv_generated
+ top_jitstate = self.interpreter.fresh_jitstate(builder)
+ newredargs = ()
+ red_i = 0
+ for color, _, make_arg_redbox, _ in args_specification:
+ if color == "red":
+ box = make_arg_redbox(top_jitstate, inputargs_gv, red_i)
+ red_i += make_arg_redbox.consumes
+ newredargs += (box,)
+ newredargs = list(newredargs)
+
+ self.graph_compilation_queue.append(
+ (top_jitstate, greenargs, newredargs))
+ residualargs_gv = [box.getgenvar(jitstate) for box in redargs]
+
+ gv_res = curbuilder.genop_call(sigtoken, gv_generated,
+ residualargs_gv)
+ self.interpreter.exceptiondesc.fetch_global_excdata(jitstate)
+
+ RESTYPE = RESIDUAL_FUNCTYPE.RESULT
+ reskind = rgenop.kindToken(RESTYPE)
+ boxbuilder = rvalue.ll_redboxbuilder(RESTYPE)
+
+ if RESTYPE == lltype.Void:
+ retbox = None
+ else:
+ retbox = boxbuilder(reskind, gv_res)
+ jitstate.returnbox = retbox
+ assert jitstate.next is None
+
def compile(self, key, *args):
portal_ts_args = ()
@@ -173,14 +231,12 @@
greenargs = ()
redargs = ()
red_i = 0
- for color, _, make_arg_redbox in args_specification:
+ for color, _, make_arg_redbox, _ in args_specification:
+ llvalue = args[0]
+ args = args[1:]
if color == "green":
- llvalue = args[0]
- args = args[1:]
greenargs += (rgenop.genconst(llvalue),)
else:
- llvalue = args[0]
- args = args[1:]
box = make_arg_redbox(top_jitstate, inputargs_gv, red_i)
red_i += make_arg_redbox.consumes
redargs += (box,)
@@ -196,7 +252,7 @@
def readportal(self, *args):
i = 0
key = ()
- for color, _, _ in args_specification:
+ for color, _, _, _ in args_specification:
if color == "green":
x = args[i]
if isinstance(lltype.typeOf(x), lltype.Ptr):
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py Fri Feb 29 11:19:22 2008
@@ -554,12 +554,14 @@
self.check_insns({'int_gt': 1})
def test_recursive_call(self):
+ def indirection(n, fudge):
+ return ll_pseudo_factorial(n, fudge)
def ll_pseudo_factorial(n, fudge):
k = hint(n, concrete=True)
if n <= 0:
return 1
return n * ll_pseudo_factorial(n - 1, fudge + n) - fudge
- res = self.interpret(ll_pseudo_factorial, [4, 2], [0])
+ res = self.interpret(indirection, [4, 2], [0])
expected = ll_pseudo_factorial(4, 2)
assert res == expected
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py Fri Feb 29 11:19:22 2008
@@ -424,3 +424,119 @@
res = self.timeshift_from_portal(f, f, [15], policy=P_OOPSPEC)
assert res == 15
+
+ def test_simple_recursive_portal_call(self):
+
+ def main(code, x):
+ return evaluate(code, x)
+
+ def evaluate(y, x):
+ hint(y, concrete=True)
+ if y <= 0:
+ return x
+ z = 1 + evaluate(y - 1, x)
+ return z
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 2])
+ assert res == 5
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 5])
+ assert res == 8
+
+ res = self.timeshift_from_portal(main, evaluate, [4, 7])
+ assert res == 11
+
+
+ def test_simple_recursive_portal_call2(self):
+
+ def main(code, x):
+ return evaluate(code, x)
+
+ def evaluate(y, x):
+ hint(y, concrete=True)
+ if x <= 0:
+ return y
+ z = evaluate(y, x - 1) + 1
+ return z
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 2])
+ assert res == 5
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 5])
+ assert res == 8
+
+ res = self.timeshift_from_portal(main, evaluate, [4, 7])
+ assert res == 11
+
+ def test_simple_recursive_portal_call_with_exc(self):
+
+ def main(code, x):
+ return evaluate(code, x)
+
+ class Bottom(Exception):
+ pass
+
+ def evaluate(y, x):
+ hint(y, concrete=True)
+ if y <= 0:
+ raise Bottom
+ try:
+ z = 1 + evaluate(y - 1, x)
+ except Bottom:
+ z = 1 + x
+ return z
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 2])
+ assert res == 5
+
+ res = self.timeshift_from_portal(main, evaluate, [3, 5])
+ assert res == 8
+
+ res = self.timeshift_from_portal(main, evaluate, [4, 7])
+ assert res == 11
+
+
+ def test_portal_returns_none(self):
+ py.test.skip("portal returning None is not supported")
+ def g(x):
+ x = hint(x, promote=True)
+ if x == 42:
+ return None
+ def f(x):
+ return g(x)
+
+ res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
+
+ def test_portal_returns_none_with_origins(self):
+ py.test.skip("portal returning None is not supported")
+ def returnNone():
+ pass
+ def returnNone2():
+ pass
+ def g(x):
+ x = hint(x, promote=True)
+ if x == 42:
+ return returnNone()
+ return returnNone2()
+ def f(x):
+ return g(x)
+
+ res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
+
+ def test_recursive_portal_call(self):
+ py.test.skip("not working yet")
+ def indirection(green, red):
+ newgreen = hint((green + red) % 100, promote=True)
+ return portal(newgreen, red + 1)
+ def portal(green, red):
+ hint(None, global_merge_point=True)
+ green = abs(green)
+ red = abs(red)
+ hint(green, concrete=True)
+ if green > 42:
+ return 0
+ if red > 42:
+ return 1
+ return indirection(green, red)
+ res = self.timeshift_from_portal(portal, portal, [41, 1], policy=P_NOVIRTUAL)
+ assert res == 0
Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py Fri Feb 29 11:19:22 2008
@@ -141,117 +141,3 @@
return calls
class TestPortal(PortalTest):
- def test_simple_recursive_portal_call(self):
-
- def main(code, x):
- return evaluate(code, x)
-
- def evaluate(y, x):
- hint(y, concrete=True)
- if y <= 0:
- return x
- z = 1 + evaluate(y - 1, x)
- return z
-
- res = self.timeshift_from_portal(main, evaluate, [3, 2])
- assert res == 5
-
- res = self.timeshift_from_portal(main, evaluate, [3, 5])
- assert res == 8
-
- res = self.timeshift_from_portal(main, evaluate, [4, 7])
- assert res == 11
-
-
- def test_simple_recursive_portal_call2(self):
-
- def main(code, x):
- return evaluate(code, x)
-
- def evaluate(y, x):
- hint(y, concrete=True)
- if x <= 0:
- return y
- z = evaluate(y, x - 1) + 1
- return z
-
- res = self.timeshift_from_portal(main, evaluate, [3, 2])
- assert res == 5
-
- res = self.timeshift_from_portal(main, evaluate, [3, 5])
- assert res == 8
-
- res = self.timeshift_from_portal(main, evaluate, [4, 7])
- assert res == 11
-
- def test_simple_recursive_portal_call_with_exc(self):
-
- def main(code, x):
- return evaluate(code, x)
-
- class Bottom(Exception):
- pass
-
- def evaluate(y, x):
- hint(y, concrete=True)
- if y <= 0:
- raise Bottom
- try:
- z = 1 + evaluate(y - 1, x)
- except Bottom:
- z = 1 + x
- return z
-
- res = self.timeshift_from_portal(main, evaluate, [3, 2])
- assert res == 5
-
- res = self.timeshift_from_portal(main, evaluate, [3, 5])
- assert res == 8
-
- res = self.timeshift_from_portal(main, evaluate, [4, 7])
- assert res == 11
-
-
- def test_portal_returns_none(self):
- py.test.skip("portal returning None is not supported")
- def g(x):
- x = hint(x, promote=True)
- if x == 42:
- return None
- def f(x):
- return g(x)
-
- res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
-
- def test_portal_returns_none_with_origins(self):
- py.test.skip("portal returning None is not supported")
- def returnNone():
- pass
- def returnNone2():
- pass
- def g(x):
- x = hint(x, promote=True)
- if x == 42:
- return returnNone()
- return returnNone2()
- def f(x):
- return g(x)
-
- res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
-
- def test_recursive_portal_call(self):
- def indirection(green, red):
- newgreen = hint((green + red) % 100, promote=True)
- return portal(newgreen, red + 1)
- def portal(green, red):
- hint(None, global_merge_point=True)
- green = abs(green)
- red = abs(red)
- hint(green, concrete=True)
- if green > 42:
- return 0
- if red > 42:
- return 1
- return indirection(green, red)
- res = self.timeshift_from_portal(portal, portal, [41, 1], policy=P_NOVIRTUAL)
- assert res == 0
More information about the Pypy-commit
mailing list