[pypy-svn] r69025 - in pypy/trunk/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Fri Nov 6 10:07:39 CET 2009


Author: arigo
Date: Fri Nov  6 10:07:38 2009
New Revision: 69025

Modified:
   pypy/trunk/pypy/jit/metainterp/optimizeopt.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
   pypy/trunk/pypy/jit/metainterp/resoperation.py
   pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/trunk/pypy/jit/metainterp/test/test_slist.py
Log:
Fix the "xxx inefficient" in pyjitpl by turning the guard_value
into guard_true or guard_false in optimizeopt.py.


Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py	Fri Nov  6 10:07:38 2009
@@ -367,6 +367,7 @@
         self.interned_refs = self.cpu.ts.new_ref_dict()
         self.resumedata_memo = resume.ResumeDataLoopMemo(self.cpu)
         self.heap_op_optimizer = HeapOpOptimizer(self)
+        self.bool_boxes = {}
 
     def forget_numberings(self, virtualbox):
         self.metainterp_sd.profiler.count(OPT_FORCINGS)
@@ -513,6 +514,8 @@
             self.store_final_boxes_in_guard(op)
         elif op.can_raise():
             self.exception_might_have_happened = True
+        elif op.returns_bool_result():
+            self.bool_boxes[op.result] = None
         self.newoperations.append(op)
 
     def store_final_boxes_in_guard(self, op):
@@ -566,6 +569,16 @@
     def optimize_GUARD_VALUE(self, op):
         constbox = op.args[1]
         assert isinstance(constbox, Const)
+        if op.args[0] in self.bool_boxes:
+            if constbox.value == 0:
+                opnum = rop.GUARD_FALSE
+            elif constbox.value == 1:
+                opnum = rop.GUARD_TRUE
+            else:
+                raise InvalidLoop
+            newop = ResOperation(opnum, [op.args[0]], None, op.descr)
+            newop.fail_args = op.fail_args
+            op = newop
         self.optimize_guard(op, constbox)
 
     def optimize_GUARD_TRUE(self, op):

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Fri Nov  6 10:07:38 2009
@@ -354,7 +354,6 @@
     def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
         negbox = self.metainterp.execute_and_record(
             rop.INT_LT, None, indexbox, ConstInt(0))
-        # xxx inefficient
         negbox = self.implement_guard_value(pc, negbox)
         if negbox.getint():
             # the index is < 0; add the array length to it
@@ -394,7 +393,6 @@
                                          indexbox):
         negbox = self.metainterp.execute_and_record(
             rop.INT_LT, None, indexbox, ConstInt(0))
-        # xxx inefficient
         negbox = self.implement_guard_value(pc, negbox)
         if negbox.getint():
             # the index is < 0; add the array length to it
@@ -408,7 +406,6 @@
     def opimpl_check_zerodivisionerror(self, pc, box):
         nonzerobox = self.metainterp.execute_and_record(
             rop.INT_NE, None, box, ConstInt(0))
-        # xxx inefficient
         nonzerobox = self.implement_guard_value(pc, nonzerobox)
         if nonzerobox.getint():
             return False
@@ -426,7 +423,6 @@
             rop.INT_AND, None, tmp1, box2)                    # tmp2=-1
         tmp3 = self.metainterp.execute_and_record(
             rop.INT_EQ, None, tmp2, ConstInt(-1))             # tmp3?
-        # xxx inefficient
         tmp4 = self.implement_guard_value(pc, tmp3)       # tmp4?
         if not tmp4.getint():
             return False
@@ -442,7 +438,6 @@
     def opimpl_int_abs(self, pc, box):
         nonneg = self.metainterp.execute_and_record(
             rop.INT_GE, None, box, ConstInt(0))
-        # xxx inefficient
         nonneg = self.implement_guard_value(pc, nonneg)
         if nonneg.getint():
             self.make_result_box(box)

Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/resoperation.py	Fri Nov  6 10:07:38 2009
@@ -93,6 +93,14 @@
     def is_final(self):
         return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST
 
+    def returns_bool_result(self):
+        opnum = self.opnum
+        if we_are_translated():
+            assert opnum >= 0
+        elif opnum < 0:
+            return False     # for tests
+        return opboolresult[opnum]
+
 # ____________________________________________________________
 
 _oplist = [
@@ -137,40 +145,40 @@
     'FLOAT_TRUEDIV/2',
     'FLOAT_NEG/1',
     'FLOAT_ABS/1',
-    'FLOAT_IS_TRUE/1',
+    'FLOAT_IS_TRUE/1b',
     'CAST_FLOAT_TO_INT/1',
     'CAST_INT_TO_FLOAT/1',
     #
     '_COMPARISON_FIRST',
-    'INT_LT/2',
-    'INT_LE/2',
-    'INT_EQ/2',
-    'INT_NE/2',
-    'INT_GT/2',
-    'INT_GE/2',
-    'UINT_LT/2',
-    'UINT_LE/2',
-    'UINT_GT/2',
-    'UINT_GE/2',
+    'INT_LT/2b',
+    'INT_LE/2b',
+    'INT_EQ/2b',
+    'INT_NE/2b',
+    'INT_GT/2b',
+    'INT_GE/2b',
+    'UINT_LT/2b',
+    'UINT_LE/2b',
+    'UINT_GT/2b',
+    'UINT_GE/2b',
     '_COMPARISON_LAST',
-    'FLOAT_LT/2',          # maybe these ones should be comparisons too
-    'FLOAT_LE/2',
-    'FLOAT_EQ/2',
-    'FLOAT_NE/2',
-    'FLOAT_GT/2',
-    'FLOAT_GE/2',
+    'FLOAT_LT/2b',          # maybe these ones should be comparisons too
+    'FLOAT_LE/2b',
+    'FLOAT_EQ/2b',
+    'FLOAT_NE/2b',
+    'FLOAT_GT/2b',
+    'FLOAT_GE/2b',
     #
-    'INT_IS_TRUE/1',
+    'INT_IS_TRUE/1b',
     'INT_NEG/1',
     'INT_INVERT/1',
-    'BOOL_NOT/1',
+    'BOOL_NOT/1b',
     #
     'SAME_AS/1',      # gets a Const, turns it into a Box
     #
-    'OONONNULL/1',
-    'OOISNULL/1',
-    'OOIS/2',
-    'OOISNOT/2',
+    'OONONNULL/1b',
+    'OOISNULL/1b',
+    'OOIS/2b',
+    'OOISNOT/2b',
     #
     'ARRAYLEN_GC/1d',
     'STRLEN/1',
@@ -182,8 +190,8 @@
     'UNICODEGETITEM/2',
     #
     # ootype operations
-    'INSTANCEOF/1d',
-    'SUBCLASSOF/2',
+    'INSTANCEOF/1db',
+    'SUBCLASSOF/2b',
     #
     '_ALWAYS_PURE_LAST',  # ----- end of always_pure operations -----
 
@@ -231,6 +239,7 @@
 opname = {}      # mapping numbers to the original names, for debugging
 oparity = []     # mapping numbers to the arity of the operation or -1
 opwithdescr = [] # mapping numbers to a flag "takes a descr"
+opboolresult= [] # mapping numbers to a flag "returns a boolean"
 
 
 def setup(debug_print=False):
@@ -239,16 +248,18 @@
             print '%30s = %d' % (name, i)
         if '/' in name:
             name, arity = name.split('/')
-            withdescr = arity.endswith('d')
-            arity = int(arity.rstrip('d'))
+            withdescr = 'd' in arity
+            boolresult = 'b' in arity
+            arity = int(arity.rstrip('db'))
         else:
-            arity, withdescr = -1, True       # default
+            arity, withdescr, boolresult = -1, True, False       # default
         setattr(rop, name, i)
         if not name.startswith('_'):
             opname[i] = name
         oparity.append(arity)
         opwithdescr.append(withdescr)
-    assert len(oparity) == len(opwithdescr) == len(_oplist)
+        opboolresult.append(boolresult)
+    assert len(oparity)==len(opwithdescr)==len(opboolresult)==len(_oplist)
 
 setup(__name__ == '__main__')   # print out the table when run directly
 del _oplist

Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	Fri Nov  6 10:07:38 2009
@@ -524,6 +524,45 @@
         """
         self.optimize_loop(ops, '', ops)
 
+    def test_guard_value_to_guard_true(self):
+        ops = """
+        [i]
+        i1 = int_lt(i, 3)
+        guard_value(i1, 1) [i]
+        jump(i)
+        """
+        expected = """
+        [i]
+        i1 = int_lt(i, 3)
+        guard_true(i1) [i]
+        jump(i)
+        """
+        self.optimize_loop(ops, 'Not', expected)
+
+    def test_guard_value_to_guard_false(self):
+        ops = """
+        [p]
+        i1 = ooisnull(p)
+        guard_value(i1, 0) [p]
+        jump(p)
+        """
+        expected = """
+        [p]
+        i1 = ooisnull(p)
+        guard_false(i1) [p]
+        jump(p)
+        """
+        self.optimize_loop(ops, 'Not', expected)
+
+    def test_guard_value_on_nonbool(self):
+        ops = """
+        [i]
+        i1 = int_add(i, 3)
+        guard_value(i1, 0) [i]
+        jump(i)
+        """
+        self.optimize_loop(ops, 'Not', ops)
+
 
     def test_p123_simple(self):
         ops = """

Modified: pypy/trunk/pypy/jit/metainterp/test/test_slist.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_slist.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_slist.py	Fri Nov  6 10:07:38 2009
@@ -82,13 +82,20 @@
         self.check_loops(call=0)
 
     def test_getitem_neg(self):
+        myjitdriver = JitDriver(greens = [], reds = ['i', 'n'])
         def f(n):
-            lst = [41]
-            lst.append(42)
-            return lst[n]
-        res = self.interp_operations(f, [-2], listops=True)
+            x = i = 0
+            while i < 10:
+                myjitdriver.can_enter_jit(n=n, i=i)
+                myjitdriver.jit_merge_point(n=n, i=i)
+                lst = [41]
+                lst.append(42)
+                x = lst[n]
+                i += 1
+            return x
+        res = self.meta_interp(f, [-2], listops=True)
         assert res == 41
-        self.check_history_(call=1)
+        self.check_loops(call=1, guard_value=0)
 
 # we don't support resizable lists on ootype
 #class TestOOtype(ListTests, OOJitMixin):



More information about the Pypy-commit mailing list