[pypy-svn] r33894 - in pypy/dist/pypy/jit/timeshifter: . test

pedronis at codespeak.net pedronis at codespeak.net
Mon Oct 30 15:45:20 CET 2006


Author: pedronis
Date: Mon Oct 30 15:45:18 2006
New Revision: 33894

Added:
   pypy/dist/pypy/jit/timeshifter/test/test_portal.py   (contents, props changed)
Modified:
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/rtyper.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/dist/pypy/jit/timeshifter/transform.py
Log:
(arre, pedronis)

first test passing using a main/portal (usually eval) setup for timeshifting.



Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Mon Oct 30 15:45:18 2006
@@ -422,11 +422,11 @@
 class PromotionPathRoot(AbstractPromotionPath):
     cut_limit = True
 
-    def __init__(self, greens_gv, rgenop, frozen, portalblock, global_resumer):
+    def __init__(self, greens_gv, rgenop, frozen, replayableblock, global_resumer):
         self.greens_gv = greens_gv
         self.rgenop = rgenop
         self.frozen = frozen
-        self.portalblock = portalblock
+        self.replayableblock = replayableblock
         self.global_resumer = global_resumer
 
     def follow_path(self, path):
@@ -437,7 +437,7 @@
         memo = rvalue.unfreeze_memo()
         jitstate = self.frozen.unfreeze(incoming, memo)
         kinds = [box.kind for box in incoming]
-        builder, vars_gv = self.rgenop.replay(self.portalblock, kinds)
+        builder, vars_gv = self.rgenop.replay(self.replayableblock, kinds)
         for i in range(len(incoming)):
             incoming[i].genvar = vars_gv[i]
         jitstate.curbuilder = builder
@@ -775,7 +775,7 @@
     return DispatchQueueClass()
 ensure_queue._annspecialcase_ = 'specialize:arg(1)'
 
-def portal_ensure_queue(jitstate, DispatchQueueClass):
+def replayable_ensure_queue(jitstate, DispatchQueueClass):
     resuming = jitstate.resuming
     if resuming is None:
         return DispatchQueueClass()
@@ -783,7 +783,7 @@
         dispatchqueue = jitstate.frame.dispatchqueue
         assert isinstance(dispatchqueue, DispatchQueueClass)
         return dispatchqueue
-portal_ensure_queue._annspecialcase_ = 'specialize:arg(1)'
+replayable_ensure_queue._annspecialcase_ = 'specialize:arg(1)'
 
 def enter_frame(jitstate, dispatchqueue):
     jitstate.frame = VirtualFrame(jitstate.frame, dispatchqueue)

Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py	Mon Oct 30 15:45:18 2006
@@ -4,6 +4,8 @@
 from pypy.translator.backendopt.ssa import SSA_to_SSI
 from pypy.annotation import model as annmodel
 from pypy.annotation.pairtype import pair, pairtype
+from pypy.rpython.annlowlevel import PseudoHighLevelCallable
+from pypy.rpython.unroll import unrolling_iterable
 from pypy.rpython import annlowlevel
 from pypy.rpython.rtyper import RPythonTyper, LowLevelOpList, TyperError
 from pypy.rpython.rmodel import Repr, inputconst
@@ -142,12 +144,13 @@
 
         self.v_queue = varoftype(self.r_Queue.lowleveltype, 'queue')
 
-    def specialize(self, view=False):
+    def specialize(self, origportalgraph=None, view=False):
         """
         Driver for running the timeshifter.
         """
         self.type_system.perform_normalizations(self)
-        self.annotator.bookkeeper.compute_after_normalization()
+        bk = self.annotator.bookkeeper
+        bk.compute_after_normalization()
         entrygraph = self.annotator.translator.graphs[0]
         pending = [entrygraph]
         seen = {entrygraph: True}
@@ -162,6 +165,97 @@
         for graph in seen:
             self.timeshift_graph(graph)
 
+        if origportalgraph:
+            portalgraph = bk.get_graph_by_key(origportalgraph, None)
+            self.rewire_portal(origportalgraph, portalgraph)
+        
+    def rewire_portal(self, origportalgraph, portalgraph):
+        annhelper = self.annhelper
+
+        argcolors = []
+        portal_args_s = []
+        for v in portalgraph.getargs()[1:]:
+            r = self.bindingrepr(v)
+            if isinstance(r, GreenRepr):
+                color = "green"
+                portal_args_s.append(annmodel.lltype_to_annotation(
+                    r.lowleveltype))
+            else:
+                color = "red"
+                portal_args_s.append(self.s_RedBox)
+            argcolors.append(color)
+
+        portal_fnptr = self.rtyper.type_system.getcallable(portalgraph)
+        portal_fn = PseudoHighLevelCallable(
+            portal_fnptr,
+            [self.s_JITState] + portal_args_s,
+            self.s_JITState)
+        FUNC = self.get_residual_functype(portalgraph)
+        argcolors = unrolling_iterable(argcolors)
+        fresh_jitstate = self.ll_fresh_jitstate
+        finish_jitstate = self.ll_finish_jitstate
+
+        cache = {}
+        rgenop = self.RGenOp()
+        def portalentry(*args):
+            i = 0
+            key = ()
+            residualargs = ()
+            for color in argcolors:
+                if color == "green":
+                    key = key + (args[i],)
+                else:
+                    residualargs = residualargs + (args[i],)
+                i = i + 1
+            try:
+                fn = cache[key]
+            except KeyError:
+                portal_ts_args = ()
+                sigtoken = rgenop.sigToken(FUNC)
+                builder, entrypoint, inputargs_gv = rgenop.newgraph(sigtoken)
+                i = 0
+                for color in argcolors:
+                    if color == "green":
+                        llvalue = args[0]
+                        args = args[1:]
+                        portal_ts_args += (llvalue,)
+                    else:
+                        llvalue = args[0]
+                        args = args[1:]
+                        TYPE = lltype.typeOf(llvalue)
+                        kind = rgenop.kindToken(TYPE)
+                        boxcls = rvalue.ll_redboxcls(TYPE)
+                        gv_arg = inputargs_gv[i]
+                        box = boxcls(kind, gv_arg)
+                        i += 1
+                        portal_ts_args += (box,)
+
+                top_jitstate = fresh_jitstate(builder)
+                top_jitstate = portal_fn(top_jitstate, *portal_ts_args)
+                if top_jitstate is not None:
+                    finish_jitstate(top_jitstate, sigtoken)
+
+                gv_generated = rgenop.gencallableconst(sigtoken,
+                                                       "generated",
+                                                       entrypoint)
+                fn = gv_generated.revealconst(lltype.Ptr(FUNC))
+                builder.show_incremental_progress()
+                cache[key] = fn
+            return fn(*residualargs)
+
+        args_s = [annmodel.lltype_to_annotation(v.concretetype) for
+                  v in origportalgraph.getargs()]
+        s_result = annmodel.lltype_to_annotation(
+                    origportalgraph.getreturnvar().concretetype)
+        portalentrygraph = annhelper.getgraph(portalentry, args_s, s_result)
+
+        annhelper.finish()
+
+        origportalgraph.startblock = portalentrygraph.startblock
+        origportalgraph.returnblock = portalentrygraph.returnblock
+        origportalgraph.exceptblock = portalentrygraph.exceptblock
+        # name, func?
+
     def transform_graph(self, graph):
         # prepare the graphs by inserting all bookkeeping/dispatching logic
         # as special operations
@@ -590,8 +684,8 @@
                                                   self.v_queue))
 
 
-    def translate_op_portal_ensure_queue(self, hop):
-        return self.translate_op_ensure_queue(hop, prefix='portal_')
+    def translate_op_replayable_ensure_queue(self, hop):
+        return self.translate_op_ensure_queue(hop, prefix='replayable_')
 
         
     def translate_op_enter_frame(self, hop):

Added: pypy/dist/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/timeshifter/test/test_portal.py	Mon Oct 30 15:45:18 2006
@@ -0,0 +1,48 @@
+from pypy import conftest
+from pypy.translator.translator import graphof
+from pypy.jit.timeshifter.test.test_timeshift import hannotate
+from pypy.jit.timeshifter.rtyper import HintRTyper
+from pypy.jit.codegen.llgraph.rgenop import RGenOp
+from pypy.rpython.llinterp import LLInterpreter
+from pypy.objspace.flow.model import checkgraph
+
+from pypy.rpython.objectmodel import hint
+
+
+def timeshift_from_portal(main, portal, main_args):
+    hs, ha, rtyper = hannotate(main, main_args, portal=portal)
+
+    # make the timeshifted graphs
+    hrtyper = HintRTyper(ha, rtyper, RGenOp)
+    t = rtyper.annotator.translator
+    origportalgraph = graphof(t, portal)
+    hrtyper.specialize(origportalgraph=origportalgraph,
+                       view = conftest.option.view)
+
+    for graph in ha.translator.graphs:
+        checkgraph(graph)
+        t.graphs.append(graph)
+
+    if conftest.option.view:
+        t.view()
+    maingraph = graphof(t, main)
+
+    llinterp = LLInterpreter(rtyper)
+
+    return llinterp.eval_graph(maingraph, main_args)
+
+
+def test_simple():
+
+    def main(code, x):
+        return evaluate(code, x)
+
+    def evaluate(y, x):
+        hint(y, concrete=True)
+        z = y+x
+        return z
+
+    res = timeshift_from_portal(main, evaluate, [3, 2])
+
+    assert res == 5
+    

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Mon Oct 30 15:45:18 2006
@@ -33,7 +33,8 @@
         t = annmodel.lltype_to_annotation(T)
     return a.typeannotation(t)
 
-def hannotate(func, values, policy=None, inline=None, backendoptimize=False):
+def hannotate(func, values, policy=None, inline=None, backendoptimize=False,
+              portal=None):
     # build the normal ll graphs for ll_function
     t = TranslationContext()
     a = t.buildannotator()
@@ -46,7 +47,9 @@
     if backendoptimize:
         from pypy.translator.backendopt.all import backend_optimizations
         backend_optimizations(t)
-    graph1 = graphof(t, func)
+    if portal is None:
+        portal = func
+    graph1 = graphof(t, portal)
     # build hint annotator types
     hannotator = HintAnnotator(base_translator=t, policy=policy)
     hs = hannotator.build_types(graph1, [SomeLLAbstractConstant(v.concretetype,

Modified: pypy/dist/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/transform.py	Mon Oct 30 15:45:18 2006
@@ -370,7 +370,7 @@
     def insert_ensure_queue(self):
         entryblock = self.before_start_block()
         if self.mergepointfamily.has_global_mergepoints():
-            prefix = 'portal_'
+            prefix = 'replayable_'
         else:
             prefix = ''
         self.genop(entryblock, prefix+'ensure_queue', [self.c_mpfamily])



More information about the Pypy-commit mailing list