[pypy-svn] r68020 - in pypy/branch/kill-jumptarget/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 30 13:15:24 CEST 2009


Author: arigo
Date: Wed Sep 30 13:15:23 2009
New Revision: 68020

Modified:
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py
   pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py
Log:
Progress.


Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/compile.py	Wed Sep 30 13:15:23 2009
@@ -33,6 +33,11 @@
     name = metainterp.staticdata.stats.name_for_new_loop()
     return TreeLoop(name)
 
+def make_loop_token(nb_args):
+    loop_token = LoopToken()
+    loop_token.specnodes = [prebuiltNotSpecNode] * nb_args
+    return loop_token
+
 # ____________________________________________________________
 
 def compile_new_loop(metainterp, old_loop_tokens, greenkey, start):
@@ -50,7 +55,9 @@
         loop.operations = history.operations[start:]
     else:
         loop.operations = history.operations
-    loop.operations[-1].jump_target = None
+    loop_token = make_loop_token(len(loop.inputargs))
+    loop.token = loop_token
+    loop.operations[-1].descr = loop_token     # patch the target of the JUMP
     metainterp_sd = metainterp.staticdata
     try:
         old_loop_token = metainterp_sd.state.optimize_loop(
@@ -61,12 +68,7 @@
         if DEBUG > 0:
             debug_print("reusing old loop")
         return old_loop_token
-    executable_token = send_loop_to_backend(metainterp_sd, loop, "loop")
-    loop_token = LoopToken()
-    loop_token.specnodes = loop.specnodes
-    loop_token.executable_token = executable_token
-    if not we_are_translated():
-        loop.token = loop_token
+    send_loop_to_backend(metainterp_sd, loop, "loop")
     insert_loop_token(old_loop_tokens, loop_token)
     return loop_token
 
@@ -89,8 +91,7 @@
     if not we_are_translated():
         show_loop(metainterp_sd, loop)
         loop.check_consistency()
-    executable_token = metainterp_sd.cpu.compile_loop(loop.inputargs,
-                                                      loop.operations)
+    metainterp_sd.cpu.compile_loop(loop.inputargs, loop.operations, loop.token)
     metainterp_sd.profiler.end_backend()
     metainterp_sd.stats.add_new_loop(loop)
     if not we_are_translated():
@@ -103,7 +104,6 @@
         from pypy.jit.metainterp.pyjitpl import DEBUG
         if DEBUG > 0:
             debug_print("compiled new " + type)
-    return executable_token
 
 def send_bridge_to_backend(metainterp_sd, faildescr, inputargs, operations):
     metainterp_sd.options.logger_ops.log_loop(inputargs, operations)
@@ -226,21 +226,19 @@
         # with completely unoptimized arguments, as in the interpreter.
         metainterp_sd = metainterp.staticdata
         metainterp.history.inputargs = self.redkey
+        new_loop_token = make_loop_token(len(self.redkey))
         new_loop.greenkey = self.original_greenkey
         new_loop.inputargs = self.redkey
-        executable_token = send_loop_to_backend(metainterp_sd, new_loop,
-                                                "entry bridge")
+        new_loop.token = new_loop_token
+        send_loop_to_backend(metainterp_sd, new_loop, "entry bridge")
         # send the new_loop to warmspot.py, to be called directly the next time
         metainterp_sd.state.attach_unoptimized_bridge_from_interp(
             self.original_greenkey,
-            executable_token)
+            new_loop_token)
         # store the new loop in compiled_merge_points too
         glob = metainterp_sd.globaldata
         greenargs = glob.unpack_greenkey(self.original_greenkey)
         old_loop_tokens = glob.compiled_merge_points.setdefault(greenargs, [])
-        new_loop_token = LoopToken()
-        new_loop_token.specnodes = [prebuiltNotSpecNode] * len(self.redkey)
-        new_loop_token.executable_token = executable_token
         # it always goes at the end of the list, as it is the most
         # general loop token
         old_loop_tokens.append(new_loop_token)
@@ -280,11 +278,11 @@
     op = new_loop.operations[-1]
     if not isinstance(target_loop_token, TerminatingLoopToken):
         # normal case
-        op.jump_target = target_loop_token
+        op.descr = target_loop_token     # patch the jump target
     else:
         # The target_loop_token is a pseudo loop token,
         # e.g. loop_tokens_done_with_this_frame_void[0]
-        # Replace the operation with the real operation we want, i.e. a FAIL.
+        # Replace the operation with the real operation we want, i.e. a FINISH
         descr = target_loop_token.finishdescr
         new_op = ResOperation(rop.FINISH, op.args, None, descr=descr)
         new_loop.operations[-1] = new_op

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/graphpage.py	Wed Sep 30 13:15:23 2009
@@ -168,7 +168,7 @@
                              (graphindex, opindex))
                 break
         if op.opnum == rop.JUMP:
-            tgt = op.jump_target
+            tgt = op.descr
             tgt_g = -1
             if tgt is None:
                 tgt_g = graphindex

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/history.py	Wed Sep 30 13:15:23 2009
@@ -652,13 +652,14 @@
     generated assembler.
     """
     terminating = False # see TerminatingLoopToken in compile.py
-    # specnodes
-    # executable_token
+    # specnodes = ...
+    # and more data specified by the backend when the loop is compiled
 
 class TreeLoop(object):
     inputargs = None
-    specnodes = None
     operations = None
+    token = None
+    specnodes = property(lambda x: crash, lambda x, y: crash)  # XXX temp
 
     def __init__(self, name):
         self.name = name
@@ -729,7 +730,7 @@
                 seen[box] = True
         assert operations[-1].is_final()
         if operations[-1].opnum == rop.JUMP:
-            target = operations[-1].jump_target
+            target = operations[-1].descr
             if target is not None:
                 assert isinstance(target, LoopToken)
 
@@ -802,6 +803,9 @@
     def add_new_loop(self, loop):
         pass
 
+    def view(self, **kwds):
+        pass
+
 class Stats(object):
     """For tests."""
 

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimize.py	Wed Sep 30 13:15:23 2009
@@ -9,7 +9,7 @@
     finder = PerfectSpecializationFinder(cpu)
     finder.find_nodes_loop(loop)
     for old_loop_token in old_loop_tokens:
-        if equals_specnodes(old_loop_token.specnodes, loop.specnodes):
+        if equals_specnodes(old_loop_token.specnodes, loop.token.specnodes):
             return old_loop_token
     optimize_loop_1(cpu, loop)
     return None
@@ -25,7 +25,7 @@
     finder.find_nodes_bridge(bridge)
     for old_loop_token in old_loop_tokens:
         if finder.bridge_matches(old_loop_token.specnodes):
-            bridge.operations[-1].jump_target = old_loop_token
+            bridge.operations[-1].descr = old_loop_token   # patch jump target
             optimize_bridge_1(cpu, bridge)
             return old_loop_token
     return None

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizefindnode.py	Wed Sep 30 13:15:23 2009
@@ -299,7 +299,7 @@
         for box in op.args:
             self.getnode(box).set_unique_nodes()
 
-    def find_nodes_FAIL(self, op):
+    def find_nodes_FINISH(self, op):
         # only for bridges, and only for the ones that end in a 'return'
         # or 'raise'; all other cases end with a JUMP.
         for box in op.args:
@@ -337,7 +337,7 @@
             inputnode = self.inputnodes[i]
             exitnode = self.getnode(op.args[i])
             specnodes.append(self.intersect(inputnode, exitnode))
-        loop.specnodes = specnodes
+        loop.token.specnodes = specnodes
 
     def intersect(self, inputnode, exitnode):
         assert inputnode.fromstart

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/optimizeopt.py	Wed Sep 30 13:15:23 2009
@@ -458,7 +458,7 @@
 
     def setup_virtuals_and_constants(self):
         inputargs = self.loop.inputargs
-        specnodes = self.loop.specnodes
+        specnodes = self.loop.token.specnodes
         assert len(inputargs) == len(specnodes)
         newinputargs = []
         for i in range(len(inputargs)):

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/pyjitpl.py	Wed Sep 30 13:15:23 2009
@@ -1428,7 +1428,7 @@
         residual_args = self.get_residual_args(loop_token.specnodes,
                                                gmp.argboxes[num_green_args:])
         history.set_future_values(self.cpu, residual_args)
-        return loop_token.executable_token
+        return loop_token
 
     def prepare_resume_from_failure(self, opnum):
         if opnum == rop.GUARD_TRUE:     # a goto_if_not that jumps only now

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/resume.py	Wed Sep 30 13:15:23 2009
@@ -3,7 +3,7 @@
 from pypy.jit.metainterp.resoperation import rop
 
 # Logic to encode the chain of frames and the state of the boxes at a
-# FAIL operation, and to decode it again.  This is a bit advanced,
+# guard operation, and to decode it again.  This is a bit advanced,
 # because it needs to support optimize.py which encodes virtuals with
 # arbitrary cycles.
 

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_compile.py	Wed Sep 30 13:15:23 2009
@@ -1,6 +1,9 @@
-from pypy.jit.metainterp.history import LoopToken, ConstInt
+from pypy.jit.metainterp.history import LoopToken, ConstInt, History, Stats
 from pypy.jit.metainterp.specnode import NotSpecNode, ConstantSpecNode
-from pypy.jit.metainterp.compile import insert_loop_token
+from pypy.jit.metainterp.compile import insert_loop_token, compile_new_loop
+from pypy.jit.metainterp import optimize, jitprof
+from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
 
 
 def test_insert_loop_token():
@@ -20,3 +23,71 @@
     tok3.specnodes = [ConstantSpecNode(ConstInt(-13))]
     insert_loop_token(lst, tok3)
     assert lst == [tok2, tok3, tok1]
+
+
+class FakeCPU:
+    def __init__(self):
+        self.seen = []
+    def compile_loop(self, inputargs, operations, token):
+        self.seen.append((inputargs, operations, token))
+
+class FakeLogger:
+    def log_loop(self, inputargs, operations):
+        pass
+
+class FakeOptions:
+    logger_noopt = FakeLogger()
+    logger_ops = FakeLogger()
+
+class FakeState:
+    optimize_loop = staticmethod(optimize.optimize_loop)
+
+class FakeMetaInterpStaticData:
+    options = FakeOptions()
+    state = FakeState()
+    stats = Stats()
+    profiler = jitprof.EmptyProfiler()
+
+class FakeMetaInterp:
+    pass
+
+def test_compile_new_loop():
+    cpu = FakeCPU()
+    staticdata = FakeMetaInterpStaticData()
+    staticdata.cpu = cpu
+    #
+    loop = parse('''
+    [p1]
+    i1 = getfield_gc(p1, descr=valuedescr)
+    i2 = int_add(i1, 1)
+    p2 = new_with_vtable(ConstClass(node_vtable))
+    setfield_gc(p2, i2, descr=valuedescr)
+    jump(p2)
+    ''', namespace=LLtypeMixin.__dict__.copy())
+    #
+    metainterp = FakeMetaInterp()
+    metainterp.staticdata = staticdata
+    metainterp.cpu = cpu
+    metainterp.history = History(metainterp.cpu)
+    metainterp.history.operations = loop.operations[:]
+    metainterp.history.inputargs = loop.inputargs[:]
+    #
+    loop_tokens = []
+    loop_token = compile_new_loop(metainterp, loop_tokens, [], 0)
+    assert loop_tokens == [loop_token]
+    #
+    assert len(cpu.seen) == 1
+    assert cpu.seen[0][2] == loop_token
+    #
+    del cpu.seen[:]
+    metainterp = FakeMetaInterp()
+    metainterp.staticdata = staticdata
+    metainterp.cpu = cpu
+    metainterp.history = History(metainterp.cpu)
+    metainterp.history.operations = loop.operations[:]
+    metainterp.history.inputargs = loop.inputargs[:]
+    #
+    loop_token_2 = compile_new_loop(metainterp, loop_tokens, [], 0)
+    assert loop_token_2 is loop_token
+    assert loop_tokens == [loop_token]
+    assert len(cpu.seen) == 0

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizefindnode.py	Wed Sep 30 13:15:23 2009
@@ -224,7 +224,7 @@
         loop = self.parse(ops, boxkinds=boxkinds)
         perfect_specialization_finder = PerfectSpecializationFinder(self.cpu)
         perfect_specialization_finder.find_nodes_loop(loop)
-        self.check_specnodes(loop.specnodes, spectext)
+        self.check_specnodes(loop.token.specnodes, spectext)
         return (loop.getboxes(), perfect_specialization_finder.getnode)
 
     def test_find_nodes_simple(self):
@@ -1062,6 +1062,9 @@
         finish(p1)
         """
         self.find_bridge(ops, 'Not', 'Not')
+        self.find_bridge(ops, 'Not',
+                         'Virtual(node_vtable, valuedescr=Not)',
+                         mismatch=True)
 
     def test_bridge_array_virtual_1(self):
         ops = """

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_optimizeopt.py	Wed Sep 30 13:15:23 2009
@@ -147,12 +147,11 @@
             cpu = self.cpu
             perfect_specialization_finder = PerfectSpecializationFinder(cpu)
             perfect_specialization_finder.find_nodes_loop(loop)
-            self.check_specnodes(loop.specnodes, spectext)
+            self.check_specnodes(loop.token.specnodes, spectext)
         else:
             # for cases where we want to see how optimizeopt behaves with
             # combinations different from the one computed by optimizefindnode
-            loop.specnodes = self.unpack_specnodes(spectext)
-        loop.token.specnodes = loop.specnodes
+            loop.token.specnodes = self.unpack_specnodes(spectext)
         #
         optimize_loop_1(self.cpu, loop)
         #

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/test/test_send.py	Wed Sep 30 13:15:23 2009
@@ -586,7 +586,27 @@
             self.check_loops(oosend=0)
         else:
             self.check_loops(call=0)
-        
+
+    def test_generalize_loop(self):
+        myjitdriver = JitDriver(greens=[], reds = ['i', 'obj'])
+        class A:
+            def __init__(self, n):
+                self.n = n
+        def extern(obj):
+            pass
+        def fn(i):
+            obj = A(1)
+            while i > 0:
+                myjitdriver.can_enter_jit(i=i, obj=obj)
+                myjitdriver.jit_merge_point(i=i, obj=obj)
+                obj = A(obj.n + 1)
+                if i < 10:
+                    extern(obj)
+                i -= 1
+            return obj.n
+        res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern))
+        assert res == 21
+
 
 class TestOOtype(SendTests, OOJitMixin):
     pass

Modified: pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/kill-jumptarget/pypy/jit/metainterp/warmspot.py	Wed Sep 30 13:15:23 2009
@@ -696,8 +696,8 @@
     #
     class MachineCodeEntryPoint(object):
         next = None    # linked list
-        def __init__(self, entry_executable_token, *greenargs):
-            self.entry_executable_token = entry_executable_token
+        def __init__(self, entry_loop_token, *greenargs):
+            self.entry_loop_token = entry_loop_token
             i = 0
             for name in green_args_names:
                 setattr(self, 'green_' + name, greenargs[i])
@@ -825,7 +825,7 @@
                     return
                 metainterp = MetaInterp(metainterp_sd)
                 try:
-                    executable_token = metainterp.compile_and_run_once(*args)
+                    loop_token = metainterp.compile_and_run_once(*args)
                 except warmrunnerdesc.ContinueRunningNormally:
                     # the trace got too long, reset the counter
                     self.mccounters[argshash] = 0
@@ -837,21 +837,20 @@
                 cell = self.mcentrypoints[argshash]
                 if not cell.equalkey(*greenargs):
                     # hash collision
-                    executable_token = self.handle_hash_collision(cell,
-                                                                  argshash,
-                                                                  *args)
-                    if executable_token is None:
+                    loop_token = self.handle_hash_collision(cell, argshash,
+                                                            *args)
+                    if loop_token is None:
                         return
                 else:
                     # get the assembler and fill in the boxes
                     cell.set_future_values(*args[num_green_args:])
-                    executable_token = cell.entry_executable_token
+                    loop_token = cell.entry_loop_token
             # ---------- execute assembler ----------
             while True:     # until interrupted by an exception
                 metainterp_sd.profiler.start_running()
-                fail_descr = metainterp_sd.cpu.execute_token(executable_token)
+                fail_descr = metainterp_sd.cpu.execute_token(loop_token)
                 metainterp_sd.profiler.end_running()
-                executable_token = fail_descr.handle_fail(metainterp_sd)
+                loop_token = fail_descr.handle_fail(metainterp_sd)
 
         maybe_compile_and_run._dont_inline_ = True
 
@@ -867,7 +866,7 @@
                     nextcell.next = firstcell
                     self.mcentrypoints[argshash] = nextcell
                     nextcell.set_future_values(*args[num_green_args:])
-                    return nextcell.entry_executable_token
+                    return nextcell.entry_loop_token
                 cell = nextcell
             # not found at all, do profiling
             counter = self.mccounters[argshash]
@@ -927,9 +926,9 @@
             key.counter = 0
 
         def attach_unoptimized_bridge_from_interp(self, greenkey,
-                                                  entry_executable_token):
+                                                  entry_loop_token):
             greenargs = self.unwrap_greenkey(greenkey)
-            newcell = MachineCodeEntryPoint(entry_executable_token, *greenargs)
+            newcell = MachineCodeEntryPoint(entry_loop_token, *greenargs)
             argshash = self.getkeyhash(*greenargs) & self.hashtablemask
             oldcell = self.mcentrypoints[argshash]
             newcell.next = oldcell     # link



More information about the Pypy-commit mailing list