Exemplo n.º 1
0
def compute_bitstrings(all_descrs):
    # Compute the bitstrings in the EffectInfo,
    # bitstring_{readonly,write}_descrs_{fieldd,arrays,interiordescrs},
    # and for each FieldDescrs and ArrayDescrs compute 'ei_index'.
    # Each bit in the bitstrings says whether this Descr is present in
    # this EffectInfo or not.  We try to share the value of 'ei_index'
    # across multiple Descrs if they always give the same answer (in
    # PyPy, it reduces the length of the bitstrings from 4000+ to
    # 373).
    from rpython.jit.codewriter.policy import log

    log("compute_bitstrings:")
    effectinfos = []
    descrs = {'fields': set(), 'arrays': set(), 'interiorfields': set()}
    for descr in all_descrs:
        if hasattr(descr, 'get_extra_info'):
            ei = descr.get_extra_info()
            if ei is None:
                continue
            if ei._readonly_descrs_fields is None:
                for key in descrs:
                    assert getattr(ei, '_readonly_descrs_' + key) is None
                    assert getattr(ei, '_write_descrs_' + key) is None
                    setattr(ei, 'bitstring_readonly_descrs_' + key, None)
                    setattr(ei, 'bitstring_write_descrs_' + key, None)
            else:
                effectinfos.append(ei)
                for key in descrs:
                    descrs[key].update(getattr(ei, '_readonly_descrs_' + key))
                    descrs[key].update(getattr(ei, '_write_descrs_' + key))
        else:
            descr.ei_index = sys.maxint
    log("  %d effectinfos:" % (len(effectinfos),))
    for key in sorted(descrs):
        log("    %d descrs for %s" % (len(descrs[key]), key))

    seen = set()
    for key in descrs:
        all_sets = []
        for descr in descrs[key]:
            eisetr = [ei for ei in effectinfos
                         if descr in getattr(ei, '_readonly_descrs_' + key)]
            eisetw = [ei for ei in effectinfos
                         if descr in getattr(ei, '_write_descrs_' + key)]
            # these are the set of all ei such that this descr is in
            # ei._readonly_descrs or ei._write_descrs
            eisetr = frozenset(eisetr)
            eisetw = frozenset(eisetw)
            all_sets.append((descr, eisetr, eisetw))

        # heuristic to reduce the total size of the bitstrings: start with
        # numbering the descrs that are seen in many EffectInfos.  If instead,
        # by lack of chance, such a descr had a high number, then all these
        # EffectInfos' bitstrings would need to store the same high number.
        def size_of_both_sets((d, r, w)):
            return len(r) + len(w)
        all_sets.sort(key=size_of_both_sets, reverse=True)

        mapping = {}
        for (descr, eisetr, eisetw) in all_sets:
            assert descr.ei_index == sys.maxint    # not modified yet
            descr.ei_index = mapping.setdefault((eisetr, eisetw), len(mapping))

        for ei in effectinfos:
            bitstrr = [descr.ei_index
                           for descr in getattr(ei, '_readonly_descrs_' + key)]
            bitstrw = [descr.ei_index
                           for descr in getattr(ei, '_write_descrs_' + key)]
            assert sys.maxint not in bitstrr
            assert sys.maxint not in bitstrw
            bitstrr = bitstring.make_bitstring(bitstrr)
            bitstrw = bitstring.make_bitstring(bitstrw)
            setattr(ei, 'bitstring_readonly_descrs_' + key, bitstrr)
            setattr(ei, 'bitstring_write_descrs_' + key, bitstrw)
            seen.add(bitstrr)
            seen.add(bitstrw)

    if seen:
        mean_length = float(sum(len(x) for x in seen)) / len(seen)
        max_length = max(len(x) for x in seen)
        log("-> %d bitstrings, mean length %.1f, max length %d" % (
            len(seen), mean_length, max_length))
Exemplo n.º 2
0
def compute_bitstrings(all_descrs):
    # Compute the bitstrings in the EffectInfo,
    # bitstring_{readonly,write}_descrs_{fieldd,arrays,interiordescrs},
    # and for each FieldDescrs and ArrayDescrs compute 'ei_index'.
    # Each bit in the bitstrings says whether this Descr is present in
    # this EffectInfo or not.  We try to share the value of 'ei_index'
    # across multiple Descrs if they always give the same answer (in
    # PyPy, it reduces the length of the bitstrings from 4000+ to
    # 373).
    from rpython.jit.codewriter.policy import log

    log("compute_bitstrings:")
    effectinfos = []
    descrs = {'fields': set(), 'arrays': set(), 'interiorfields': set()}
    for descr in all_descrs:
        if hasattr(descr, 'get_extra_info'):
            ei = descr.get_extra_info()
            if ei is None:
                continue
            if ei._readonly_descrs_fields is None:
                for key in descrs:
                    assert getattr(ei, '_readonly_descrs_' + key) is None
                    assert getattr(ei, '_write_descrs_' + key) is None
                    setattr(ei, 'bitstring_readonly_descrs_' + key, None)
                    setattr(ei, 'bitstring_write_descrs_' + key, None)
            else:
                effectinfos.append(ei)
                for key in descrs:
                    descrs[key].update(getattr(ei, '_readonly_descrs_' + key))
                    descrs[key].update(getattr(ei, '_write_descrs_' + key))
        else:
            descr.ei_index = sys.maxint
    log("  %d effectinfos:" % (len(effectinfos), ))
    for key in sorted(descrs):
        log("    %d descrs for %s" % (len(descrs[key]), key))

    seen = set()
    for key in descrs:
        all_sets = []
        for descr in descrs[key]:
            eisetr = [
                ei for ei in effectinfos
                if descr in getattr(ei, '_readonly_descrs_' + key)
            ]
            eisetw = [
                ei for ei in effectinfos
                if descr in getattr(ei, '_write_descrs_' + key)
            ]
            # these are the set of all ei such that this descr is in
            # ei._readonly_descrs or ei._write_descrs
            eisetr = frozenset(eisetr)
            eisetw = frozenset(eisetw)
            all_sets.append((descr, eisetr, eisetw))

        # heuristic to reduce the total size of the bitstrings: start with
        # numbering the descrs that are seen in many EffectInfos.  If instead,
        # by lack of chance, such a descr had a high number, then all these
        # EffectInfos' bitstrings would need to store the same high number.
        def size_of_both_sets((d, r, w)):
            return len(r) + len(w)

        all_sets.sort(key=size_of_both_sets, reverse=True)

        mapping = {}
        for (descr, eisetr, eisetw) in all_sets:
            assert descr.ei_index == sys.maxint  # not modified yet
            descr.ei_index = mapping.setdefault((eisetr, eisetw), len(mapping))

        for ei in effectinfos:
            bitstrr = [
                descr.ei_index
                for descr in getattr(ei, '_readonly_descrs_' + key)
            ]
            bitstrw = [
                descr.ei_index for descr in getattr(ei, '_write_descrs_' + key)
            ]
            assert sys.maxint not in bitstrr
            assert sys.maxint not in bitstrw
            bitstrr = bitstring.make_bitstring(bitstrr)
            bitstrw = bitstring.make_bitstring(bitstrw)
            setattr(ei, 'bitstring_readonly_descrs_' + key, bitstrr)
            setattr(ei, 'bitstring_write_descrs_' + key, bitstrw)
            seen.add(bitstrr)
            seen.add(bitstrw)

    if seen:
        mean_length = float(sum(len(x) for x in seen)) / len(seen)
        max_length = max(len(x) for x in seen)
        log("-> %d bitstrings, mean length %.1f, max length %d" %
            (len(seen), mean_length, max_length))