Source

pypy / pypy / translator / backendopt / all.py

Full commit
Eric van Riet Pa… 3ba1c35 
Carl Friedrich B… 36aa9f3 
Armin Rigo d34d273 
Samuele Pedroni b1b6145 
Armin Rigo 75c489c 
Carl Friedrich B… 9ecb307 
Eric van Riet Pa… 6e73b93 
Armin Rigo 7bc2027 
Samuele Pedroni b1b6145 
Armin Rigo 92b73ec 
Samuele Pedroni 2864506 
Antonio Cuni 687086c 
Jean-Philippe St… c775f9d 
Armin Rigo d34d273 
Armin Rigo 7bc2027 
Samuele Pedroni 783e403 

Samuele Pedroni 18525b4 















Samuele Pedroni e6ee2c5 
Carl Friedrich B… 596ecf8 


Armin Rigo 92b73ec 
Eric van Riet Pa… 3ba1c35 
Armin Rigo d6449de 
Carl Friedrich B… 596ecf8 
Carl Friedrich B… e820a54 
Armin Rigo d34d273 

Armin Rigo fd7ffe8 

Armin Rigo d34d273 
Carl Friedrich B… e820a54 
Carl Friedrich B… 9ecb307 
Carl Friedrich B… c1acdb0 
Carl Friedrich B… 9ecb307 
Carl Friedrich B… 596ecf8 
Samuele Pedroni a298800 
Eric van Riet Pa… 3ba1c35 
Antonio Cuni 687086c 


Carl Friedrich B… f12ceee 








Armin Rigo 7bc2027 
Samuele Pedroni 23dd071 





Eric van Riet Pa… 3394668 
Samuele Pedroni 23dd071 




Carl Friedrich B… 9ecb307 
Guido Wesdorp f74fa3d 
Samuele Pedroni 18525b4 
Guido Wesdorp f74fa3d 



Samuele Pedroni 0ccfc65 
Guido Wesdorp f74fa3d 
Samuele Pedroni 18525b4 
Armin Rigo d6449de 
Samuele Pedroni 18525b4 










Samuele Pedroni b1b6145 
Samuele Pedroni 18525b4 
Carl Friedrich B… e820a54 
Carl Friedrich B… ad795ac 
Samuele Pedroni 18525b4 
Carl Friedrich B… 9ecb307 
Jean-Philippe St… c775f9d 


Samuele Pedroni 18525b4 















Armin Rigo d6449de 
Armin Rigo 75c489c 
Carl Friedrich B… 596ecf8 
Alexander Schrem… 42df47a 
Armin Rigo d34d273 
Alexander Schrem… 8a60825 
Carl Friedrich B… 9ecb307 
Carl Friedrich B… e820a54 
Carl Friedrich B… 9ecb307 


Samuele Pedroni 23dd071 

Armin Rigo d34d273 

Samuele Pedroni 0ccfc65 
Samuele Pedroni 18525b4 




Samuele Pedroni 0ccfc65 
Samuele Pedroni 18525b4 
Samuele Pedroni 0ccfc65 

Antonio Cuni b52b749 
Samuele Pedroni 0ccfc65 

Guido Wesdorp f74fa3d 



Samuele Pedroni b1b6145 
Samuele Pedroni 18525b4 
Samuele Pedroni b1b6145 
Samuele Pedroni 0ccfc65 






Alexander Schrem… 8a60825 
Samuele Pedroni b1b6145 
Samuele Pedroni 0ccfc65 


from pypy.translator.backendopt.raisingop2direct_call import raisingop2direct_call
from pypy.translator.backendopt import removenoops
from pypy.translator.backendopt import inline
from pypy.translator.backendopt.malloc import remove_mallocs
from pypy.translator.backendopt.constfold import constant_fold_graph
from pypy.translator.backendopt.stat import print_statistics
from pypy.translator.backendopt.merge_if_blocks import merge_if_blocks
from pypy.translator import simplify
from pypy.translator.backendopt import mallocprediction
from pypy.translator.backendopt.removeassert import remove_asserts
from pypy.translator.backendopt.support import log
from pypy.translator.backendopt.checkvirtual import check_virtual_methods
from pypy.translator.backendopt.storesink import storesink_graph
from pypy.objspace.flow.model import checkgraph

INLINE_THRESHOLD_FOR_TEST = 33

def get_function(dottedname):
    parts = dottedname.split('.')
    module = '.'.join(parts[:-1])
    name = parts[-1]
    try:
        mod = __import__(module, {}, {}, ['__doc__'])
    except ImportError, e:
        raise Exception, "Import error loading %s: %s" % (dottedname, e)

    try:
        func = getattr(mod, name)
    except AttributeError:
        raise Exception, "Function %s not found in module" % dottedname

    return func

def backend_optimizations(translator, graphs=None, secondary=False, **kwds):
    # sensible keywords are
    # raisingop2direct_call, inline_threshold, mallocs
    # merge_if_blocks, constfold, heap2stack
    # clever_malloc_removal, remove_asserts

    config = translator.config.translation.backendopt.copy(as_default=True)
    config.set(**kwds)

    if graphs is None:
        graphs = translator.graphs
    for graph in graphs:
        assert not hasattr(graph, '_seen_by_the_backend')

    if config.print_statistics:
        print "before optimizations:"
        print_statistics(translator.graphs[0], translator, "per-graph.txt")

    if config.raisingop2direct_call:
        raisingop2direct_call(translator, graphs)

    if translator.rtyper.type_system.name == 'ootypesystem':
        check_virtual_methods()

    if config.remove_asserts:
        constfold(config, graphs)
        remove_asserts(translator, graphs)

    if config.really_remove_asserts:
        for graph in graphs:
            removenoops.remove_debug_assert(graph)
        # the dead operations will be killed by the remove_obvious_noops below

    # remove obvious no-ops
    def remove_obvious_noops():
        for graph in graphs:
            removenoops.remove_same_as(graph)
            simplify.eliminate_empty_blocks(graph)
            simplify.transform_dead_op_vars(graph, translator)
            removenoops.remove_duplicate_casts(graph, translator)

        if config.print_statistics:
            print "after no-op removal:"
            print_statistics(translator.graphs[0], translator)

    remove_obvious_noops()

    if config.inline or config.mallocs:
        heuristic = get_function(config.inline_heuristic)
        if config.inline:
            threshold = config.inline_threshold
        else:
            threshold = 0
        inline_malloc_removal_phase(config, translator, graphs,
                                    threshold,
                                    inline_heuristic=heuristic)
        constfold(config, graphs)

    if config.clever_malloc_removal:
        threshold = config.clever_malloc_removal_threshold
        heuristic = get_function(config.clever_malloc_removal_heuristic)        
        log.inlineandremove("phase with threshold factor: %s" % threshold)
        log.inlineandremove("heuristic: %s.%s" % (heuristic.__module__,
                                                  heuristic.__name__))
        count = mallocprediction.clever_inlining_and_malloc_removal(
            translator, graphs,
            threshold = threshold,
            heuristic=heuristic)
        log.inlineandremove("removed %d simple mallocs in total" % count)
        constfold(config, graphs)
        if config.print_statistics:
            print "after clever inlining and malloc removal"
            print_statistics(translator.graphs[0], translator)        

    if config.storesink:
        for graph in graphs:
            storesink_graph(graph)

    if config.profile_based_inline and not secondary:
        threshold = config.profile_based_inline_threshold
        heuristic = get_function(config.profile_based_inline_heuristic)
        inline.instrument_inline_candidates(graphs, threshold)
        counters = translator.driver_instrument_result(
            config.profile_based_inline)
        n = len(counters)
        def call_count_pred(label):
            if label >= n:
                return False
            return counters[label] > 250 # xxx introduce an option for this
        inline_malloc_removal_phase(config, translator, graphs,
                                    threshold,
                                    inline_heuristic=heuristic,
                                    call_count_pred=call_count_pred)
    constfold(config, graphs)

    if config.merge_if_blocks:
        log.mergeifblocks("starting to merge if blocks")
        for graph in graphs:
            merge_if_blocks(graph, translator.config.translation.verbose)

    if config.print_statistics:
        print "after if-to-switch:"
        print_statistics(translator.graphs[0], translator)

    remove_obvious_noops()

    for graph in graphs:
        checkgraph(graph)

def constfold(config, graphs):
    if config.constfold:
        for graph in graphs:
            constant_fold_graph(graph)    

def inline_malloc_removal_phase(config, translator, graphs, inline_threshold,
                                inline_heuristic,
                                call_count_pred=None):

    type_system = translator.rtyper.type_system.name
    # inline functions in each other
    if inline_threshold:
        log.inlining("phase with threshold factor: %s" % inline_threshold)
        log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__,
                                           inline_heuristic.__name__))

        inline.auto_inline_graphs(translator, graphs, inline_threshold,
                                  heuristic=inline_heuristic,
                                  call_count_pred=call_count_pred)

        if config.print_statistics:
            print "after inlining:"
            print_statistics(translator.graphs[0], translator)

    # vaporize mallocs
    if config.mallocs:
        log.malloc("starting malloc removal")
        remove_mallocs(translator, graphs, type_system)

        if config.print_statistics:
            print "after malloc removal:"
            print_statistics(translator.graphs[0], translator)