[pypy-svn] r25676 - in pypy/dist/pypy/translator: . backendopt backendopt/test
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon Apr 10 20:46:57 CEST 2006
Author: cfbolz
Date: Mon Apr 10 20:46:55 2006
New Revision: 25676
Modified:
pypy/dist/pypy/translator/backendopt/propagate.py
pypy/dist/pypy/translator/backendopt/test/test_propagate.py
pypy/dist/pypy/translator/simplify.py
Log:
fix constant folding of calls
Modified: pypy/dist/pypy/translator/backendopt/propagate.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/propagate.py (original)
+++ pypy/dist/pypy/translator/backendopt/propagate.py Mon Apr 10 20:46:55 2006
@@ -133,6 +133,9 @@
raise TooManyOperations
return super(CountingLLFrame, self).eval_operation(operation)
+def op_can_be_folded(op):
+ return not lloperation.LL_OPERATIONS[op.opname].canfold
+
def constant_folding(graph, translator):
"""do constant folding if the arguments of an operations are constants"""
lli = LLInterpreter(translator.rtyper)
@@ -158,23 +161,24 @@
block.operations[i].opname = "same_as"
block.operations[i].args = [res]
changed = True
- # disabling the code for now, since it is not correct
- elif 0: #op.opname == "direct_call":
+ elif op.opname == "direct_call":
called_graph = get_graph(op.args[0], translator)
if (called_graph is not None and
- simplify.has_no_side_effects(translator, called_graph) and
+ simplify.has_no_side_effects(
+ translator, called_graph,
+ is_operation_false=op_can_be_folded) and
(block.exitswitch != c_last_exception or
i != len(block.operations) - 1)):
args = [arg.value for arg in op.args[1:]]
countingframe = CountingLLFrame(called_graph, args, lli)
- print "folding call", op, "in graph", graph.name
+ #print "folding call", op, "in graph", graph.name
try:
res = countingframe.eval()
except:
- print "did not work"
+ #print "did not work"
pass
else:
- print "result", res
+ #print "result", res
res = Constant(res)
res.concretetype = op.result.concretetype
block.operations[i].opname = "same_as"
@@ -341,16 +345,19 @@
log.removegetfield("removed %s getfields in %s" % (count, graph.name))
return count
+def propagate_all_per_graph(graph, translator):
+ def prop():
+ changed = False
+ changed = rewire_links(graph) or changed
+ changed = propagate_consts(graph) or changed
+ changed = coalesce_links(graph) or changed
+ changed = do_atmost(100, constant_folding, graph,
+ translator) or changed
+ changed = partial_folding(graph, translator) or changed
+ changed = remove_all_getfields(graph, translator) or changed
+ return changed
+ do_atmost(10, prop)
+
def propagate_all(translator):
for graph in translator.graphs:
- def prop():
- changed = False
- changed = rewire_links(graph) or changed
- changed = propagate_consts(graph) or changed
- changed = coalesce_links(graph) or changed
- changed = do_atmost(100, constant_folding, graph,
- translator) or changed
- changed = partial_folding(graph, translator) or changed
- changed = remove_all_getfields(graph, translator) or changed
- return changed
- do_atmost(10, prop)
+ propagate_all_per_graph(graph, translator)
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 Mon Apr 10 20:46:55 2006
@@ -82,22 +82,33 @@
check_graph(graph, [1], None, t)
def test_propagate_despite_vars():
- py.test.skip("immediate test")
patterns = [1, 1, 2, 3, 5, 7, 12]
class A(object): pass
- a = A()
- a.x = 10
- a.y = 20
- def f(x):
+ global_a = A()
+ global_a.x = 10
+ global_a.y = 20
+ def f(x):
+ a = A()
+ a.x = 10
+ a.y = 20
result = 0
+ i = 0
for i in range(a.x):
- for j in range(a.y):
+ j = 0
+ for i in range(global_a.y):
result += i * j
+ j += 1
return result
graph, t = get_graph(f, [int])
- propagate_consts(graph)
if conftest.option.view:
t.view()
+ while propagate_consts(graph):
+ pass
+ assert len(graph.startblock.exits[0].args) == 2
+ innerloopblock = graph.startblock.exits[0].target.exits[0].target.exits[0].target
+ assert len(innerloopblock.inputargs) == 4
+ assert len(innerloopblock.exits[0].args) == 4
+ check_graph(graph, [0], f(0), t)
def test_constant_fold():
def f(x):
@@ -112,8 +123,6 @@
check_graph(graph, [1], g(1), t)
def test_constant_fold_call():
- # fix the logic and try again :-)
- py.test.skip("constant folding calls is disabled, for sanity reasons")
def s(x):
res = 0
i = 1
@@ -131,6 +140,21 @@
assert len(graph.startblock.operations) == 1
check_graph(graph, [10], g(10), t)
+def test_dont_constant_fold_call():
+ class A(object):
+ pass
+ global_a = A()
+ global_a.x = 1
+ def g():
+ return global_a.x
+ def f(x):
+ global_a.x = x
+ return g()
+ graph, t = get_graph(f, [int], inline_threshold=0)
+ while constant_folding(graph, t):
+ pass
+ check_graph(graph, [10], 10, t)
+
def test_dont_fold_getfield():
# must not constant fold this, because the container might be collected
string = "blablabla"
Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py (original)
+++ pypy/dist/pypy/translator/simplify.py Mon Apr 10 20:46:55 2006
@@ -9,6 +9,7 @@
from pypy.objspace.flow.model import Variable, Constant, Block, Link
from pypy.objspace.flow.model import c_last_exception
from pypy.objspace.flow.model import checkgraph, traverse, mkentrymap
+from pypy.rpython.lltypesystem import lloperation
def get_graph(arg, translator):
from pypy.translator.translator import graphof
@@ -373,8 +374,11 @@
class HasSideEffects(Exception):
pass
-def has_no_side_effects(translator, graph, seen=None):
- from pypy.rpython.lltypesystem import lloperation
+def op_has_side_effects(op):
+ return lloperation.LL_OPERATIONS[op.opname].sideeffects
+
+def has_no_side_effects(translator, graph, seen=None,
+ is_operation_false=op_has_side_effects):
#is the graph specialized? if no we can't say anything
#don't cache the result though
if translator.rtyper is None:
@@ -406,7 +410,7 @@
for g in graphs:
if not has_no_side_effects(translator, g, newseen):
raise HasSideEffects
- elif lloperation.LL_OPERATIONS[op.opname].sideeffects:
+ elif is_operation_false(op):
raise HasSideEffects
traverse(visit, graph)
except HasSideEffects:
More information about the Pypy-commit
mailing list