[pypy-svn] r35752 - in pypy/dist/pypy/translator: cli cli/test oosupport

antocuni at codespeak.net antocuni at codespeak.net
Thu Dec 14 17:23:58 CET 2006


Author: antocuni
Date: Thu Dec 14 17:23:57 2006
New Revision: 35752

Added:
   pypy/dist/pypy/translator/cli/test/test_backendopt.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/cli/function.py
   pypy/dist/pypy/translator/cli/ilgenerator.py
   pypy/dist/pypy/translator/cli/test/runtest.py
   pypy/dist/pypy/translator/oosupport/function.py
Log:
Now gencli (partially) supports the graphs produced by merge_if_blocks.



Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py	(original)
+++ pypy/dist/pypy/translator/cli/function.py	Thu Dec 14 17:23:57 2006
@@ -5,6 +5,7 @@
 
 from pypy.objspace.flow import model as flowmodel
 from pypy.rpython.lltypesystem.lltype import Void
+from pypy.rpython.ootypesystem import ootype
 from pypy.translator.oosupport.function import Function as OOFunction
 from pypy.translator.cli.option import getoption
 from pypy.translator.cli.cts import CTS
@@ -203,6 +204,39 @@
             self.load(return_var)
         self.ilasm.opcode('ret')
 
+    def render_numeric_switch(self, block):
+        cases = {}
+        for link in block.exits:
+            if link.exitcase == "default":
+                default = link, self.next_label('switch')
+            else:
+                if block.exitswitch.concretetype in (ootype.Char, ootype.UniChar):
+                    value = ord(link.exitcase)
+                else:
+                    value = link.exitcase
+                assert value >= 0
+                cases[value] = link, self.next_label('switch')
+
+        max_case = max(cases.keys())
+        if max_case > 4096: # XXX: how to find a good way to determine whether to use switch?
+            raise NotImplementedError # TODO
+
+        targets = []
+        for i in xrange(max_case+1):
+            link, lbl = cases.get(i, default)
+            targets.append(lbl)
+        self.generator.load(block.exitswitch)
+        self.ilasm.switch(targets)
+        self.render_switch_case(*default)
+        for link, lbl in cases.itervalues():
+            self.render_switch_case(link, lbl)
+
+    def render_switch_case(self, link, label):
+        target_label = self._get_block_name(link.target)
+        self.set_label(label)
+        self._setup_link(link)
+        self.generator.branch_unconditionally(target_label)
+
     # Those parts of the generator interface that are function
     # specific
 

Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py	Thu Dec 14 17:23:57 2006
@@ -8,7 +8,7 @@
 from pypy.translator.cli.support import string_literal
 
 def isnan(v):
-        return v != v*1.0 or (v == 1.0 and v == 2.0)
+    return v != v*1.0 or (v == 1.0 and v == 2.0)
 
 def isinf(v):
     return v!=0 and (v == v*2)
@@ -211,6 +211,10 @@
     def load_local(self,v):
         self.opcode('ldloc', repr(v.name))
 
+    def switch(self, targets):
+        cmd = 'switch(%s)' % ', '.join(targets)
+        self.opcode(cmd)
+
     def load_const(self,type_,v):
         if type_ is Void:
             pass

Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py	Thu Dec 14 17:23:57 2006
@@ -9,6 +9,7 @@
 from pypy.rpython.lltypesystem.lltype import typeOf
 from pypy.rpython.ootypesystem import ootype
 from pypy.annotation.model import lltype_to_annotation
+from pypy.translator.backendopt.all import backend_optimizations
 
 from pypy.translator.cli.option import getoption
 from pypy.translator.cli.gencli import GenCli
@@ -134,15 +135,15 @@
             assert False, 'Input type %s not supported' % arg_type
 
 
-def compile_function(func, annotation=[], graph=None):
+def compile_function(func, annotation=[], graph=None, backend_opt={}):
     olddefs = patch()
-    gen = _build_gen(func, annotation, graph)
+    gen = _build_gen(func, annotation, graph, backend_opt)
     gen.generate_source()
     exe_name = gen.build_exe()
     unpatch(*olddefs) # restore original values
     return CliFunctionWrapper(exe_name)
 
-def _build_gen(func, annotation, graph=None):
+def _build_gen(func, annotation, graph=None, backend_opt={}):
     try: 
         func = func.im_func
     except AttributeError: 
@@ -162,7 +163,16 @@
        t.view()
 
     t.buildrtyper(type_system="ootype").specialize()
-    
+    backend_opt_default = dict(
+        raisingop2direct_call=False,
+        inline_threshold=0,
+        mallocs=False,
+        merge_if_blocks=False,
+        constfold=True,
+        heap2stack=False,
+        clever_malloc_removal=False)
+    backend_opt_default.update(backend_opt)
+    backend_optimizations(t, **backend_opt_default)
     
     main_graph = t.graphs[0]
 

Added: pypy/dist/pypy/translator/cli/test/test_backendopt.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/test/test_backendopt.py	Thu Dec 14 17:23:57 2006
@@ -0,0 +1,22 @@
+import py
+from pypy.translator.cli.test.runtest import compile_function
+from pypy.translator.c.test.test_backendoptimized import \
+     TestTypedOptimizedSwitchTestCase as c_TestTypedOptimizedSwitchTestCase
+
+class CTestCompat:
+    backend_opt = {
+        'merge_if_blocks': True
+        }
+
+    def CodeGenerator(self):
+        return self
+
+    def getcompiled(self, fn, annotation):
+        return compile_function(fn, annotation, backend_opt=self.backend_opt)
+
+class TestOptimizedSwitchTestCase(CTestCompat, c_TestTypedOptimizedSwitchTestCase):
+    def test_longlong_switch(self):
+        py.test.skip('Not yet supported')
+
+    def test_ulonglong_switch(self):
+        py.test.skip('Not yet supported')

Modified: pypy/dist/pypy/translator/oosupport/function.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/function.py	(original)
+++ pypy/dist/pypy/translator/oosupport/function.py	Thu Dec 14 17:23:57 2006
@@ -1,5 +1,5 @@
 from pypy.objspace.flow import model as flowmodel
-from pypy.rpython.ootypesystem.ootype import Void
+from pypy.rpython.ootypesystem import ootype
 from pypy.translator.oosupport.metavm import InstructionList
 
 class Function(object):
@@ -166,26 +166,42 @@
         raise NotImplementedError
             
     def render_normal_block(self, block):
-        # renders all ops but the last one
         for op in block.operations:
             self._render_op(op)
 
+        if block.exitswitch is None:
+            assert len(block.exits) == 1
+            link = block.exits[0]
+            target_label = self._get_block_name(link.target)
+            self._setup_link(link)
+            self.generator.branch_unconditionally(target_label)
+        elif block.exitswitch.concretetype is ootype.Bool:
+            self.render_bool_switch(block)
+        elif block.exitswitch.concretetype in (ootype.Signed, ootype.Unsigned, ootype.Char, ootype.UniChar):
+            self.render_numeric_switch(block)
+        else:
+            assert False, 'Unknonw exitswitch type: %s' % block.exitswitch.concretetype
+
+    def render_bool_switch(self, block):
         for link in block.exits:
             self._setup_link(link)
             target_label = self._get_block_name(link.target)
-            if link.exitcase is None or link is block.exits[-1]:
+            if link is block.exits[-1]:
                 self.generator.branch_unconditionally(target_label)
             else:
-                assert type(link.exitcase is bool)
+                assert type(link.exitcase) is bool
                 assert block.exitswitch is not None
                 self.generator.load(block.exitswitch)
                 self.generator.branch_conditionally(link.exitcase, target_label)
 
+    def render_numeric_switch(self, block):
+        raise NotImplementedError # it's too dependent on the backend to be implemented here
+
     def _setup_link(self, link):
         self.generator.add_comment("Setup link")
         target = link.target
         for to_load, to_store in zip(link.args, target.inputargs):
-            if to_load.concretetype is not Void:
+            if to_load.concretetype is not ootype.Void:
                 self.generator.add_comment("  to_load=%r to_store=%r" % (
                     to_load, to_store))
                 self.generator.load(to_load)
@@ -247,13 +263,13 @@
         seen = {}
         for v in mix:
             is_var = isinstance(v, flowmodel.Variable)
-            if id(v) not in seen and is_var and v.name not in args and v.concretetype is not Void:
+            if id(v) not in seen and is_var and v.name not in args and v.concretetype is not ootype.Void:
                 locals.append(self.cts.llvar_to_cts(v))
                 seen[id(v)] = True
 
         self.locals = locals
 
     def _set_args(self):
-        args = [arg for arg in self.graph.getargs() if arg.concretetype is not Void]
+        args = [arg for arg in self.graph.getargs() if arg.concretetype is not ootype.Void]
         self.args = map(self.cts.llvar_to_cts, args)
         self.argset = set([argname for argtype, argname in self.args])



More information about the Pypy-commit mailing list