[pypy-svn] r27142 - in pypy/dist/pypy/translator: backendopt stackless stackless/test
mwh at codespeak.net
mwh at codespeak.net
Fri May 12 17:31:42 CEST 2006
Author: mwh
Date: Fri May 12 17:31:41 2006
New Revision: 27142
Modified:
pypy/dist/pypy/translator/backendopt/graphanalyze.py
pypy/dist/pypy/translator/stackless/test/test_transform.py
pypy/dist/pypy/translator/stackless/transform.py
Log:
don't stackless transform graphs that don't need it, and don't protect calls to
such graphs.
Modified: pypy/dist/pypy/translator/backendopt/graphanalyze.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/graphanalyze.py (original)
+++ pypy/dist/pypy/translator/backendopt/graphanalyze.py Fri May 12 17:31:41 2006
@@ -20,13 +20,19 @@
def analyze_startblock(self, block, seen=None):
return False
+ def analyze_external_call(self, op):
+ return True
+
+ def analyze_link(self, graph, link):
+ return False
+
# general methods
def analyze(self, op, seen=None):
if op.opname == "direct_call":
graph = get_graph(op.args[0], self.translator)
if graph is None:
- return True
+ return self.analyze_external_call(op)
return self.analyze_direct_call(graph, seen)
elif op.opname == "indirect_call":
if op.args[-1].value is None:
@@ -58,6 +64,9 @@
if self.analyze(op, seen):
self.analyzed_calls[graph] = True
return True
+ for exit in block.exits:
+ if self.analyze_link(graph, exit):
+ return True
self.analyzed_calls[graph] = False
return False
Modified: pypy/dist/pypy/translator/stackless/test/test_transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_transform.py (original)
+++ pypy/dist/pypy/translator/stackless/test/test_transform.py Fri May 12 17:31:41 2006
@@ -205,6 +205,27 @@
res = llinterp_stackless_function(f)
assert res == 106
+def test_dont_transform_too_much():
+ def check(x):
+ if x:
+ raise code.UnwindException
+ check.stackless_explicit = True
+ def f(x):
+ return x + 2
+ def g(x):
+ check(x)
+ return f(x) + x + 1
+ def example():
+ return g(one()) + 1
+ res, t = llinterp_stackless_function(example, returntranslator=True)
+ assert res == 6
+
+ ggraph = graphof(t, g)
+ for block, op in ggraph.iterblockops():
+ if op.opname == 'direct_call':
+ if op.args[0].value._obj._callable is f:
+ assert op != block.operations[-1]
+
def rtype_stackless_function(fn):
s_list_of_strings = annmodel.SomeList(ListDef(None, annmodel.SomeString()))
s_list_of_strings.listdef.resize()
@@ -241,7 +262,7 @@
res = cbuilder.cmdexec('')
return int(res.strip())
-def llinterp_stackless_function(fn):
+def llinterp_stackless_function(fn, returntranslator=False):
def wrapper(argv):
return fn()
t = rtype_stackless_function(wrapper)
@@ -256,4 +277,7 @@
ll_list = r_list_of_strings.convert_const([''])
interp = llinterp.LLInterpreter(t.rtyper)
res = interp.eval_graph(graph, [ll_list])
- return res
+ if returntranslator:
+ return res, t
+ else:
+ return res
Modified: pypy/dist/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/transform.py (original)
+++ pypy/dist/pypy/translator/stackless/transform.py Fri May 12 17:31:41 2006
@@ -111,15 +111,35 @@
return T, fieldnames
class StacklessAnalyzer(graphanalyze.GraphAnalyzer):
+ def __init__(self, translator, unwindtype):
+ graphanalyze.GraphAnalyzer.__init__(self, translator)
+ self.unwindtype = unwindtype
+
def operation_is_true(self, op):
- return True
+ return op.opname == 'yield_current_frame_to_caller'
+
+ def analyze_link(self, graph, link):
+ if link.target is graph.exceptblock:
+ # XXX is this the right way to do this?
+ op = link.prevblock.operations[-1]
+ if op.opname == 'cast_pointer':
+ ct = op.args[0].concretetype
+ return ct is self.unwindtype
+ return False
+
+ def analyze_external_call(self, op):
+ callable = op.args[0].value._obj._callable
+ #assert getattr(callable, 'suggested_primitive', False)
+ return callable in [ll_stack.ll_stack_unwind,
+ ll_stackless.ll_stackless_stack_frames_depth,
+ ll_stackless.ll_stackless_switch]
+
class StacklessTransformer(object):
def __init__(self, translator, entrypoint):
self.translator = translator
self.frametyper = FrameTyper()
- self.analyzer = StacklessAnalyzer(translator)
self.curr_graph = None
bk = translator.annotator.bookkeeper
@@ -127,6 +147,8 @@
self.unwind_exception_type = getinstancerepr(
self.translator.rtyper,
bk.getuniqueclassdef(code.UnwindException)).lowleveltype
+ self.analyzer = StacklessAnalyzer(translator,
+ self.unwind_exception_type)
mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
l2a = annmodel.lltype_to_annotation
@@ -363,6 +385,10 @@
if func in self.suggested_primitives:
op = replace_with_call(self.suggested_primitives[func])
+ if not self.analyzer.analyze(op):
+ i += 1
+ continue
+
if i == len(block.operations) - 1 \
and block.exitswitch == model.c_last_exception:
link = block.exits[0]
More information about the Pypy-commit
mailing list