[pypy-svn] r25488 - in pypy/dist/pypy/translator/backendopt: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri Apr 7 12:20:03 CEST 2006
Author: cfbolz
Date: Fri Apr 7 12:20:02 2006
New Revision: 25488
Modified:
pypy/dist/pypy/translator/backendopt/propagate.py
pypy/dist/pypy/translator/backendopt/removenoops.py
pypy/dist/pypy/translator/backendopt/test/test_propagate.py
pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
Log:
add an transformation that removes superfluous keepalives. move some stuff from
propagate to removenoops
Modified: pypy/dist/pypy/translator/backendopt/propagate.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/propagate.py (original)
+++ pypy/dist/pypy/translator/backendopt/propagate.py Fri Apr 7 12:20:02 2006
@@ -249,56 +249,6 @@
else:
return False
-def remove_duplicate_casts(graph, translator):
- simplify.join_blocks(graph)
- num_removed = 0
- # remove chains of casts
- for block in graph.iterblocks():
- comes_from = {}
- for op in block.operations:
- if op.opname == "cast_pointer":
- if op.args[0] in comes_from:
- from_var = comes_from[op.args[0]]
- comes_from[op.result] = from_var
- if from_var.concretetype == op.result.concretetype:
- op.opname = "same_as"
- op.args = [from_var]
- num_removed += 1
- else:
- op.args = [from_var]
- else:
- comes_from[op.result] = op.args[0]
- if num_removed:
- remove_same_as(graph)
- # remove duplicate casts
- for block in graph.iterblocks():
- available = {}
- for op in block.operations:
- if op.opname == "cast_pointer":
- key = (op.args[0], op.result.concretetype)
- if key in available:
- op.opname = "same_as"
- op.args = [available[key]]
- num_removed += 1
- else:
- available[key] = op.result
- if num_removed:
- remove_same_as(graph)
- # remove casts with unused results
- for block in graph.iterblocks():
- used = {}
- for link in block.exits:
- for arg in link.args:
- used[arg] = True
- for i, op in list(enumerate(block.operations))[::-1]:
- if op.opname == "cast_pointer" and op.result not in used:
- del block.operations[i]
- num_removed += 1
- else:
- for arg in op.args:
- used[arg] = True
- print "removed %s cast_pointers in %s" % (num_removed, graph.name)
- return num_removed
def propagate_all(translator):
for graph in translator.graphs:
@@ -310,6 +260,5 @@
changed = do_atmost(100, constant_folding, graph,
translator) or changed
changed = partial_folding(graph, translator) or changed
- changed = remove_duplicate_casts(graph, translator) or changed
return changed
do_atmost(10, prop)
Modified: pypy/dist/pypy/translator/backendopt/removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/removenoops.py (original)
+++ pypy/dist/pypy/translator/backendopt/removenoops.py Fri Apr 7 12:20:02 2006
@@ -1,6 +1,8 @@
from pypy.objspace.flow.model import Block, Variable, Constant
from pypy.objspace.flow.model import traverse
from pypy.rpython.lltypesystem.lltype import Void
+from pypy.translator import simplify
+from pypy import conftest
def remove_unaryops(graph, opnames):
"""Removes unary low-level ops with a name appearing in the opnames list.
@@ -63,6 +65,67 @@
args = [arg for arg in op.args
if arg.concretetype is not Void]
op.args = args
+
+def remove_duplicate_casts(graph, translator):
+ simplify.join_blocks(graph)
+ num_removed = 0
+ # remove chains of casts
+ for block in graph.iterblocks():
+ comes_from = {}
+ for op in block.operations:
+ if op.opname == "cast_pointer":
+ if op.args[0] in comes_from:
+ from_var = comes_from[op.args[0]]
+ comes_from[op.result] = from_var
+ if from_var.concretetype == op.result.concretetype:
+ op.opname = "same_as"
+ op.args = [from_var]
+ num_removed += 1
+ else:
+ op.args = [from_var]
+ else:
+ comes_from[op.result] = op.args[0]
+ if num_removed:
+ remove_same_as(graph)
+ # remove duplicate casts
+ for block in graph.iterblocks():
+ available = {}
+ for op in block.operations:
+ if op.opname == "cast_pointer":
+ key = (op.args[0], op.result.concretetype)
+ if key in available:
+ op.opname = "same_as"
+ op.args = [available[key]]
+ num_removed += 1
+ else:
+ available[key] = op.result
+ if num_removed:
+ remove_same_as(graph)
+ # remove casts with unused results
+ for block in graph.iterblocks():
+ used = {}
+ for link in block.exits:
+ for arg in link.args:
+ used[arg] = True
+ for i, op in list(enumerate(block.operations))[::-1]:
+ if op.opname == "cast_pointer" and op.result not in used:
+ del block.operations[i]
+ num_removed += 1
+ else:
+ for arg in op.args:
+ used[arg] = True
+ print "removed %s cast_pointers in %s" % (num_removed, graph.name)
+ return num_removed
+
+def remove_superfluous_keep_alive(graph):
+ for block in graph.iterblocks():
+ used = {}
+ for i, op in list(enumerate(block.operations))[::-1]:
+ if op.opname == "keepalive":
+ if op.args[0] in used:
+ del block.operations[i]
+ else:
+ used[op.args[0]] = True
##def rename_extfunc_calls(translator):
## from pypy.rpython.extfunctable import table as extfunctable
Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_propagate.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py Fri Apr 7 12:20:02 2006
@@ -183,43 +183,4 @@
if conftest.option.view:
t.view()
-def test_remove_duplicate_casts():
- class A(object):
- def __init__(self, x, y):
- self.x = x
- self.y = y
- def getsum(self):
- return self.x + self.y
- class B(A):
- def __init__(self, x, y, z):
- A.__init__(self, x, y)
- self.z = z
- def getsum(self):
- return self.x + self.y + self.z
- def f(x, switch):
- a = A(x, x + 1)
- b = B(x, x + 1, x + 2)
- if switch:
- c = A(x, x + 1)
- else:
- c = B(x, x + 1, x + 2)
- return a.x + a.y + b.x + b.y + b.z + c.getsum()
- assert f(10, True) == 75
- graph, t = get_graph(f, [int, bool], 1)
- num_cast_pointer = len(getops(graph)['cast_pointer'])
- changed = remove_duplicate_casts(graph, t)
- assert changed
- ops = getops(graph)
- assert len(ops['cast_pointer']) < num_cast_pointer
- print len(ops['cast_pointer']), num_cast_pointer
- graph_getsum = graphof(t, B.getsum.im_func)
- num_cast_pointer = len(getops(graph_getsum)['cast_pointer'])
- changed = remove_duplicate_casts(graph_getsum, t)
- assert changed
- if conftest.option.view:
- t.view()
- check_graph(graph, [10, True], 75, t)
- ops = getops(graph_getsum)
- assert len(ops['cast_pointer']) < num_cast_pointer
- print len(ops['cast_pointer']), num_cast_pointer
-
+
Modified: pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_removenoops.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_removenoops.py Fri Apr 7 12:20:02 2006
@@ -1,12 +1,14 @@
from pypy.translator.backendopt.removenoops import remove_void, remove_same_as, \
- remove_unaryops
+ remove_unaryops, remove_duplicate_casts, remove_superfluous_keep_alive
from pypy.translator.backendopt.inline import inline_function
+from pypy.translator.backendopt.test.test_propagate import getops, get_graph, check_graph
from pypy.translator.translator import TranslationContext, graphof
from pypy.translator.test.snippet import simple_method
from pypy.objspace.flow.model import checkgraph, flatten, Block
-from pypy.rpython.lltypesystem.lltype import Void, Signed
+from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.llinterp import LLInterpreter
+from pypy import conftest
import py
log = py.log.Producer('test_backendoptimization')
@@ -26,7 +28,7 @@
for graph in t.graphs:
assert checkgraph(graph) is None
for arg in graph.startblock.inputargs:
- assert arg.concretetype is not Void
+ assert arg.concretetype is not lltype.Void
interp = LLInterpreter(t.rtyper)
assert interp.eval_graph(graphof(t, f), [0]) == 1
@@ -40,7 +42,7 @@
#for fieldname in self.struct._names: #XXX helper (in lltype?) should remove these voids
# type_ = getattr(struct, fieldname)
# log('fieldname=%(fieldname)s , type_=%(type_)s' % locals())
- # assert _type is not Void
+ # assert _type is not lltype.Void
#interp = LLInterpreter(t.flowgraphs, t.rtyper)
#assert interp.eval_function(f, [0]) == 1
@@ -75,9 +77,9 @@
# oodowncast in dynamically typed languages, but it's easier to test
# it with operations on ints here.
def f(x):
- i = llop.int_invert(Signed, x)
- i = llop.int_add(Signed, x, 1)
- return llop.int_neg(Signed, i)
+ i = llop.int_invert(lltype.Signed, x)
+ i = llop.int_add(lltype.Signed, x, 1)
+ return llop.int_neg(lltype.Signed, i)
t = TranslationContext()
t.buildannotator().build_types(f, [int])
t.buildrtyper().specialize()
@@ -89,3 +91,57 @@
result = interp.eval_graph(f_graph, [-2])
assert result == -1
+def test_remove_keepalive():
+ S = lltype.GcStruct("s", ("f", lltype.Signed))
+ def f():
+ s1 = lltype.malloc(S)
+ llop.keepalive(lltype.Void, s1)
+ s2 = lltype.malloc(S)
+ llop.keepalive(lltype.Void, s1)
+ llop.keepalive(lltype.Void, s2)
+ return id(s1) + id(s2)
+ graph, t = get_graph(f, [])
+ remove_superfluous_keep_alive(graph)
+ ops = getops(graph)
+ assert len(ops['keepalive']) == 2
+
+def test_remove_duplicate_casts():
+ class A(object):
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+ def getsum(self):
+ return self.x + self.y
+ class B(A):
+ def __init__(self, x, y, z):
+ A.__init__(self, x, y)
+ self.z = z
+ def getsum(self):
+ return self.x + self.y + self.z
+ def f(x, switch):
+ a = A(x, x + 1)
+ b = B(x, x + 1, x + 2)
+ if switch:
+ c = A(x, x + 1)
+ else:
+ c = B(x, x + 1, x + 2)
+ return a.x + a.y + b.x + b.y + b.z + c.getsum()
+ assert f(10, True) == 75
+ graph, t = get_graph(f, [int, bool], 1)
+ num_cast_pointer = len(getops(graph)['cast_pointer'])
+ changed = remove_duplicate_casts(graph, t)
+ assert changed
+ ops = getops(graph)
+ assert len(ops['cast_pointer']) < num_cast_pointer
+ print len(ops['cast_pointer']), num_cast_pointer
+ graph_getsum = graphof(t, B.getsum.im_func)
+ num_cast_pointer = len(getops(graph_getsum)['cast_pointer'])
+ changed = remove_duplicate_casts(graph_getsum, t)
+ assert changed
+ if conftest.option.view:
+ t.view()
+ check_graph(graph, [10, True], 75, t)
+ ops = getops(graph_getsum)
+ assert len(ops['cast_pointer']) < num_cast_pointer
+ print len(ops['cast_pointer']), num_cast_pointer
+
More information about the Pypy-commit
mailing list