[pypy-svn] r33169 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Wed Oct 11 16:12:59 CEST 2006
Author: cfbolz
Date: Wed Oct 11 16:12:57 2006
New Revision: 33169
Modified:
pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
pypy/dist/pypy/translator/backendopt/test/test_all.py
pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
Log:
fix a bug in merge_if_blocks: if two of the checked values are the same, then
checkgraph complains. In this case drop the additional block.
Modified: pypy/dist/pypy/translator/backendopt/merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/merge_if_blocks.py (original)
+++ pypy/dist/pypy/translator/backendopt/merge_if_blocks.py Wed Oct 11 16:12:57 2006
@@ -20,7 +20,7 @@
return False
return True
-def merge_chain(chain, checkvar, varmap):
+def merge_chain(chain, checkvar, varmap, graph):
def get_new_arg(var_or_const):
if isinstance(var_or_const, Constant):
return var_or_const
@@ -28,6 +28,7 @@
firstblock, case = chain[0]
firstblock.operations = firstblock.operations[:-1]
firstblock.exitswitch = checkvar
+ values = {}
links = []
default = chain[-1][0].exits[0]
default.exitcase = "default"
@@ -35,6 +36,11 @@
default.prevblock = firstblock
default.args = [get_new_arg(arg) for arg in default.args]
for block, case in chain:
+ if case.value in values:
+ log.WARNING("unreachable code with value %s in graph %s" % (
+ case.value, graph))
+ continue
+ values[case.value] = True
link = block.exits[1]
links.append(link)
link.exitcase = case.value
@@ -97,11 +103,13 @@
break
else:
return False
- log("merging blocks in %s" % (graph.name, ))
- merge_chain(chain, checkvars[0], varmap)
+ merge_chain(chain, checkvars[0], varmap, graph)
checkgraph(graph)
return True
def merge_if_blocks(graph):
+ merge = False
while merge_if_blocks_once(graph):
- pass
+ merge = True
+ if merge:
+ log("merging blocks in %s" % (graph.name, ))
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 Oct 11 16:12:57 2006
@@ -6,11 +6,15 @@
from pypy.objspace.flow.model import Constant
from pypy.annotation import model as annmodel
from pypy.rpython.llinterp import LLInterpreter
+from pypy.rpython.rarithmetic import intmask
+from pypy import conftest
def translateopt(func, sig, **optflags):
t = TranslationContext()
t.buildannotator().build_types(func, sig)
t.buildrtyper().specialize()
+ if conftest.option.view:
+ t.view()
backend_optimizations(t, **optflags)
return t
@@ -166,3 +170,23 @@
interp = LLInterpreter(t.rtyper)
res = interp.eval_graph(graphof(t, myfunc), [10])
assert res == 5
+
+def test_range_iter():
+ def fn(start, stop, step):
+ res = 0
+ if step == 0:
+ if stop >= start:
+ r = range(start, stop, 1)
+ else:
+ r = range(start, stop, -1)
+ else:
+ r = range(start, stop, step)
+ for i in r:
+ res = res * 51 + i
+ return res
+ t = translateopt(fn, [int, int, int], merge_if_blocks_to_switch=True)
+ interp = LLInterpreter(t.rtyper)
+ for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
+ assert interp.eval_graph(graphof(t, fn), args) == intmask(fn(*args))
+
+
Modified: pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_merge_if_blocks.py Wed Oct 11 16:12:57 2006
@@ -160,3 +160,26 @@
merge_if_blocks(graph)
assert blocknum == len(list(graph.iterblocks()))
+def test_same_cases():
+ def fn(x):
+ if x == 42:
+ r = 1
+ elif x == 42:
+ r = 2
+ else:
+ r = 3
+ return r
+ t = TranslationContext()
+ a = t.buildannotator()
+ a.build_types(fn, [int])
+ rtyper = t.buildrtyper()
+ rtyper.specialize()
+ backend_optimizations(t, merge_if_blocks_to_switch=True)
+ graph = tgraphof(t, fn)
+ assert len(graph.startblock.exits) == 2
+ interp = LLInterpreter(rtyper)
+ for i in [42, 43]:
+ expected = fn(i)
+ actual = interp.eval_graph(graph, [i])
+ assert actual == expected
+
More information about the Pypy-commit
mailing list