[pypy-svn] r63453 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Tue Mar 31 17:44:49 CEST 2009


Author: arigo
Date: Tue Mar 31 17:44:47 2009
New Revision: 63453

Modified:
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
Log:
This is a partial revert of r63074.

Instead of making the liveboxes list as compact as possible for
each of the true and false cases, generate a single livebox list
for both cases.  This is needed for the following checkin.



Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py	Tue Mar 31 17:44:47 2009
@@ -263,9 +263,6 @@
 
     def make_bytecode_block(self, block):
         if block.exits == ():
-            # note: the same label might be generated multiple times, but a
-            # jump to this label is free to pick whichever target so it's fine
-            self.emit(label(block))
             if len(block.inputargs) == 1:
                 # return from function
                 returnvar, = block.inputargs
@@ -322,16 +319,19 @@
             linkfalse, linktrue = block.exits
             if linkfalse.llexitcase == True:
                 linkfalse, linktrue = linktrue, linkfalse
-            truelist = self.get_renaming_list(linktrue.args)
-            falselist = self.get_renaming_list(linkfalse.args)
             self.emit("goto_if_not",
-                      self.var_position(block.exitswitch),
-                      tlabel(linkfalse.target))
-            self.emit(len(truelist), *truelist)
-            self.emit(len(falselist), *falselist)
+                      tlabel(linkfalse),
+                      self.var_position(block.exitswitch))
+            self.minimize_variables(argument_only=True, exitswitch=False)
+            truerenaming = self.insert_renaming(linktrue.args)
+            falserenaming = self.insert_renaming(linkfalse.args)
+            # true path:
+            self.emit(*truerenaming)
             self.make_bytecode_block(linktrue.target)
-            if linkfalse.target not in self.seen_blocks:
-                self.make_bytecode_block(linkfalse.target)
+            # false path:
+            self.emit(label(linkfalse))
+            self.emit(*falserenaming)
+            self.make_bytecode_block(linkfalse.target)
         else:
             self.minimize_variables()
             switches = [link for link in block.exits
@@ -426,11 +426,12 @@
         else:
             return ["make_new_vars_%d" % len(list)] + list
 
-    def minimize_variables(self):
+    def minimize_variables(self, argument_only=False, exitswitch=True):
         if self.dont_minimize_variables:
+            assert not argument_only
             return
         block, index = self.current_position
-        allvars = self.vars_alive_through_op(block, index)
+        allvars = self.vars_alive_through_op(block, index, exitswitch)
         seen = {}       # {position: unique Variable} without Voids
         unique = {}     # {Variable: unique Variable} without Voids
         for v in allvars:
@@ -441,7 +442,12 @@
         vars = seen.items()
         vars.sort()
         vars = [v1 for pos, v1 in vars]
-        self.emit(*self.insert_renaming(vars))
+        if argument_only:
+            # only generate the list of vars as an arg in a complex operation
+            renaming_list = self.get_renaming_list(vars)
+            self.emit(len(renaming_list), *renaming_list)
+        else:
+            self.emit(*self.insert_renaming(vars))
         self.free_vars = 0
         self.var_positions.clear()
         for v1 in vars:
@@ -449,7 +455,7 @@
         for v, v1 in unique.items():
             self.var_positions[v] = self.var_positions[v1]
 
-    def vars_alive_through_op(self, block, index):
+    def vars_alive_through_op(self, block, index, include_exitswitch=True):
         """Returns the list of variables that are really used by or after
         the operation at 'index'.
         """
@@ -468,7 +474,8 @@
         for op in block.operations[index:]:
             for v in op.args:
                 see(v)
-        see(block.exitswitch)
+        if include_exitswitch:
+            see(block.exitswitch)
         for link in block.exits:
             for v in link.args:
                 if v not in (link.last_exception, link.last_exc_value):

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	Tue Mar 31 17:44:47 2009
@@ -176,6 +176,11 @@
         count = self.load_int()
         return [self.load_const_arg() for i in range(count)]
 
+    def ignore_varargs(self):
+        count = self.load_int()
+        for i in range(count):
+            self.load_int()
+
     def getvarenv(self, i):
         return self.env[i]
 
@@ -279,25 +284,27 @@
     def opimpl_goto(self, target):
         self.pc = target
 
-    @arguments("box", "jumptarget", "varargs", "varargs")
-    def opimpl_goto_if_not(self, box, target, truelist, falselist):
+    @arguments("orgpc", "jumptarget", "box", "varargs")
+    def opimpl_goto_if_not(self, pc, target, box, livelist):
         switchcase = box.getint()
         if switchcase:
-            currentpc = self.pc
-            currentenv = truelist
-            targetpc = target
-            targetenv = falselist
             opnum = rop.GUARD_TRUE
         else:
-            currentpc = target
-            currentenv = falselist
-            targetpc = self.pc
-            targetenv = truelist
+            self.pc = target
             opnum = rop.GUARD_FALSE
-        self.env = targetenv
-        self.generate_guard(targetpc, opnum, box)
-        self.pc = currentpc
-        self.env = currentenv
+        self.env = livelist
+        self.generate_guard(pc, opnum, box)
+
+    def follow_jump(self):
+        self.pc += 1          # past the bytecode for 'goto_if_not'
+        target = self.load_3byte()  # load the 'target' argument
+        self.pc = target      # jump
+
+    def dont_follow_jump(self):
+        self.pc += 1          # past the bytecode for 'goto_if_not'
+        self.load_3byte()     # past the 'target' argument
+        self.load_int()       # past the 'box' argument
+        self.ignore_varargs() # past the 'livelist' argument
 
     @arguments("orgpc", "box", "constargs", "jumptargets")
     def opimpl_switch(self, pc, valuebox, constargs, jumptargets):
@@ -847,9 +854,7 @@
         self.initialize_state_from_guard_failure(guard_failure)
         key = guard_failure.key
         try:
-            if key.guard_op.opnum in (rop.GUARD_NO_EXCEPTION,
-                                      rop.GUARD_EXCEPTION):
-                self.handle_exception()
+            self.prepare_resume_from_failure(key.guard_op.opnum)
             self.interpret()
             assert False, "should always raise"
         except GenerateMergePoint, gmp:
@@ -866,6 +871,14 @@
                                                gmp.argboxes[num_green_args:])
         return (loop, residual_args)
 
+    def prepare_resume_from_failure(self, opnum):
+        if opnum == rop.GUARD_TRUE:     # a goto_if_not that fails only now
+            self.framestack[-1].follow_jump()
+        elif opnum == rop.GUARD_FALSE:     # a goto_if_not that stops failing
+            self.framestack[-1].dont_follow_jump()
+        elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
+            self.handle_exception()
+
     def compile(self, original_boxes, live_arg_boxes):
         num_green_args = self.num_green_args
         for i in range(num_green_args):

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py	Tue Mar 31 17:44:47 2009
@@ -152,8 +152,9 @@
             for op in get_stats().loops[0]._all_operations():
                 if op.getopname() == 'fail':
                     liveboxes = op.args
-                    assert len(liveboxes) == 1
-                    assert isinstance(liveboxes[0], history.BoxInt)
+                    assert len(liveboxes) == 3
+                    for box in liveboxes:
+                        assert isinstance(box, history.BoxInt)
                     found += 1
             assert found == 1
 



More information about the Pypy-commit mailing list