[pypy-svn] r20397 - in pypy/branch/somepbc-refactoring/pypy: rpython translator/c translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 29 16:54:54 CET 2005
Author: arigo
Date: Tue Nov 29 16:54:52 2005
New Revision: 20397
Modified:
pypy/branch/somepbc-refactoring/pypy/rpython/rptr.py
pypy/branch/somepbc-refactoring/pypy/rpython/rtyper.py
pypy/branch/somepbc-refactoring/pypy/translator/c/stackless.py
pypy/branch/somepbc-refactoring/pypy/translator/c/test/test_stackless.py
Log:
Fix test_stackless: stackless.py needs to handle graphs instead of
funcs, and there was a way for the call graph to miss some edges --
more precisely, ll helpers calling other ll helpers.
Modified: pypy/branch/somepbc-refactoring/pypy/rpython/rptr.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/rpython/rptr.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/rpython/rptr.py Tue Nov 29 16:54:52 2005
@@ -59,6 +59,9 @@
if not isinstance(self.lowleveltype.TO, FuncType):
raise TyperError("calling a non-function %r", self.lowleveltype.TO)
vlist = hop.inputargs(*hop.args_r)
+ if isinstance(vlist[0], flowmodel.Constant):
+ if hasattr(vlist[0].value, 'graph'):
+ hop.llops.record_extra_call(vlist[0].value.graph)
hop.exception_is_here()
return hop.genop('direct_call', vlist,
resulttype = self.lowleveltype.TO.RESULT)
Modified: pypy/branch/somepbc-refactoring/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/rpython/rtyper.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/rpython/rtyper.py Tue Nov 29 16:54:52 2005
@@ -719,6 +719,13 @@
def hasparentgraph(self):
return self.originalblock is not None
+ def record_extra_call(self, graph):
+ if self.hasparentgraph():
+ self.rtyper.annotator.translator.update_call_graph(
+ caller_graph = self.getparentgraph(),
+ callee_graph = graph,
+ position_tag = object())
+
def convertvar(self, v, r_from, r_to):
assert isinstance(v, (Variable, Constant))
if r_from != r_to:
@@ -778,11 +785,7 @@
ll_function = ll_function.im_func
graph = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s)
- if self.hasparentgraph():
- rtyper.annotator.translator.update_call_graph(
- caller_graph = self.getparentgraph(),
- callee_graph = graph,
- position_tag = object())
+ self.record_extra_call(graph)
# build the 'direct_call' operation
f = self.rtyper.getcallable(graph)
Modified: pypy/branch/somepbc-refactoring/pypy/translator/c/stackless.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/c/stackless.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/c/stackless.py Tue Nov 29 16:54:52 2005
@@ -8,6 +8,7 @@
from pypy.objspace.flow.model import Variable
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.memory.lladdress import Address
+from pypy.rpython.module import ll_stack, ll_stackless
from pypy.translator.c.support import cdecl
from pypy.translator.c.funcgen import FunctionCodeGenerator
@@ -21,21 +22,26 @@
# start the decoding table with entries for the functions that
# are written manually in ll_stackless.h
- def reg(name):
- self.stackless_roots[name.lower()] = True
- return name
+ def reg(llfn):
+ """Register the given ll_ primitive function as being able to unwing
+ the stack. Required to compute 'can_reach_unwind' correctly."""
+ assert llfn.suggested_primitive
+ self.stackless_roots[llfn] = True
+ name = llfn.__name__
+ assert name.startswith('ll_')
+ return 'LL_' + name[3:]
- reg('LL_stack_unwind')
- self.registerunwindable(reg('LL_stackless_stack_unwind'),
+ reg(ll_stack.ll_stack_unwind)
+ self.registerunwindable('LL_stackless_stack_unwind',
lltype.FuncType([], lltype.Void),
resume_points=1)
- self.registerunwindable(reg('LL_stackless_stack_frames_depth'),
+ self.registerunwindable(reg(ll_stackless.ll_stackless_stack_frames_depth),
lltype.FuncType([], lltype.Signed),
resume_points=1)
- self.registerunwindable(reg('LL_stackless_switch'),
+ self.registerunwindable(reg(ll_stackless.ll_stackless_switch),
lltype.FuncType([Address], Address),
resume_points=1)
- self.registerunwindable(reg('slp_end_of_yielding_function'),
+ self.registerunwindable('slp_end_of_yielding_function',
lltype.FuncType([], Address),
resume_points=1)
@@ -43,11 +49,11 @@
self.database = database
self.count_calls = [0, 0]
- def unwind_reachable(self, func):
+ def unwind_reachable(self, graph):
reach_dict = self.can_reach_unwind
- if func not in reach_dict:
+ if graph not in reach_dict:
self.setup()
- return reach_dict[func]
+ return reach_dict[graph]
def setup(self):
# to be called after database is complete, or we would
@@ -58,28 +64,28 @@
callers = {}
assert self.database.completed
translator = self.database.translator
- here = len(translator.functions)
- for func in translator.functions:
- callers[func] = []
- for caller, callee in translator.complete_callgraph.values():
- callers[caller].append(callee)
- # add newly generated ones
- for func in translator.functions[here:]:
- callers.setdefault(func, [])
+ for graph in translator.graphs:
+ callers[graph] = []
+ for caller, callee in translator.callgraph.values():
+ # ignore calls issued suggested_primitives -- they are not
+ # compiled in, and they typically contain pseudo-recursions
+ try:
+ suggprim = caller.func.suggested_primitive
+ except AttributeError:
+ suggprim = False
+ if not suggprim:
+ callers[caller].append(callee)
# check all callees if they can reach unwind
seen = self.can_reach_unwind
pending = {}
ext = self.database.externalfuncs
- def check_unwind(func):
- if func in pending:
- ret = func not in ext
- # typical pseudo-recursion of externals
- # but true recursions do unwind
- seen[func] = ret
- return ret
- pending[func] = func
- for callee in callers[func]:
+ def check_unwind(graph):
+ if graph in pending:
+ seen[graph] = True
+ return True
+ pending[graph] = graph
+ for callee in callers[graph]:
if callee in seen:
ret = seen[callee]
else:
@@ -87,9 +93,9 @@
if ret:
break
else:
- ret = func.__name__ in self.stackless_roots
- del pending[func]
- seen[func] = ret
+ ret = graph.func in self.stackless_roots
+ del pending[graph]
+ seen[graph] = ret
return ret
[check_unwind(caller) for caller in callers if caller not in seen]
@@ -251,10 +257,10 @@
slp = self.db.stacklessdata
# don't generate code for calls that cannot unwind
if not specialreturnvalue:
- need_stackless = slp.unwind_reachable(self.graph.func)
+ need_stackless = slp.unwind_reachable(self.graph)
if need_stackless:
try:
- callee = op.args[0].value._obj.graph.func
+ callee = op.args[0].value._obj.graph
except AttributeError:
pass # assume we need it really
else:
Modified: pypy/branch/somepbc-refactoring/pypy/translator/c/test/test_stackless.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/c/test/test_stackless.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/c/test/test_stackless.py Tue Nov 29 16:54:52 2005
@@ -1,4 +1,5 @@
-from pypy.translator.translator import Translator
+from pypy.translator.translator import TranslationContext
+from pypy.translator.c.genc import CStandaloneBuilder
from pypy.annotation.model import SomeList, SomeString
from pypy.annotation.listdef import ListDef
from pypy.rpython.rstack import stack_unwind, stack_frames_depth, stack_too_big
@@ -10,12 +11,13 @@
os.write(1, str(fn())+"\n")
return 0
- t = Translator(entry_point)
s_list_of_strings = SomeList(ListDef(None, SomeString()))
s_list_of_strings.listdef.resize()
- ann = t.annotate([s_list_of_strings])
- t.specialize()
- cbuilder = t.cbuilder(standalone=True)
+ t = TranslationContext()
+ t.buildannotator().build_types(entry_point, [s_list_of_strings])
+ t.buildrtyper().specialize()
+
+ cbuilder = CStandaloneBuilder(t, entry_point)
cbuilder.stackless = True
cbuilder.generate_source()
cbuilder.compile()
More information about the Pypy-commit
mailing list