[pypy-svn] r22730 - in pypy/dist/pypy: rpython/raisingops translator/backendopt translator/c/test

ericvrp at codespeak.net ericvrp at codespeak.net
Fri Jan 27 14:07:25 CET 2006


Author: ericvrp
Date: Fri Jan 27 14:07:21 2006
New Revision: 22730

Added:
   pypy/dist/pypy/rpython/raisingops/
   pypy/dist/pypy/rpython/raisingops/__init__.py
   pypy/dist/pypy/rpython/raisingops/raisingops.py
   pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
Modified:
   pypy/dist/pypy/translator/backendopt/all.py
   pypy/dist/pypy/translator/backendopt/support.py
   pypy/dist/pypy/translator/c/test/test_backendoptimized.py
Log:
WIP for exception raising operations to direct_call transformation


Added: pypy/dist/pypy/rpython/raisingops/__init__.py
==============================================================================

Added: pypy/dist/pypy/rpython/raisingops/raisingops.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/raisingops/raisingops.py	Fri Jan 27 14:07:21 2006
@@ -0,0 +1,26 @@
+from pypy.rpython.rarithmetic import r_longlong
+
+def _pypyop_divmod_adj(x, y, p_rem=None):
+  xdivy = r_longlong(x / y)
+  xmody = r_longlong(x - xdivy * y)
+  
+  # If the signs of x and y differ, and the remainder is non-0,
+  # C89 doesn't define whether xdivy is now the floor or the
+  # ceiling of the infinitely precise quotient.  We want the floor,
+  # and we have it iff the remainder's sign matches y's.
+  if xmody and ((y ^ xmody) < 0):
+  
+    xmody += y
+    xdivy -= 1
+    assert xmody and ((y ^ xmody) >= 0)
+
+  #XXX was a pointer
+  # if p_rem
+  #  p_rem = xmody;
+  return xdivy
+
+def int_floordiv_zer(x,y):
+  if y:
+    return _pypyop_divmod_adj(x, y)
+  else:
+    raise ZeroDivisionError("integer division")

Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/all.py	Fri Jan 27 14:07:21 2006
@@ -1,3 +1,4 @@
+from pypy.translator.backendopt.raisingop2direct_call import raisingop2direct_call
 from pypy.translator.backendopt.removenoops import remove_same_as
 from pypy.translator.backendopt.inline import auto_inlining
 from pypy.translator.backendopt.malloc import remove_simple_mallocs
@@ -5,13 +6,20 @@
 from pypy.translator.backendopt.propagate import propagate_all
 from pypy.translator.backendopt.merge_if_blocks import merge_if_blocks
 from pypy.translator import simplify
+from pypy.translator.backendopt.escape import malloc_to_stack
 
 
-def backend_optimizations(translator, inline_threshold=1,
+def backend_optimizations(translator, raisingop2direct_call_all=False,
+                                      inline_threshold=1,
                                       mallocs=True,
                                       ssa_form=True,
                                       merge_if_blocks_to_switch=True,
-                                      propagate=False):
+                                      propagate=False,
+                                      heap2stack=False):
+
+    if raisingop2direct_call_all:
+        raisingop2direct_call(translator)
+
     # remove obvious no-ops
     for graph in translator.graphs:
         remove_same_as(graph)
@@ -37,6 +45,9 @@
     if propagate:
         propagate_all(translator)
 
+    if heap2stack:
+        malloc_to_stack(translator)
+
     if merge_if_blocks_to_switch:
         for graph in translator.graphs:
             merge_if_blocks(graph)

Added: pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py	Fri Jan 27 14:07:21 2006
@@ -0,0 +1,19 @@
+from pypy.objspace.flow.model import Block, Constant, flatten
+from pypy.translator.backendopt.support import log, all_operations
+import pypy.rpython.raisingops
+log = log.raisingop2directcall
+
+def raisingop2direct_call(translator):
+    """search for operations that could raise an exception and change that
+    operation into a direct_call to a function from the raisingops directory.
+    This function also needs to be annotated.
+    """
+    for op in all_operations(translator):
+        s = op.opname
+        if not s.startswith('int_') and not s.startswith('uint_') and not s.startswith('float_'):
+            continue
+        if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'):
+            continue
+        log(s)
+        op.args.insert(0, s)
+        op.opname = 'direct_call'

Modified: pypy/dist/pypy/translator/backendopt/support.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/support.py	(original)
+++ pypy/dist/pypy/translator/backendopt/support.py	Fri Jan 27 14:07:21 2006
@@ -4,3 +4,14 @@
 from pypy.tool.ansi_print import ansi_log
 log = py.log.Producer("backendopt")
 py.log.setconsumer("backendopt", ansi_log)
+
+def graph_operations(graph):
+    for block in graph.iterblocks():
+        for op in block.operations: 
+            yield op
+
+def all_operations(translator):
+    for graph in translator.graphs:
+        for block in graph.iterblocks():
+            for op in block.operations: 
+                yield op

Modified: pypy/dist/pypy/translator/c/test/test_backendoptimized.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_backendoptimized.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_backendoptimized.py	Fri Jan 27 14:07:21 2006
@@ -1,4 +1,4 @@
-import autopath
+import py
 from pypy.translator.c.test.test_typed import TestTypedTestCase as _TestTypedTestCase
 from pypy.translator.backendopt.all import backend_optimizations
 from pypy.rpython import objectmodel
@@ -174,3 +174,23 @@
             y = ord(x)
             assert fn(y) == f(y)
 
+class TestTypedOptimizedRaisingOps:
+
+    class CodeGenerator(_TestTypedTestCase):
+        def process(self, t):
+            _TestTypedTestCase.process(self, t)
+            self.t = t
+            backend_optimizations(t, raisingop2direct_call_all=True)
+
+    def test_int_floordiv_zer(self):
+        py.test.skip("WIP")
+        def f(x=int):
+            try:
+                y = 123 / x
+            except:
+                y = 456
+            return y
+        codegenerator = self.CodeGenerator()
+        fn = codegenerator.getcompiled(f)
+        for x in (0,1,2,3,9,27,48, -9):
+            assert fn(x) == f(x)



More information about the Pypy-commit mailing list