[pypy-svn] r23433 - in pypy/dist/pypy: annotation rpython rpython/test
pedronis at codespeak.net
pedronis at codespeak.net
Fri Feb 17 02:31:34 CET 2006
Author: pedronis
Date: Fri Feb 17 02:31:32 2006
New Revision: 23433
Modified:
pypy/dist/pypy/annotation/description.py
pypy/dist/pypy/rpython/normalizecalls.py
pypy/dist/pypy/rpython/test/test_normalizecalls.py
Log:
make perform_normalizations callable again (for now favoring sanity-checking over skipping work)
simple testing for this based on test_normalizecalls and annotate_mixlevel_helper
it seems that annotating and rtyping new classes after a first phase of rtyping
works.
Modified: pypy/dist/pypy/annotation/description.py
==============================================================================
--- pypy/dist/pypy/annotation/description.py (original)
+++ pypy/dist/pypy/annotation/description.py Fri Feb 17 02:31:32 2006
@@ -13,6 +13,7 @@
'd1~d2 if d1 and d2 might be called at the same call site'.
"""
overridden = False
+ normalized = False
def __init__(self, desc):
self.descs = { desc: True }
@@ -20,6 +21,7 @@
self.total_calltable_size = 0
def update(self, other):
+ self.normalized = self.normalized or other.normalized
self.descs.update(other.descs)
for shape, table in other.calltables.items():
for row in table:
Modified: pypy/dist/pypy/rpython/normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/normalizecalls.py (original)
+++ pypy/dist/pypy/rpython/normalizecalls.py Fri Feb 17 02:31:32 2006
@@ -1,5 +1,5 @@
import py
-import types
+import types, sys
import inspect
from pypy.objspace.flow.model import Variable, Constant, Block, Link
from pypy.objspace.flow.model import checkgraph, FunctionGraph, SpaceOperation
@@ -14,6 +14,7 @@
def normalize_call_familes(annotator):
for callfamily in annotator.bookkeeper.pbc_maximal_call_families.infos():
normalize_calltable(annotator, callfamily)
+ callfamily.normalized = True
def normalize_calltable(annotator, callfamily):
"""Try to normalize all rows of a table."""
@@ -32,6 +33,7 @@
did_something = normalize_calltable_row_signature(annotator, shape,
row)
if did_something:
+ assert not callfamily.normalized, "change in call family normalisation"
assert nshapes == 1, "XXX call table too complex"
while True:
progress = False
@@ -40,6 +42,7 @@
progress |= normalize_calltable_row_annotation(annotator, row)
if not progress:
return # done
+ assert not callfamily.normalized, "change in call family normalisation"
def normalize_calltable_row_signature(annotator, shape, row):
graphs = row.values()
@@ -198,10 +201,14 @@
raise TyperError("reading attributes %r: no common base class "
"for %r" % (
access_set.attrs.keys(), descs.keys()))
- access_set.commonbase = commonbase
extra_access_sets = rtyper.class_pbc_attributes.setdefault(commonbase,
{})
- extra_access_sets[access_set] = len(extra_access_sets)
+ if commonbase in rtyper.class_reprs:
+ assert access_set in extra_access_sets # minimal sanity check
+ return
+ access_set.commonbase = commonbase
+ if access_set not in extra_access_sets:
+ extra_access_sets[access_set] = len(extra_access_sets)
# ____________________________________________________________
@@ -218,7 +225,10 @@
# Note that a callfamily of classes must really be in the same
# attrfamily as well; This property is relied upon on various
# places in the rtyper
- descs[0].mergeattrfamilies(*descs[1:])
+ change = descs[0].mergeattrfamilies(*descs[1:])
+ if hasattr(descs[0].getuniqueclassdef(), 'my_instantiate_graph'):
+ assert not change, "after the fact change to a family of classes" # minimal sanity check
+ return
attrfamily = descs[0].getattrfamily()
# Put __init__ into the attr family, for ClassesPBCRepr.call()
s_value = attrfamily.attrs.get('__init__', annmodel.s_ImpossibleValue)
@@ -246,6 +256,8 @@
# def my_instantiate():
# return instantiate(cls)
#
+ if hasattr(classdef, 'my_instantiate_graph'):
+ return
v = Variable()
block = Block([])
block.operations.append(SpaceOperation('instantiate1', [], v))
@@ -272,7 +284,9 @@
id_ = 0
for classdef in annotator.bookkeeper.classdefs:
if classdef.basedef is None:
+ prevmaxid = getattr(classdef, 'maxid', sys.maxint)
id_ = assign_id(classdef, id_)
+ assert id_ <= prevmaxid, "non-orthogonal class hierarchy growth"
# ____________________________________________________________
Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_normalizecalls.py (original)
+++ pypy/dist/pypy/rpython/test/test_normalizecalls.py Fri Feb 17 02:31:32 2006
@@ -1,132 +1,186 @@
from pypy.annotation import model as annmodel
from pypy.translator.translator import TranslationContext, graphof
+from pypy.rpython.llinterp import LLInterpreter
from pypy.rpython.test.test_llinterp import interpret
from pypy.rpython.lltypesystem import lltype
-def rtype(fn, argtypes=[]):
- t = TranslationContext()
- t.buildannotator().build_types(fn, argtypes)
- typer = t.buildrtyper()
- typer.specialize()
- #t.view()
- t.checkgraphs()
- return t
# ____________________________________________________________
-def test_normalize_f2_as_taking_string_argument():
- def f1(l1):
- pass
- def f2(l2):
- pass
- def g(n):
- if n > 0:
- f1("123")
- f = f1
- else:
- f2("b")
- f = f2
- f("a")
-
- # The call table looks like:
- #
- # FuncDesc(f1) FuncDesc(f2)
- # --------------------------------------------
- # line g+2: graph1
- # line g+5: graph2
- # line g+7: graph1 graph2
- #
- # But all lines get compressed to a single line.
-
- translator = rtype(g, [int])
- f1graph = graphof(translator, f1)
- f2graph = graphof(translator, f2)
- s_l1 = translator.annotator.binding(f1graph.getargs()[0])
- s_l2 = translator.annotator.binding(f2graph.getargs()[0])
- assert s_l1.__class__ == annmodel.SomeString # and not SomeChar
- assert s_l2.__class__ == annmodel.SomeString # and not SomeChar
- #translator.view()
-
-def test_normalize_keyword_call():
- def f1(a, b):
- return (a, b, 0, 0)
- def f2(b, c=123, a=456, d=789):
- return (a, b, c, d)
- def g(n):
- if n > 0:
- f = f1
- else:
- f = f2
- f(a=5, b=6)
-
- translator = rtype(g, [int])
- f1graph = graphof(translator, f1)
- f2graph = graphof(translator, f2)
- assert len(f1graph.getargs()) == 2
- assert len(f2graph.getargs()) == 2 # normalized to the common call pattern
- #translator.view()
-
-def test_normalize_returnvar():
- def add_one(n):
- return n+1
- def add_half(n):
- return n+0.5
- def dummyfn(n, i):
- if i == 1:
- adder = add_one
- else:
- adder = add_half
- return adder(n)
-
- res = interpret(dummyfn, [52, 1])
- assert type(res) is float and res == 53.0
- res = interpret(dummyfn, [7, 2])
- assert type(res) is float and res == 7.5
-
-def test_normalize_missing_return():
- def add_one(n):
- return n+1
- def oups(n):
- raise ValueError
- def dummyfn(n, i):
- if i == 1:
- adder = add_one
- else:
- adder = oups
- try:
+class TestNormalize(object):
+
+ def rtype(self, fn, argtypes=[]):
+ t = TranslationContext()
+ t.buildannotator().build_types(fn, argtypes)
+ typer = t.buildrtyper()
+ typer.specialize()
+ #t.view()
+ t.checkgraphs()
+ return t
+
+
+ def test_normalize_f2_as_taking_string_argument(self):
+ def f1(l1):
+ pass
+ def f2(l2):
+ pass
+ def g(n):
+ if n > 0:
+ f1("123")
+ f = f1
+ else:
+ f2("b")
+ f = f2
+ f("a")
+
+ # The call table looks like:
+ #
+ # FuncDesc(f1) FuncDesc(f2)
+ # --------------------------------------------
+ # line g+2: graph1
+ # line g+5: graph2
+ # line g+7: graph1 graph2
+ #
+ # But all lines get compressed to a single line.
+
+ translator = self.rtype(g, [int])
+ f1graph = graphof(translator, f1)
+ f2graph = graphof(translator, f2)
+ s_l1 = translator.annotator.binding(f1graph.getargs()[0])
+ s_l2 = translator.annotator.binding(f2graph.getargs()[0])
+ assert s_l1.__class__ == annmodel.SomeString # and not SomeChar
+ assert s_l2.__class__ == annmodel.SomeString # and not SomeChar
+ #translator.view()
+
+ def test_normalize_keyword_call(self):
+ def f1(a, b):
+ return (a, b, 0, 0)
+ def f2(b, c=123, a=456, d=789):
+ return (a, b, c, d)
+ def g(n):
+ if n > 0:
+ f = f1
+ else:
+ f = f2
+ f(a=5, b=6)
+
+ translator = self.rtype(g, [int])
+ f1graph = graphof(translator, f1)
+ f2graph = graphof(translator, f2)
+ assert len(f1graph.getargs()) == 2
+ assert len(f2graph.getargs()) == 2 # normalized to the common call pattern
+ #translator.view()
+
+ def test_normalize_returnvar(self):
+ def add_one(n):
+ return n+1
+ def add_half(n):
+ return n+0.5
+ def dummyfn(n, i):
+ if i == 1:
+ adder = add_one
+ else:
+ adder = add_half
return adder(n)
- except ValueError:
- return -1
- translator = rtype(dummyfn, [int, int])
- add_one_graph = graphof(translator, add_one)
- oups_graph = graphof(translator, oups)
- assert add_one_graph.getreturnvar().concretetype == lltype.Signed
- assert oups_graph .getreturnvar().concretetype == lltype.Signed
- #translator.view()
-
-def test_normalize_abstract_method():
- class Base:
- def fn(self):
- raise NotImplementedError
- class Sub1(Base):
- def fn(self):
- return 1
- class Sub2(Base):
- def fn(self):
- return 2
- def dummyfn(n):
- if n == 1:
- x = Sub1()
- else:
- x = Sub2()
- return x.fn()
-
- translator = rtype(dummyfn, [int])
- base_graph = graphof(translator, Base.fn.im_func)
- sub1_graph = graphof(translator, Sub1.fn.im_func)
- sub2_graph = graphof(translator, Sub2.fn.im_func)
- assert base_graph.getreturnvar().concretetype == lltype.Signed
- assert sub1_graph.getreturnvar().concretetype == lltype.Signed
- assert sub2_graph.getreturnvar().concretetype == lltype.Signed
+ res = interpret(dummyfn, [52, 1])
+ assert type(res) is float and res == 53.0
+ res = interpret(dummyfn, [7, 2])
+ assert type(res) is float and res == 7.5
+
+ def test_normalize_missing_return(self):
+ def add_one(n):
+ return n+1
+ def oups(n):
+ raise ValueError
+ def dummyfn(n, i):
+ if i == 1:
+ adder = add_one
+ else:
+ adder = oups
+ try:
+ return adder(n)
+ except ValueError:
+ return -1
+
+ translator = self.rtype(dummyfn, [int, int])
+ add_one_graph = graphof(translator, add_one)
+ oups_graph = graphof(translator, oups)
+ assert add_one_graph.getreturnvar().concretetype == lltype.Signed
+ assert oups_graph .getreturnvar().concretetype == lltype.Signed
+ #translator.view()
+
+ def test_normalize_abstract_method(self):
+ class Base:
+ def fn(self):
+ raise NotImplementedError
+ class Sub1(Base):
+ def fn(self):
+ return 1
+ class Sub2(Base):
+ def fn(self):
+ return 2
+ def dummyfn(n):
+ if n == 1:
+ x = Sub1()
+ else:
+ x = Sub2()
+ return x.fn()
+
+ translator = self.rtype(dummyfn, [int])
+ base_graph = graphof(translator, Base.fn.im_func)
+ sub1_graph = graphof(translator, Sub1.fn.im_func)
+ sub2_graph = graphof(translator, Sub2.fn.im_func)
+ assert base_graph.getreturnvar().concretetype == lltype.Signed
+ assert sub1_graph.getreturnvar().concretetype == lltype.Signed
+ assert sub2_graph.getreturnvar().concretetype == lltype.Signed
+
+ llinterp = LLInterpreter(translator.rtyper)
+ res = llinterp.eval_graph(graphof(translator, dummyfn), [1])
+ assert res == 1
+ res = llinterp.eval_graph(graphof(translator, dummyfn), [2])
+ assert res == 2
+
+class TestNormalizeAfterTheFact(TestNormalize):
+
+ def rtype(self, fn, argtypes=[]):
+ class Base:
+ def fn(self):
+ raise NotImplementedError
+ class Sub1(Base):
+ def fn(self):
+ return 1
+ class Sub2(Base):
+ def fn(self):
+ return 2
+ def prefn(n):
+ if n == 1:
+ x = Sub1()
+ else:
+ x = Sub2()
+ return x.fn()
+
+ t = TranslationContext()
+ a = t.buildannotator()
+ a.build_types(prefn, [int])
+ typer = t.buildrtyper()
+ typer.specialize()
+ #t.view()
+
+ from pypy.rpython import annlowlevel
+ # normalize and rtype fn after the fact
+ graph = annlowlevel.annotate_mixlevel_helper(typer, fn, [a.typeannotation(argtype) for argtype in argtypes])
+ from pypy.rpython.normalizecalls import perform_normalizations
+ perform_normalizations(typer)
+ typer.specialize_more_blocks()
+
+ # sanity check prefn
+ llinterp = LLInterpreter(typer)
+ res = llinterp.eval_graph(graphof(t, prefn), [1])
+ assert res == 1
+ res = llinterp.eval_graph(graphof(t, prefn), [2])
+ assert res == 2
+
+ t.checkgraphs()
+ return t
More information about the Pypy-commit
mailing list