[pypy-svn] r24518 - in pypy/dist/pypy/jit: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Mar 17 14:35:33 CET 2006
Author: arigo
Date: Fri Mar 17 14:35:31 2006
New Revision: 24518
Modified:
pypy/dist/pypy/jit/hintcontainer.py
pypy/dist/pypy/jit/hintmodel.py
pypy/dist/pypy/jit/test/test_hint_annotation.py
Log:
hintannotator: detect mixing of incompatible virtual container types
and fall back by setting a "degenerated" flag on the ContainerDef.
The hintrtyper should detect this flag.
Modified: pypy/dist/pypy/jit/hintcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/hintcontainer.py (original)
+++ pypy/dist/pypy/jit/hintcontainer.py Fri Mar 17 14:35:31 2006
@@ -12,6 +12,12 @@
def __init__(self, bookkeeper, TYPE):
self.T = TYPE
self.bookkeeper = bookkeeper
+ # if a virtual container "escapes" control in some way, e.g. by
+ # being unified with a SomeLLAbstractVariable, the ContainerDef
+ # becomes 'degenerated'. For the hintrtyper, degenerated
+ # SomeLLAbstractContainers should roughly be equivalent to
+ # SomeLLAbstractVariables.
+ self.degenerated = False
# hack to try to produce a repr that shows identifications
key = (self.__class__, TYPE)
weakdict = AbstractContainerDef.__cache.setdefault(key,
@@ -47,6 +53,14 @@
hs_c.const = TYPE._defl()
return hs_c
+def degenerate_item(item, ITEM_TYPE):
+ if isinstance(ITEM_TYPE, lltype.ContainerType):
+ hs = item.s_value
+ assert isinstance(hs, hintmodel.SomeLLAbstractContainer)
+ hs.contentdef.mark_degenerated()
+ else:
+ item.generalize(hintmodel.SomeLLAbstractVariable(ITEM_TYPE))
+
# ____________________________________________________________
class FieldValue(ListItem):
@@ -99,15 +113,37 @@
return self.fields == other.fields
def union(self, other):
- # xxx about vparent?
assert self.T == other.T
for name in self.names:
self.fields[name].merge(other.fields[name])
+ incompatible = False
+ if self.vparent is not None:
+ if other.vparent is not None:
+ if self.vparent.T != other.vparent.T:
+ incompatible = True
+ else:
+ self.vparent.union(other.vparent)
+ else:
+ incompatible = True
+ elif other.vparent is not None:
+ incompatible = True
+ if incompatible or self.degenerated or other.degenerated:
+ self.mark_degenerated()
+ other.mark_degenerated()
return self
def generalize_field(self, name, hs_value):
self.fields[name].generalize(hs_value)
+ def mark_degenerated(self):
+ if self.degenerated:
+ return
+ self.degenerated = True
+ for name in self.names:
+ degenerate_item(self.fields[name], self.fieldtype(name))
+ if self.vparent is not None:
+ self.vparent.mark_degenerated()
+
# ____________________________________________________________
@@ -140,3 +176,7 @@
def generalize_item(self, hs_value):
self.arrayitem.generalize(hs_value)
+
+ def mark_degenerated(self):
+ self.degenerated = True
+ degenerate_item(self.arrayitem, self.T.OF)
Modified: pypy/dist/pypy/jit/hintmodel.py
==============================================================================
--- pypy/dist/pypy/jit/hintmodel.py (original)
+++ pypy/dist/pypy/jit/hintmodel.py Fri Mar 17 14:35:31 2006
@@ -151,6 +151,14 @@
if hs_flags.const.get('forget', False):
XXX # not implemented
+ def getfield(hs_v1, hs_fieldname):
+ S = hs_v1.concretetype.TO
+ FIELD_TYPE = getattr(S, hs_fieldname.const)
+ return SomeLLAbstractVariable(FIELD_TYPE)
+
+ def setfield(hs_v1, hs_fieldname, hs_value):
+ pass
+
class __extend__(SomeLLAbstractConstant):
def hint(hs_c1, hs_flags):
@@ -366,7 +374,18 @@
class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractContainer)):
def union((hs_cont1, hs_cont2)):
- return SomeLLAbstractContainer(hs_cont1.contentdef.union(hs_cont2.contentdef))
+ contentdef = hs_cont1.contentdef.union(hs_cont2.contentdef)
+ return SomeLLAbstractContainer(contentdef)
+
+class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractValue)):
+ def union((hs_cont1, hs_val2)):
+ hs_cont1.contentdef.mark_degenerated()
+ assert hs_cont1.concretetype == hs_val2.concretetype
+ return SomeLLAbstractVariable(hs_cont1.concretetype)
+
+class __extend__(pairtype(SomeLLAbstractValue, SomeLLAbstractContainer)):
+ def union((hs_val1, hs_cont2)):
+ return pair(hs_cont2, hs_val1).union()
class __extend__(pairtype(SomeLLAbstractContainer, SomeLLAbstractConstant)):
Modified: pypy/dist/pypy/jit/test/test_hint_annotation.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_annotation.py (original)
+++ pypy/dist/pypy/jit/test/test_hint_annotation.py Fri Mar 17 14:35:31 2006
@@ -294,6 +294,38 @@
hs_n = ha.binding(g1.getargs()[0])
assert hs_n.origins.keys()[0].fixed
+def test_prebuilt_structure():
+ S = lltype.GcStruct('S', ('n', lltype.Signed))
+ s = lltype.malloc(S)
+ def ll1(n):
+ s.n = n
+ return s.n
+ hs = hannotate(ll1, [int])
+ assert isinstance(hs, SomeLLAbstractVariable)
+
+def test_merge_substructure():
+ S = lltype.GcStruct('S', ('n', lltype.Signed))
+ T = lltype.GcStruct('T', ('s', S), ('n', lltype.Float))
+
+ def ll_function(flag):
+ t = lltype.malloc(T)
+ t.s.n = 3
+ s = lltype.malloc(S)
+ s.n = 4
+ if flag:
+ s = t.s
+ return s, t
+ hs = hannotate(ll_function, [bool])
+ assert isinstance(hs, SomeLLAbstractContainer)
+ assert not hs.contentdef.degenerated
+ assert len(hs.contentdef.fields) == 2
+ hs0 = hs.contentdef.fields['item0'].s_value # 's'
+ assert isinstance(hs0, SomeLLAbstractContainer)
+ assert hs0.contentdef.degenerated
+ hs1 = hs.contentdef.fields['item1'].s_value # 't'
+ assert isinstance(hs1, SomeLLAbstractContainer)
+ assert hs1.contentdef.degenerated
+
def test_simple_fixed_call():
def ll_help(cond, x, y):
if cond:
More information about the Pypy-commit
mailing list