[pypy-svn] r17475 - in pypy/dist/pypy: annotation rpython/test translator translator/test
pedronis at codespeak.net
pedronis at codespeak.net
Sun Sep 11 22:35:22 CEST 2005
Author: pedronis
Date: Sun Sep 11 22:35:19 2005
New Revision: 17475
Modified:
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/rpython/test/test_rpbc.py
pypy/dist/pypy/translator/annrpython.py
pypy/dist/pypy/translator/test/test_annrpython.py
Log:
emulate_pbc_call should not require position_key to be set
support specifying a calalback that will be called with annotator, graph each time one of the involved callable
result gets generalized
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Sun Sep 11 22:35:19 2005
@@ -522,8 +522,8 @@
callfamily.patterns.update({shape: True})
- def pbc_call(self, pbc, args, implicit_init):
- if not implicit_init:
+ def pbc_call(self, pbc, args, implicit_init=False, emulated=None):
+ if not implicit_init and not emulated:
fn, block, i = self.position_key
assert block.operations[i].opname in ('call_args', 'simple_call')
assert self.annotator.binding(block.operations[i].args[0], extquery=True) is pbc
@@ -541,17 +541,25 @@
if func is not None]
mono = len(nonnullcallables) == 1
+ if emulated is not None:
+ if emulated is True:
+ context = None
+ else:
+ context = emulated
+ else:
+ context = 'current'
+
for func, classdef in nonnullcallables:
if isclassdef(classdef):
s_self = SomeInstance(classdef)
args1 = args.prepend(s_self)
else:
args1 = args
- results.append(self.pycall(func, args1, mono))
+ results.append(self.pycall(func, args1, mono, context=context))
return unionof(*results)
- def emulate_pbc_call(self, unique_key, pbc, args_s, replace=[]):
+ def emulate_pbc_call(self, unique_key, pbc, args_s, replace=[], callback=None):
args = self.build_args("simple_call", args_s)
shape = args.rawshape()
emulated_pbc_calls = self.emulated_pbc_calls
@@ -564,7 +572,12 @@
del emulated_pbc_calls[other_key]
emulated_pbc_calls[unique_key] = pbc, shape
- return self.pbc_call(pbc, args, True)
+ if callback is None:
+ emulated = True
+ else:
+ emulated = callback
+
+ return self.pbc_call(pbc, args, emulated=emulated)
# decide_callable(position, func, args, mono) -> callb, key
# query_spaceop_callable(spaceop) -> pbc, isspecialcase
@@ -644,13 +657,17 @@
return inputcells
- def pycall(self, func, args, mono):
+ def pycall(self, func, args, mono, context='current'):
if func is None: # consider None as a NULL function pointer
return SomeImpossibleValue()
# decide and pick if necessary a specialized version
base_func = func
- func, key = decide_callable(self, self.position_key, func, args, mono, unpacked=True)
+ if context == 'current':
+ position_key = self.position_key
+ else:
+ position_key = None
+ func, key = decide_callable(self, position_key, func, args, mono, unpacked=True)
if func is None:
assert isinstance(key, SomeObject)
@@ -675,11 +692,15 @@
assert isinstance(func, FunctionType), "[%s] expected user-defined function, got %r" % (self.whereami(), func)
inputcells = self.get_inputcells(func, args)
-
- r = self.annotator.recursivecall(func, self.position_key, inputcells)
+ if context == 'current':
+ whence = self.position_key
+ else:
+ whence = context
+ r = self.annotator.recursivecall(func, whence, inputcells)
# if we got different specializations keys for a same site, mix previous results for stability
if key is not None:
+ assert context == 'current'
occurence = (base_func, self.position_key)
try:
prev_key, prev_r = self.spec_callsite_keys_results[occurence]
Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py (original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py Sun Sep 11 22:35:19 2005
@@ -850,15 +850,14 @@
def test_hlinvoke_simple():
def f(a,b):
return a + b
+ from pypy.translator import translator
from pypy.translator import annrpython
- a = annrpython.RPythonAnnotator()
+ a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
from pypy.annotation import model as annmodel
- def g():
- f(2,3)
- f(4,5)
-
- a.build_types(g, [])
+ s_f = a.bookkeeper.immutablevalue(f)
+ a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
+ a.complete()
from pypy.rpython import rtyper
rt = rtyper.RPythonTyper(a)
@@ -870,7 +869,6 @@
from pypy.rpython import annlowlevel
- s_f = a.bookkeeper.immutablevalue(f)
r_f = rt.getrepr(s_f)
s_R = a.bookkeeper.immutablevalue(r_f)
Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py (original)
+++ pypy/dist/pypy/translator/annrpython.py Sun Sep 11 22:35:19 2005
@@ -269,14 +269,23 @@
#___ interface for annotator.bookkeeper _______
- def recursivecall(self, func, position_key, inputcells):
- parent_fn, parent_block, parent_index = position_key
+ def recursivecall(self, func, whence, inputcells): # whence = position_key|callback taking the annotator, graph
+ if isinstance(whence, tuple):
+ parent_fn, parent_block, parent_index = position_key = whence
+ else:
+ parent_fn = position_key = None
graph = self.getflowgraph(func, parent_fn, position_key)
# self.notify[graph.returnblock] is a dictionary of call
# points to this func which triggers a reflow whenever the
# return block of this graph has been analysed.
callpositions = self.notify.setdefault(graph.returnblock, {})
- callpositions[position_key] = True
+ if whence is not None:
+ if callable(whence):
+ def callback():
+ whence(self, graph)
+ else:
+ callback = whence
+ callpositions[callback] = True
# generalize the function's input arguments
self.addpendingblock(func, graph.startblock, inputcells, position_key)
@@ -584,8 +593,11 @@
self.addpendingblock(fn, link.target, cells)
if block in self.notify:
# reflow from certain positions when this block is done
- for position_key in self.notify[block]:
- self.reflowfromposition(position_key)
+ for callback in self.notify[block]:
+ if isinstance(callback, tuple):
+ self.reflowfromposition(callback) # callback is a position
+ else:
+ callback()
#___ creating the annotations based on operations ______
Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py (original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py Sun Sep 11 22:35:19 2005
@@ -1664,6 +1664,44 @@
s = a.build_types(g, [int])
assert None not in s.prebuiltinstances
+ def test_emulated_pbc_call_simple(self):
+ def f(a,b):
+ return a + b
+ from pypy.translator import translator
+ from pypy.translator import annrpython
+ a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
+ from pypy.annotation import model as annmodel
+
+ s_f = a.bookkeeper.immutablevalue(f)
+ a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
+ a.complete()
+
+ assert f in a.translator.flowgraphs
+ assert a.binding(a.translator.flowgraphs[f].getreturnvar()).knowntype == int
+
+ def test_emulated_pbc_call_callback(self):
+ def f(a,b):
+ return a + b
+ from pypy.translator import translator
+ from pypy.translator import annrpython
+ a = annrpython.RPythonAnnotator(translator.Translator(simplifying=True))
+ from pypy.annotation import model as annmodel
+
+ memo = []
+ def callb(ann, graph):
+ memo.append(annmodel.SomeInteger().contains(ann.binding(graph.getreturnvar())))
+
+ s_f = a.bookkeeper.immutablevalue(f)
+ s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()],
+ callback=callb)
+ assert s == annmodel.SomeImpossibleValue()
+ a.complete()
+
+ assert f in a.translator.flowgraphs
+ assert a.binding(a.translator.flowgraphs[f].getreturnvar()).knowntype == int
+ assert len(memo) >= 1
+ for t in memo:
+ assert t
def g(n):
return [0,1,2,n]
More information about the Pypy-commit
mailing list