[pypy-svn] r52040 - in pypy/branch/jit-refactoring/pypy/jit/rainbow: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sun Mar 2 15:53:21 CET 2008
Author: cfbolz
Date: Sun Mar 2 15:53:21 2008
New Revision: 52040
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
Log:
support for metacalls
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 Sun Mar 2 15:53:21 2008
@@ -69,6 +69,53 @@
def _freeze_(self):
return True
+
+class CallDesc:
+ __metaclass__ = cachedtype
+
+ def __init__(self, RGenOp, rtyper, FUNCTYPE, voidargs=()):
+ self.sigtoken = RGenOp.sigToken(FUNCTYPE.TO)
+ self.result_kind = RGenOp.kindToken(FUNCTYPE.TO.RESULT)
+ # xxx what if the result is virtualizable?
+ self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.TO.RESULT)
+ whatever_return_value = FUNCTYPE.TO.RESULT._defl()
+ numargs = len(FUNCTYPE.TO.ARGS)
+ argiter = unrolling_iterable(FUNCTYPE.TO.ARGS)
+ def green_call(interpreter, fnptr_gv, greenargs):
+ fnptr = fnptr_gv.revealconst(FUNCTYPE)
+ assert len(greenargs) + len(voidargs) == numargs
+ args = ()
+ j = 0
+ k = 0
+ for ARG in argiter:
+ if ARG == lltype.Void:
+ arg = voidargs[k]
+ # XXX terrible hack
+ if not we_are_translated():
+ arg._TYPE = lltype.Void
+ args += (arg, )
+ k += 1
+ else:
+ genconst = greenargs[j]
+ arg = genconst.revealconst(ARG)
+ args += (arg, )
+ j += 1
+ rgenop = interpreter.jitstate.curbuilder.rgenop
+ try:
+ result = rgenop.genconst(fnptr(*args))
+ except Exception, e:
+ if not we_are_translated():
+ residual_exception_nontranslated(interpreter.jitstate, e, rtyper)
+ else:
+ interpreter.jitstate.residual_exception(e)
+ result = rgenop.genconst(whatever_return_value)
+ interpreter.green_result(result)
+ self.green_call = green_call
+
+ def _freeze_(self):
+ return True
+
+
class IndirectCallsetDesc(object):
__metaclass__ = cachedtype
@@ -143,6 +190,7 @@
self.graph_color = self.graph_calling_color(graph)
self.calldescs = []
self.indirectcalldescs = []
+ self.metacalldescs = []
self.is_portal = is_portal
# mapping constant -> index in constants
self.const_positions = {}
@@ -176,6 +224,8 @@
self.graph_positions = {}
# mapping fnobjs to index
self.calldesc_positions = {}
+ # mapping class to index
+ self.metacalldesc_positions = {}
# mapping fnobjs to index
self.indirectcalldesc_positions = {}
@@ -205,6 +255,7 @@
self.num_local_mergepoints,
self.graph_color,
self.calldescs,
+ self.metacalldescs,
self.indirectcalldescs,
self.is_portal)
bytecode._source = self.assembler
@@ -608,6 +659,29 @@
self.calldesc_positions[key] = result
return result
+ def metacalldesc_position(self, op):
+ key = op
+ if key in self.metacalldesc_positions:
+ return self.metacalldesc_positions[key]
+ result = len(self.metacalldescs)
+ metadesc = op.args[1].value(self)
+ ARGS = [arg.concretetype for arg in op.args[2:]]
+ argiter = unrolling_iterable(ARGS)
+ def func(interpreter, redargs):
+ args = ()
+ j = 0
+ for ARG in argiter:
+ if ARG == lltype.Void:
+ args += (None, )
+ else:
+ box = redargs[j]
+ args += (box, )
+ j += 1
+ return metadesc.metafunc(interpreter.jitstate, *args)
+ self.metacalldescs.append(func)
+ self.metacalldesc_positions[key] = result
+ return result
+
def indirectcalldesc_position(self, graph2code):
key = graph2code.items()
key.sort()
@@ -753,6 +827,15 @@
print op, kind, withexc
return handler(op, withexc)
+ def serialize_op_ts_metacall(self, op):
+ emitted_args = []
+ for v in op.args[2:]:
+ if v.concretetype != lltype.Void:
+ emitted_args.append(self.serialize_oparg("red", v))
+ metaindex = self.metacalldesc_position(op)
+ self.emit("metacall", metaindex, len(emitted_args), *emitted_args)
+ self.register_redvar(op.result)
+
def serialize_op_indirect_call(self, op):
kind, withexc = self.guess_call_kind(op)
if kind == "green":
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py Sun Mar 2 15:53:21 2008
@@ -132,6 +132,10 @@
index = src.load_2byte()
function = jitcode.calldescs[index]
args.append(function)
+ elif argspec == "metacalldesc":
+ index = src.load_2byte()
+ function = jitcode.metacalldescs[index]
+ args.append(function)
elif argspec == "indirectcalldesc":
index = src.load_2byte()
function = jitcode.indirectcalldescs[index]
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 Sun Mar 2 15:53:21 2008
@@ -23,7 +23,8 @@
keydescs, structtypedescs, fielddescs, arrayfielddescs,
interiordescs, exceptioninstances, oopspecdescs,
promotiondescs, called_bytecodes, num_mergepoints,
- graph_color, calldescs, indirectcalldescs, is_portal):
+ graph_color, calldescs, metacalldescs,
+ indirectcalldescs, is_portal):
self.name = name
self.code = code
self.constants = constants
@@ -41,6 +42,7 @@
self.num_mergepoints = num_mergepoints
self.graph_color = graph_color
self.calldescs = calldescs
+ self.metacalldescs = metacalldescs
self.indirectcalldescs = indirectcalldescs
self.is_portal = is_portal
@@ -121,6 +123,10 @@
index = self.load_2byte()
function = self.frame.bytecode.calldescs[index]
args += (function, )
+ elif argspec == "metacalldesc":
+ index = self.load_2byte()
+ function = self.frame.bytecode.metacalldescs[index]
+ args += (function, )
elif argspec == "indirectcalldesc":
index = self.load_2byte()
function = self.frame.bytecode.indirectcalldescs[index]
@@ -647,6 +653,11 @@
rtimeshift.residual_fetch(self.jitstate, self.exceptiondesc,
True, flagbox)
+ @arguments("metacalldesc", "red_varargs", returns="red")
+ def opimpl_metacall(self, metafunc, redargs):
+ return metafunc(self, redargs)
+
+
# exceptions
@arguments(returns="red")
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 Sun Mar 2 15:53:21 2008
@@ -1641,10 +1641,49 @@
res = self.interpret(f, [2, 4], backendoptimize=True)
assert res == 56 - 90
- def test_substitute_graph(self):
- py.test.skip("not working yet")
+ def test_simple_substitute_graph(self):
class MetaG:
+ def __init__(self, codewriter):
+ pass
+
+ def _freeze_(self):
+ return True
+
+ def metafunc(self, jitstate, abox, bbox):
+ from pypy.jit.timeshifter.rvalue import IntRedBox
+ builder = jitstate.curbuilder
+ gv_result = builder.genop2("int_sub", abox.getgenvar(jitstate),
+ bbox.getgenvar(jitstate))
+ return IntRedBox(abox.kind, gv_result)
+
+ def g(a, b):
+ return a + b
+
+ def f(a, b):
+ x = g(a, b)
+ y = g(b, a)
+ return x + y
+
+ class MyPolicy(HintAnnotatorPolicy):
+ novirtualcontainer = True
+
+ def look_inside_graph(self, graph):
+ if graph.func is g:
+ return MetaG # replaces g with a meta-call to metafunc()
+ else:
+ return True
+
+ res = self.interpret(f, [3, 6], policy=MyPolicy())
+ assert res == 0
+ self.check_insns({'int_add': 1, 'int_sub': 2})
+
+ def test_substitute_graph_void(self):
+
+ class MetaG:
+ def __init__(self, codewriter):
+ pass
+
def _freeze_(self):
return True
More information about the Pypy-commit
mailing list