[pypy-svn] r22918 - in pypy/dist/pypy/translator/backendopt: . test

ericvrp at codespeak.net ericvrp at codespeak.net
Wed Feb 1 12:16:15 CET 2006


Author: ericvrp
Date: Wed Feb  1 12:16:10 2006
New Revision: 22918

Modified:
   pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
   pypy/dist/pypy/translator/backendopt/support.py
   pypy/dist/pypy/translator/backendopt/test/test_all.py
Log:
* Added test for idempotentness of transformations.
* Refactored raisingop2direct_call a little


Modified: pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py	(original)
+++ pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py	Wed Feb  1 12:16:10 2006
@@ -10,24 +10,45 @@
     note: this could be extended to allow for any operation to be changed into
           a direct_call to a (RPython) function!
     """
-    seen = {}
-    for op in all_operations(translator):
+    #special_operations = "int_floordiv int_mod".split()
+
+    def is_raisingop(op):
         s = op.opname
         if not s.startswith('int_') and not s.startswith('uint_') and not s.startswith('float_'):
+           return False
+        if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'): #not s in special_operations:
+           return False
+        return True
+    
+    seen = {}
+    for op in all_operations(translator):
+        if not is_raisingop(op):
             continue
-        if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val') and \
-           not s in ('int_floordiv', 'int_mod'):
-            continue
-        func = getattr(pypy.rpython.raisingops.raisingops, s, None)
-        assert func, "exception raising operation %s was not found" % s
-        if s not in seen:
-            seen[s] = 0
-            log.info(s)
-        seen[s] += 1
+        func = getattr(pypy.rpython.raisingops.raisingops, op.opname, None)
+        assert func, "exception raising operation %s was not found" % op.opname
+        if op.opname not in seen:
+            seen[op.opname] = 0
+        seen[op.opname] += 1
         op.args.insert(0, annotate(translator, func, op.result, op.args))
         op.opname = 'direct_call'
+
+    #statistics...
     for k, v in seen.iteritems():
-        log("%4dx %s" % (v, k))
+        log.info("%dx %s" % (v, k))
+
+    #specialize newly annotated functions
     if seen != {}:
         translator.rtyper.specialize_more_blocks()
+
+    #rename some operations (that were introduced in the newly specialized graphs)
+    #so this transformation becomes idempotent... 
+    #for op in all_operations(translator):
+    #   if op.opname in special_operations:
+    #       log('renamed %s to %s_' % (op.opname, op.opname))
+    #       op.opname += '_' 
+
+    #selfdiagnostics... assert that there are no more raisingops
+    for op in all_operations(translator):
+        assert not is_raisingop(op)
+
     #translator.view()

Modified: pypy/dist/pypy/translator/backendopt/support.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/support.py	(original)
+++ pypy/dist/pypy/translator/backendopt/support.py	Wed Feb  1 12:16:10 2006
@@ -23,3 +23,12 @@
     fptr   = functionptr(FuncType(args, result.concretetype), func.func_name, graph=graph)
     c      = inputconst(typeOf(fptr), fptr) 
     return c
+
+def md5digest(translator):
+    import md5
+    m = md5.new()
+    for op in all_operations(translator):
+        m.update(op.opname + str(op.result))
+        for a in op.args:
+            m.update(str(a))
+    return m.digest()[:]

Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py	Wed Feb  1 12:16:10 2006
@@ -1,5 +1,6 @@
 import py
 from pypy.translator.backendopt.all import backend_optimizations
+from pypy.translator.backendopt.support import md5digest
 from pypy.translator.backendopt.test.test_malloc import check_malloc_removed
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.objspace.flow.model import Constant
@@ -56,7 +57,6 @@
     assert res == 83
 
 
-
 def test_for_loop():
     def f(n):
         total = 0
@@ -89,6 +89,7 @@
     res = interp.eval_graph(f_graph, [11, 22])
     assert res == 33
 
+
 def test_premature_death():
     import os
     from pypy.annotation import listdef
@@ -120,7 +121,32 @@
     interp = LLInterpreter(t.rtyper)
     interp.eval_graph(entry_point_graph, [argv])
 
-    
 
+def test_idempotent():
+    def s(x):
+        res = 0
+        i = 1
+        while i <= x:
+            res += i
+            i += 1
+        return res
+
+    def g(x):
+        return s(100) + s(1) + x 
+
+    def idempotent(n1, n2):
+        c = [i for i in range(n2)]
+        return 33 + big() + g(10)
+
+    t  = translateopt(idempotent, [int, int], raisingop2direct_call_all=True)
+    digest1 = md5digest(t)
+
+    digest2 = md5digest(t)
+    assert digest1 == digest2
+
+    #XXX Inlining is currently non-idempotent.
+    #    Maybe it just renames variables but it changes the graph in some way.
+    backend_optimizations(t, raisingop2direct_call_all=True, inline_threshold=0)
+    digest3 = md5digest(t)
+    assert digest1 == digest3
 
- 



More information about the Pypy-commit mailing list