[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