[pypy-commit] pypy jit-targets: Rename ProcedureToken to JitCellToken. It now refers to all compiled traces starting from a specific JitCell and it is used as a decsr of jumps produced by the frontend to indicate the target of the jump. The optimizer will the convert this to a jump to a TargetToken (which refers to a specific label in an already compiled trace). If that is not yet possible it will be converted into a label resop with a new TargetTocken

hakanardo noreply at buildbot.pypy.org
Sun Nov 6 14:10:46 CET 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-targets
Changeset: r48821:cb3302d943c7
Date: 2011-11-06 14:09 +0100
http://bitbucket.org/pypy/pypy/changeset/cb3302d943c7/

Log:	Rename ProcedureToken to JitCellToken. It now refers to all compiled
	traces starting from a specific JitCell and it is used as a decsr of
	jumps produced by the frontend to indicate the target of the jump.
	The optimizer will the convert this to a jump to a TargetToken
	(which refers to a specific label in an already compiled trace). If
	that is not yet possible it will be converted into a label resop
	with a new TargetTocken

diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -9,7 +9,7 @@
 from pypy.tool.sourcetools import func_with_new_name
 
 from pypy.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist
-from pypy.jit.metainterp.history import TreeLoop, Box, History, ProcedureToken, TargetToken
+from pypy.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken
 from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
 from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const
 from pypy.jit.metainterp import history
@@ -47,7 +47,7 @@
 
 
 def make_procedure_token(jitdriver_sd):
-    procedure_token = ProcedureToken()
+    procedure_token = JitCellToken()
     procedure_token.outermost_jitdriver_sd = jitdriver_sd
     return procedure_token
 
@@ -68,7 +68,7 @@
             n = descr.index
             if n >= 0:       # we also record the resumedescr number
                 looptoken.compiled_loop_token.record_faildescr_index(n)
-        elif isinstance(descr, ProcedureToken):
+        elif isinstance(descr, JitCellToken):
             assert False, "FIXME"
         elif isinstance(descr, TargetToken):
             # for a JUMP or a CALL_ASSEMBLER: record it as a potential jump.
@@ -285,7 +285,7 @@
         raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
 
 
-class TerminatingLoopToken(ProcedureToken): # FIXME:!!
+class TerminatingLoopToken(JitCellToken): # FIXME: kill?
     terminating = True
 
     def __init__(self, nargs, finishdescr):
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -727,7 +727,7 @@
 # of operations.  Each branch ends in a jump which can go either to
 # the top of the same loop, or to another TreeLoop; or it ends in a FINISH.
 
-class ProcedureToken(AbstractDescr):
+class JitCellToken(AbstractDescr):
     """Used for rop.JUMP, giving the target of the jump.
     This is different from TreeLoop: the TreeLoop class contains the
     whole loop, including 'operations', and goes away after the loop
@@ -766,19 +766,22 @@
         self.compiled_loop_token.cpu.dump_loop_token(self)
 
 class TargetToken(AbstractDescr):
-    def __init__(self, procedure_token):
-        self.procedure_token = procedure_token
+    def __init__(self, cell_token):
+        self.cell_token = cell_token
         self.virtual_state = None
         self.exported_state = None
         
 class TreeLoop(object):
     inputargs = None
     operations = None
-    token = None
     call_pure_results = None
     logops = None
     quasi_immutable_deps = None
 
+    def _token(*args):
+        raise Exception("TreeLoop.token is killed")
+    token = property(_token, _token)
+
     def __init__(self, name):
         self.name = name
         # self.operations = list of ResOperations
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -7,7 +7,7 @@
 from pypy.jit.metainterp.optimizeopt import optimize_loop_1, ALL_OPTS_DICT, build_opt_chain
 from pypy.jit.metainterp.optimize import InvalidLoop
 from pypy.jit.metainterp.history import AbstractDescr, ConstInt, BoxInt
-from pypy.jit.metainterp.history import TreeLoop, ProcedureToken, TargetToken
+from pypy.jit.metainterp.history import TreeLoop, JitCellToken, TargetToken
 from pypy.jit.metainterp.jitprof import EmptyProfiler
 from pypy.jit.metainterp import executor, compile, resume, history
 from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
@@ -92,19 +92,22 @@
         preamble.inputargs = inputargs
         preamble.start_resumedescr = FakeDescr()
 
-        token = ProcedureToken() 
+        token = JitCellToken() 
         preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \
                               operations +  \
-                              [ResOperation(rop.LABEL, jump_args, None, descr=TargetToken(token))]
+                              [ResOperation(rop.JUMP, jump_args, None, descr=token)]
         self._do_optimize_loop(preamble, call_pure_results)
 
+        assert preamble.operations[-1].getopnum() == rop.LABEL
+
         inliner = Inliner(inputargs, jump_args)
         loop.start_resumedescr = preamble.start_resumedescr
         loop.operations = [preamble.operations[-1]] + \
                           [inliner.inline_op(op, clone=False) for op in cloned_operations] + \
-                          [ResOperation(rop.LABEL, [inliner.inline_arg(a) for a in jump_args],
-                                        None, descr=TargetToken(token))] 
+                          [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args],
+                                        None, descr=token)] 
                           #[inliner.inline_op(jumpop)]
+        assert loop.operations[-1].getopnum() == rop.JUMP
         assert loop.operations[0].getopnum() == rop.LABEL
         loop.inputargs = loop.operations[0].getarglist()
 
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -1,7 +1,7 @@
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder, ShortBoxes
 from pypy.jit.metainterp.compile import ResumeGuardDescr
-from pypy.jit.metainterp.history import TreeLoop, TargetToken
+from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken
 from pypy.jit.metainterp.jitexc import JitException
 from pypy.jit.metainterp.optimize import InvalidLoop, RetraceLoop
 from pypy.jit.metainterp.optimizeopt.optimizer import *
@@ -67,6 +67,7 @@
         loop = self.optimizer.loop
         self.optimizer.clear_newoperations()
 
+
         start_label = loop.operations[0]
         if start_label.getopnum() == rop.LABEL:
             loop.operations = loop.operations[1:]
@@ -75,39 +76,31 @@
             self.optimizer.send_extra_operation(start_label)
         else:
             start_label = None            
-        
-        stop_label = loop.operations[-1]
-        if stop_label.getopnum() == rop.LABEL:
-            loop.operations = loop.operations[:-1]
-        else:
-            stop_label = None
+
+        jumpop = loop.operations[-1]
+        assert jumpop.getopnum() == rop.JUMP
+        loop.operations = loop.operations[:-1]
 
         self.import_state(start_label)
         self.optimizer.propagate_all_forward(clear=False)
 
-        if not stop_label:
-            self.optimizer.flush()
-            loop.operations = self.optimizer.get_newoperations()
+        if self.jump_to_already_compiled_trace(jumpop):
             return
-        elif not start_label:
-            try:
-                self.optimizer.send_extra_operation(stop_label)
-            except RetraceLoop:
-                pass
-            else:
-                self.optimizer.flush()
-                loop.operations = self.optimizer.get_newoperations()
-                return
 
+        # Failed to find a compiled trace to jump to, produce a label instead
+        cell_token = jumpop.getdescr()
+        assert isinstance(cell_token, JitCellToken)
+        stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token))
+        
         if not self.did_peel_one: # Enforce the previous behaviour of always peeling  exactly one iteration (for now)
             self.optimizer.flush()
             KillHugeIntBounds(self.optimizer).apply()
 
             loop.operations = self.optimizer.get_newoperations()
             self.export_state(stop_label)
-            loop.operations.append(stop_label)
+            loop.operations.append(stop_label)            
         else:
-            assert stop_label.getdescr().procedure_token is start_label.getdescr().procedure_token
+            assert stop_label.getdescr().cell_token is start_label.getdescr().cell_token
             jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None, descr=start_label.getdescr())
 
             self.close_loop(jumpop)
@@ -430,8 +423,82 @@
         if box in self.optimizer.values:
             box = self.optimizer.values[box].force_box(self.optimizer)
         jumpargs.append(box)
+
+    def jump_to_already_compiled_trace(self, jumpop):
+        assert jumpop.getopnum() == rop.JUMP
+        cell_token = jumpop.getdescr()
+
+        assert isinstance(cell_token, JitCellToken)
+        if not cell_token.target_tokens:
+            return False
+
+        args = jumpop.getarglist()
+        modifier = VirtualStateAdder(self.optimizer)
+        virtual_state = modifier.get_virtual_state(args)
+        debug_start('jit-log-virtualstate')
+        virtual_state.debug_print("Looking for ")
+
+        for target in procedure_token.target_tokens:
+            if not target.virtual_state:
+                continue
+            ok = False
+            extra_guards = []
+
+            bad = {}
+            debugmsg = 'Did not match '
+            if target.virtual_state.generalization_of(virtual_state, bad):
+                ok = True
+                debugmsg = 'Matched '
+            else:
+                try:
+                    cpu = self.optimizer.cpu
+                    target.virtual_state.generate_guards(virtual_state,
+                                                         args, cpu,
+                                                         extra_guards)
+
+                    ok = True
+                    debugmsg = 'Guarded to match '
+                except InvalidLoop:
+                    pass
+            target.virtual_state.debug_print(debugmsg, bad)
+
+            if ok:
+                debug_stop('jit-log-virtualstate')
+
+                values = [self.getvalue(arg)
+                          for arg in jumpop.getarglist()]
+                args = target.virtual_state.make_inputargs(values, self.optimizer,
+                                                           keyboxes=True)
+                short_inputargs = target.short_preamble[0].getarglist()
+                inliner = Inliner(short_inputargs, args)
+
+                for guard in extra_guards:
+                    if guard.is_guard():
+                        descr = target.start_resumedescr.clone_if_mutable()
+                        inliner.inline_descr_inplace(descr)
+                        guard.setdescr(descr)
+                    self.emit_operation(guard)
+
+                try:
+                    for shop in target.short_preamble[1:]:
+                        newop = inliner.inline_op(shop)
+                        self.emit_operation(newop)
+                except InvalidLoop:
+                    debug_print("Inlining failed unexpectedly",
+                                "jumping to preamble instead")
+                    assert False, "FIXME: Construct jump op"
+                    self.emit_operation(op)
+                return True
+        debug_stop('jit-log-virtualstate')
+
+        retraced_count = procedure_token.retraced_count
+        limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
+        if not self.retraced and retraced_count<limit:
+            procedure_token.retraced_count += 1
+            return False
+
         
-
+# FIXME: kill
 class OptInlineShortPreamble(Optimization):
     def __init__(self, retraced):
         self.retraced = retraced
@@ -440,82 +507,6 @@
         return OptInlineShortPreamble(self.retraced)
 
     def propagate_forward(self, op):
-        if op.getopnum() == rop.JUMP:
-            self.emit_operation(op)
-            return
-        elif op.getopnum() == rop.LABEL:
-            target_token = op.getdescr()
-            assert isinstance(target_token, TargetToken)
-            procedure_token = target_token.procedure_token
-            if not procedure_token.target_tokens:
-                self.emit_operation(op)
-                return
-
-            args = op.getarglist()
-            modifier = VirtualStateAdder(self.optimizer)
-            virtual_state = modifier.get_virtual_state(args)
-            debug_start('jit-log-virtualstate')
-            virtual_state.debug_print("Looking for ")
-
-            for target in procedure_token.target_tokens:
-                if not target.virtual_state:
-                    continue
-                ok = False
-                extra_guards = []
-
-                bad = {}
-                debugmsg = 'Did not match '
-                if target.virtual_state.generalization_of(virtual_state, bad):
-                    ok = True
-                    debugmsg = 'Matched '
-                else:
-                    try:
-                        cpu = self.optimizer.cpu
-                        target.virtual_state.generate_guards(virtual_state,
-                                                             args, cpu,
-                                                             extra_guards)
-
-                        ok = True
-                        debugmsg = 'Guarded to match '
-                    except InvalidLoop:
-                        pass
-                target.virtual_state.debug_print(debugmsg, bad)
-
-                if ok:
-                    debug_stop('jit-log-virtualstate')
-
-                    values = [self.getvalue(arg)
-                              for arg in op.getarglist()]
-                    args = target.virtual_state.make_inputargs(values, self.optimizer,
-                                                               keyboxes=True)
-                    short_inputargs = target.short_preamble[0].getarglist()
-                    inliner = Inliner(short_inputargs, args)
-
-                    for guard in extra_guards:
-                        if guard.is_guard():
-                            descr = target.start_resumedescr.clone_if_mutable()
-                            inliner.inline_descr_inplace(descr)
-                            guard.setdescr(descr)
-                        self.emit_operation(guard)
-
-                    try:
-                        for shop in target.short_preamble[1:]:
-                            newop = inliner.inline_op(shop)
-                            self.emit_operation(newop)
-                    except InvalidLoop:
-                        debug_print("Inlining failed unexpectedly",
-                                    "jumping to preamble instead")
-                        assert False, "FIXME: Construct jump op"
-                        self.emit_operation(op)
-                    return
-            debug_stop('jit-log-virtualstate')
-            
-            retraced_count = procedure_token.retraced_count
-            limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
-            if not self.retraced and retraced_count<limit:
-                procedure_token.retraced_count += 1
-                raise RetraceLoop
-
             ## # We should not be failing much anymore...
             ##     if not procedure_token.failed_states:
             ##         debug_print("Retracing (%d of %d)" % (retraced_count,
@@ -535,7 +526,8 @@
             ##         loop_token.failed_states=[virtual_state]
             ##     else:
             ##         loop_token.failed_states.append(virtual_state)
-        self.emit_operation(op)
+            self.emit_operation(op)
+
 
 class ValueImporter(object):
     def __init__(self, unroll, value, op):
diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py
--- a/pypy/jit/metainterp/test/test_compile.py
+++ b/pypy/jit/metainterp/test/test_compile.py
@@ -1,5 +1,5 @@
 from pypy.config.pypyoption import get_pypy_config
-from pypy.jit.metainterp.history import ProcedureToken, TargetToken, ConstInt, History, Stats
+from pypy.jit.metainterp.history import TargetToken, ConstInt, History, Stats
 from pypy.jit.metainterp.history import BoxInt, INT
 from pypy.jit.metainterp.compile import insert_loop_token, compile_procedure
 from pypy.jit.metainterp.compile import ResumeGuardDescr
diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py
--- a/pypy/jit/tool/oparser.py
+++ b/pypy/jit/tool/oparser.py
@@ -70,7 +70,7 @@
         self.invent_fail_descr = invent_fail_descr
         self.nonstrict = nonstrict
         self.model = get_model(self.use_mock_model)
-        self.looptoken = self.model.ProcedureToken()
+        self.celltoken = self.model.JitCellToken()
 
     def get_const(self, name, typ):
         if self._consts is None:
@@ -243,7 +243,7 @@
                     descr = self.invent_fail_descr(self.model, fail_args)
             elif opnum == rop.JUMP:
                 if descr is None and self.invent_fail_descr:
-                    descr = self.looptoken
+                    descr = self.celltoken
         return opnum, args, descr, fail_args
 
     def create_op(self, opnum, args, result, descr):
@@ -307,7 +307,6 @@
             raise ParseError("unexpected dedent at line: %s" % newlines[num])
         loop = self.model.ExtendedTreeLoop("loop")
         loop.comment = first_comment
-        loop.token = self.looptoken
         loop.operations = ops
         loop.inputargs = inpargs
         loop.last_offset = last_offset
diff --git a/pypy/jit/tool/oparser_model.py b/pypy/jit/tool/oparser_model.py
--- a/pypy/jit/tool/oparser_model.py
+++ b/pypy/jit/tool/oparser_model.py
@@ -3,7 +3,7 @@
 
 def get_real_model():
     class LoopModel(object):
-        from pypy.jit.metainterp.history import TreeLoop, ProcedureToken
+        from pypy.jit.metainterp.history import TreeLoop, JitCellToken
         from pypy.jit.metainterp.history import Box, BoxInt, BoxFloat
         from pypy.jit.metainterp.history import ConstInt, ConstObj, ConstPtr, ConstFloat
         from pypy.jit.metainterp.history import BasicFailDescr


More information about the pypy-commit mailing list