[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