Author: Armin Rigo <ar...@tunes.org>
Branch: bitstring
Changeset: r83893:93c32636b538
Date: 2016-04-25 19:02 +0200
http://bitbucket.org/pypy/pypy/changeset/93c32636b538/

Log:    in-progress

diff --git a/rpython/jit/codewriter/effectinfo.py 
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -2,6 +2,31 @@
 from rpython.rtyper.rclass import OBJECT
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.translator.backendopt.graphanalyze import BoolGraphAnalyzer
+from rpython.tool.algo import bitstring
+
+
+
+class DescrCounterCache(object):
+    cache = []
+
+    def make_descr_set(self, lst):
+        if lst is None:
+            return None
+        integer_list = []
+        for descr in lst:
+            try:
+                x = descr._ei_index
+            except AttributeError:
+                x = descr._ei_index = len(self.cache)
+                self.cache.append(descr)
+            integer_list.append(x)
+        return bitstring.make_bitstring(integer_list)
+
+def expand_descr_list(cpu, bitstr):
+    # for debugging
+    return [cpu._descr_counter_cache.cache[i]
+                for i in range(bitstring.num_bits(bitstr))
+                if bitstring.bitcheck(bitstr, i)]
 
 
 class EffectInfo(object):
@@ -109,13 +134,21 @@
                 oopspecindex=OS_NONE,
                 can_invalidate=False,
                 call_release_gil_target=_NO_CALL_RELEASE_GIL_TARGET,
-                extradescrs=None):
-        key = (frozenset_or_none(readonly_descrs_fields),
-               frozenset_or_none(readonly_descrs_arrays),
-               frozenset_or_none(readonly_descrs_interiorfields),
-               frozenset_or_none(write_descrs_fields),
-               frozenset_or_none(write_descrs_arrays),
-               frozenset_or_none(write_descrs_interiorfields),
+                extradescrs=None,
+                descr_counter_cache=DescrCounterCache()):
+        make = descr_counter_cache.make_descr_set
+        readonly_descrs_fields = make(readonly_descrs_fields)
+        readonly_descrs_arrays = make(readonly_descrs_arrays)
+        readonly_descrs_interiorfields = make(readonly_descrs_interiorfields)
+        write_descrs_fields = make(write_descrs_fields)
+        write_descrs_arrays = make(write_descrs_arrays)
+        write_descrs_interiorfields = make(write_descrs_interiorfields)
+        key = (readonly_descrs_fields,
+               readonly_descrs_arrays,
+               readonly_descrs_interiorfields,
+               write_descrs_fields,
+               write_descrs_arrays,
+               write_descrs_interiorfields,
                extraeffect,
                oopspecindex,
                can_invalidate)
@@ -142,19 +175,9 @@
         result.readonly_descrs_fields = readonly_descrs_fields
         result.readonly_descrs_arrays = readonly_descrs_arrays
         result.readonly_descrs_interiorfields = readonly_descrs_interiorfields
-        if extraeffect == EffectInfo.EF_LOOPINVARIANT or \
-           extraeffect == EffectInfo.EF_ELIDABLE_CANNOT_RAISE or \
-           extraeffect == EffectInfo.EF_ELIDABLE_OR_MEMORYERROR or \
-           extraeffect == EffectInfo.EF_ELIDABLE_CAN_RAISE:
-            # Ignore the writes.  Note that this ignores also writes with
-            # no corresponding reads (rarely the case, but possible).
-            result.write_descrs_fields = []
-            result.write_descrs_arrays = []
-            result.write_descrs_interiorfields = []
-        else:
-            result.write_descrs_fields = write_descrs_fields
-            result.write_descrs_arrays = write_descrs_arrays
-            result.write_descrs_interiorfields = write_descrs_interiorfields
+        result.write_descrs_fields = write_descrs_fields
+        result.write_descrs_arrays = write_descrs_arrays
+        result.write_descrs_interiorfields = write_descrs_interiorfields
         result.extraeffect = extraeffect
         result.can_invalidate = can_invalidate
         result.oopspecindex = oopspecindex
@@ -196,11 +219,6 @@
         return '<EffectInfo 0x%x: EF=%r%s>' % (id(self), self.extraeffect, 
more)
 
 
-def frozenset_or_none(x):
-    if x is None:
-        return None
-    return frozenset(x)
-
 EffectInfo.MOST_GENERAL = EffectInfo(None, None, None, None, None, None,
                                      EffectInfo.EF_RANDOM_EFFECTS,
                                      can_invalidate=True)
@@ -287,6 +305,18 @@
             else:
                 assert 0
     #
+    if extraeffect == EffectInfo.EF_LOOPINVARIANT or \
+       extraeffect == EffectInfo.EF_ELIDABLE_CANNOT_RAISE or \
+       extraeffect == EffectInfo.EF_ELIDABLE_OR_MEMORYERROR or \
+       extraeffect == EffectInfo.EF_ELIDABLE_CAN_RAISE:
+        # Ignore the writes.  Note that this ignores also writes with
+        # no corresponding reads (rarely the case, but possible).
+        write_descrs_fields = []
+        write_descrs_arrays = []
+        write_descrs_interiorfields = []
+    #
+    if not hasattr(cpu, '_descr_counter_cache'):
+        cpu._descr_counter_cache = DescrCounterCache()
     return EffectInfo(readonly_descrs_fields,
                       readonly_descrs_arrays,
                       readonly_descrs_interiorfields,
@@ -297,7 +327,8 @@
                       oopspecindex,
                       can_invalidate,
                       call_release_gil_target,
-                      extradescr)
+                      extradescr,
+                      cpu._descr_counter_cache)
 
 def consider_struct(TYPE, fieldname):
     if fieldType(TYPE, fieldname) is lltype.Void:
diff --git a/rpython/jit/codewriter/test/test_effectinfo.py 
b/rpython/jit/codewriter/test/test_effectinfo.py
--- a/rpython/jit/codewriter/test/test_effectinfo.py
+++ b/rpython/jit/codewriter/test/test_effectinfo.py
@@ -1,19 +1,23 @@
 import pytest
 
 from rpython.jit.codewriter.effectinfo import (effectinfo_from_writeanalyze,
-    EffectInfo, VirtualizableAnalyzer)
+    EffectInfo, VirtualizableAnalyzer, expand_descr_list)
 from rpython.rlib import jit
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.rclass import OBJECT
 from rpython.translator.translator import TranslationContext, graphof
 
 
+class FakeDescr(tuple):
+    pass
+
+
 class FakeCPU(object):
     def fielddescrof(self, T, fieldname):
-        return ('fielddescr', T, fieldname)
+        return FakeDescr(('fielddescr', T, fieldname))
 
     def arraydescrof(self, A):
-        return ('arraydescr', A)
+        return FakeDescr(('arraydescr', A))
 
 
 def test_no_oopspec_duplicate():
@@ -28,83 +32,98 @@
 def test_include_read_field():
     S = lltype.GcStruct("S", ("a", lltype.Signed))
     effects = frozenset([("readstruct", lltype.Ptr(S), "a")])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert list(effectinfo.readonly_descrs_fields) == [('fielddescr', S, "a")]
-    assert not effectinfo.write_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert (expand_descr_list(cpu, effectinfo.readonly_descrs_fields) ==
+                [('fielddescr', S, "a")])
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_include_write_field():
     S = lltype.GcStruct("S", ("a", lltype.Signed))
     effects = frozenset([("struct", lltype.Ptr(S), "a")])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert list(effectinfo.write_descrs_fields) == [('fielddescr', S, "a")]
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert (expand_descr_list(cpu, effectinfo.write_descrs_fields) ==
+                [('fielddescr', S, "a")])
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_include_read_array():
     A = lltype.GcArray(lltype.Signed)
     effects = frozenset([("readarray", lltype.Ptr(A))])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert not effectinfo.readonly_descrs_fields
-    assert list(effectinfo.readonly_descrs_arrays) == [('arraydescr', A)]
-    assert not effectinfo.write_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert (expand_descr_list(cpu, effectinfo.readonly_descrs_arrays) ==
+                [('arraydescr', A)])
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_include_write_array():
     A = lltype.GcArray(lltype.Signed)
     effects = frozenset([("array", lltype.Ptr(A))])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.write_descrs_fields
-    assert list(effectinfo.write_descrs_arrays) == [('arraydescr', A)]
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert (expand_descr_list(cpu, effectinfo.write_descrs_arrays) ==
+                [('arraydescr', A)])
 
 
 def test_dont_include_read_and_write_field():
     S = lltype.GcStruct("S", ("a", lltype.Signed))
     effects = frozenset([("readstruct", lltype.Ptr(S), "a"),
                          ("struct", lltype.Ptr(S), "a")])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert not effectinfo.readonly_descrs_fields
-    assert list(effectinfo.write_descrs_fields) == [('fielddescr', S, "a")]
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert (expand_descr_list(cpu, effectinfo.write_descrs_fields) ==
+                [('fielddescr', S, "a")])
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_dont_include_read_and_write_array():
     A = lltype.GcArray(lltype.Signed)
     effects = frozenset([("readarray", lltype.Ptr(A)),
                          ("array", lltype.Ptr(A))])
-    effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU())
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.readonly_descrs_arrays
-    assert not effectinfo.write_descrs_fields
-    assert list(effectinfo.write_descrs_arrays) == [('arraydescr', A)]
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_arrays) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert (expand_descr_list(cpu, effectinfo.write_descrs_arrays) ==
+                [('arraydescr', A)])
 
 
 def test_filter_out_typeptr():
     effects = frozenset([("struct", lltype.Ptr(OBJECT), "typeptr")])
-    effectinfo = effectinfo_from_writeanalyze(effects, None)
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.write_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_filter_out_array_of_void():
     effects = frozenset([("array", lltype.Ptr(lltype.GcArray(lltype.Void)))])
-    effectinfo = effectinfo_from_writeanalyze(effects, None)
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.write_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 def test_filter_out_struct_with_void():
     effects = frozenset([("struct", lltype.Ptr(lltype.GcStruct("x", ("a", 
lltype.Void))), "a")])
-    effectinfo = effectinfo_from_writeanalyze(effects, None)
-    assert not effectinfo.readonly_descrs_fields
-    assert not effectinfo.write_descrs_fields
-    assert not effectinfo.write_descrs_arrays
+    cpu = FakeCPU()
+    effectinfo = effectinfo_from_writeanalyze(effects, cpu)
+    assert expand_descr_list(cpu, effectinfo.readonly_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_fields) == []
+    assert expand_descr_list(cpu, effectinfo.write_descrs_arrays) == []
 
 
 class TestVirtualizableAnalyzer(object):
diff --git a/rpython/tool/algo/bitstring.py b/rpython/tool/algo/bitstring.py
--- a/rpython/tool/algo/bitstring.py
+++ b/rpython/tool/algo/bitstring.py
@@ -18,3 +18,6 @@
     if byte_number >= len(bitstring):
         return False
     return (ord(bitstring[byte_number]) & (1 << (n & 7))) != 0
+
+def num_bits(bitstring):
+    return len(bitstring) << 3
diff --git a/rpython/tool/algo/test/test_bitstring.py 
b/rpython/tool/algo/test/test_bitstring.py
--- a/rpython/tool/algo/test/test_bitstring.py
+++ b/rpython/tool/algo/test/test_bitstring.py
@@ -18,3 +18,8 @@
 def test_random(lst):
     bitstring = make_bitstring(lst)
     assert set([n for n in range(300) if bitcheck(bitstring, n)]) == set(lst)
+
+def test_num_bits():
+    assert num_bits('') == 0
+    assert num_bits('a') == 8
+    assert num_bits('bcd') == 24
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to