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