Source

pypy / pypy / translator / backendopt / removeassert.py

Full commit
Armin Rigo 25d7c9a 
Armin Rigo d6449de 
Armin Rigo 92b73ec 
Armin Rigo d6449de 
Armin Rigo 92b73ec 

Armin Rigo 25d7c9a 
Armin Rigo 92b73ec 



Armin Rigo e3c229c 
Armin Rigo 92b73ec 
Armin Rigo e3c229c 
Alexander Schrem… 869676d 
Armin Rigo 92b73ec 
Armin Rigo 25d7c9a 




Armin Rigo 92b73ec 



Armin Rigo e3c229c 

Armin Rigo f5ff92f 
Armin Rigo 25d7c9a 

Armin Rigo f5ff92f 
Armin Rigo cc2fd22 
Alexander Schrem… 869676d 


Armin Rigo 25d7c9a 


Alexander Schrem… 869676d 
Alexander Schrem… 8a60825 

Armin Rigo 25d7c9a 
Armin Rigo d6449de 
Maciej Fijalkows… 756cbdf 












Armin Rigo 92b73ec 




Armin Rigo 25d7c9a 





Armin Rigo f5ff92f 
Armin Rigo 25d7c9a 

Armin Rigo d6449de 













Armin Rigo 25d7c9a 







from pypy.objspace.flow.model import Constant, checkgraph, c_last_exception
from pypy.rpython.rtyper import LowLevelOpList, inputconst
from pypy.translator.simplify import eliminate_empty_blocks, join_blocks
#from pypy.translator.simplify import transform_dead_op_vars
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import rclass
from pypy.translator.backendopt.support import log


def remove_asserts(translator, graphs):
    rtyper = translator.rtyper
    excdata = rtyper.exceptiondata
    clsdef = translator.annotator.bookkeeper.getuniqueclassdef(AssertionError)
    ll_AssertionError = excdata.get_standard_ll_exc_instance(rtyper, clsdef)
    total_count = [0, 0]

    for graph in graphs:
        count = 0
        morework = True
        while morework:
            morework = False
            eliminate_empty_blocks(graph)
            join_blocks(graph)
            for link in graph.iterlinks():
                if (link.target is graph.exceptblock
                    and isinstance(link.args[1], Constant)
                    and link.args[1].value == ll_AssertionError):
                    if kill_assertion_link(graph, link):
                        count += 1
                        morework = True
                        break
                    else:
                        total_count[0] += 1
                        if translator.config.translation.verbose:
                            log.removeassert("cannot remove an assert from %s" % (graph.name,))
        if count:
            # now melt away the (hopefully) dead operation that compute
            # the condition
            total_count[1] += count
            if translator.config.translation.verbose:
                log.removeassert("removed %d asserts in %s" % (count, graph.name))
            checkgraph(graph)
            #transform_dead_op_vars(graph, translator)
    total_count = tuple(total_count)
    if total_count[0] == 0:
        if total_count[1] == 0:
            msg = None
        else:
            msg = "Removed %d asserts" % (total_count[1],)
    else:
        if total_count[1] == 0:
            msg = "Could not remove %d asserts" % (total_count[0],)
        else:
            msg = "Could not remove %d asserts, but removed %d asserts." % total_count
    if msg is not None:
        log.removeassert(msg)


def kill_assertion_link(graph, link):
    block = link.prevblock
    exits = list(block.exits)
    if len(exits) <= 1:
        return False
    remove_condition = len(exits) == 2
    if block.exitswitch == c_last_exception:
        if link is exits[0]:
            return False       # cannot remove the non-exceptional path
    else:
        if block.exitswitch.concretetype is not lltype.Bool:   # a switch
            remove_condition = False
        else:
            # common case: if <cond>: raise AssertionError
            # turn it into a debug_assert operation
            assert remove_condition
            newops = LowLevelOpList()
            if link.exitcase:
                v = newops.genop('bool_not', [block.exitswitch],
                                 resulttype = lltype.Bool)
            else:
                v = block.exitswitch
            msg = "assertion failed in %s" % (graph.name,)
            c_msg = inputconst(lltype.Void, msg)
            newops.genop('debug_assert', [v, c_msg])
            block.operations.extend(newops)

    exits.remove(link)
    if remove_condition:
        # condition no longer necessary
        block.exitswitch = None
        exits[0].exitcase = None
        exits[0].llexitcase = None
    block.recloseblock(*exits)
    return True