[pypy-commit] pypy canraise-assertionerror: branch to experiment with canraise not raising for assertion error
fijal
pypy.commits at gmail.com
Thu Nov 2 06:38:38 EDT 2017
Author: fijal
Branch: canraise-assertionerror
Changeset: r92903:904915e5425e
Date: 2017-11-02 11:37 +0100
http://bitbucket.org/pypy/pypy/changeset/904915e5425e/
Log: branch to experiment with canraise not raising for assertion error
diff --git a/rpython/translator/backendopt/canraise.py b/rpython/translator/backendopt/canraise.py
--- a/rpython/translator/backendopt/canraise.py
+++ b/rpython/translator/backendopt/canraise.py
@@ -1,6 +1,9 @@
from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper import rclass
from rpython.tool.ansi_print import AnsiLogger
from rpython.translator.backendopt import graphanalyze
+from rpython.flowspace import model as flowmodel
log = AnsiLogger("canraise")
@@ -8,6 +11,14 @@
class RaiseAnalyzer(graphanalyze.BoolGraphAnalyzer):
ignore_exact_class = None
+ def __init__(self, translator):
+ graphanalyze.BoolGraphAnalyzer.__init__(self, translator)
+ ed = translator.rtyper.exceptiondata
+ self.ll_assert_error = ed.get_standard_ll_exc_instance_by_class(
+ AssertionError)
+ self.ll_not_impl_error = ed.get_standard_ll_exc_instance_by_class(
+ NotImplementedError)
+
def do_ignore_memory_error(self):
self.ignore_exact_class = MemoryError
@@ -25,6 +36,12 @@
analyze_exceptblock = None # don't call this
def analyze_exceptblock_in_graph(self, graph, block, seen=None):
+ def producer(block, v):
+ for op in block.operations:
+ if op.result is v:
+ return op
+ assert False
+
if self.ignore_exact_class is not None:
from rpython.translator.backendopt.ssa import DataFlowFamilyBuilder
dff = DataFlowFamilyBuilder(graph)
@@ -38,7 +55,34 @@
# it doesn't count. We'll see the place that really
# raises the exception in the first place.
return False
- return True
+ # find all the blocks leading to the raise block
+ blocks = []
+ for candidate in graph.iterblocks():
+ if len(candidate.exits) != 1:
+ continue
+ if candidate.exits[0].target is block:
+ blocks.append(candidate)
+ ignored = 0
+ import pdb
+ pdb.set_trace()
+ for preblock in blocks:
+ exc_val = preblock.exits[0].args[1]
+ if isinstance(exc_val, flowmodel.Constant):
+ exc = exc_val.value
+ else:
+ # find the producer
+ op = producer(preblock, exc_val)
+ if op.opname == 'cast_pointer':
+ exc_val = op.args[0]
+ op = producer(preblock, exc_val)
+ if op.opname != 'same_as':
+ # something strange, return True
+ return True
+ exc = op.args[0].value
+ p = lltype.cast_pointer(rclass.OBJECTPTR, exc)
+ if p == self.ll_assert_error or p == self.ll_not_impl_error:
+ ignored += 1
+ return ignored < len(blocks)
# backward compatible interface
def can_raise(self, op, seen=None):
diff --git a/rpython/translator/backendopt/test/test_canraise.py b/rpython/translator/backendopt/test/test_canraise.py
--- a/rpython/translator/backendopt/test/test_canraise.py
+++ b/rpython/translator/backendopt/test/test_canraise.py
@@ -1,7 +1,8 @@
+from rpython.conftest import option
+from rpython.rtyper.lltypesystem import rffi
from rpython.translator.translator import TranslationContext, graphof
from rpython.translator.backendopt.canraise import RaiseAnalyzer
from rpython.translator.backendopt.all import backend_optimizations
-from rpython.conftest import option
class TestCanRaise(object):
def translate(self, func, sig):
@@ -253,3 +254,48 @@
ra.do_ignore_memory_error() # but it's potentially a KeyError
result = ra.analyze_direct_call(graphof(t, h))
assert result
+
+ def test_charp2str(self):
+ def f(a):
+ return len(rffi.charp2str(a))
+
+ t, ra = self.translate(f, [rffi.CCHARP])
+ ra.do_ignore_memory_error()
+ result = ra.analyze_direct_call(graphof(t, f))
+ assert not result # ignore AssertionError
+
+ def test_calls_raise_not_impl(self):
+ def raising():
+ raise NotImplementedError
+
+ def not_raising():
+ pass
+
+ def f(a):
+ if a == 15:
+ raising()
+ else:
+ not_raising()
+
+ t, ra = self.translate(f, [int])
+ ra.do_ignore_memory_error()
+ result = ra.analyze_direct_call(graphof(t, f))
+ assert not result # ignore AssertionError
+
+ def test_calls_raise_assertion_error(self):
+ def raising():
+ assert False
+
+ def not_raising():
+ pass
+
+ def f(a):
+ if a == 15:
+ raising()
+ else:
+ not_raising()
+
+ t, ra = self.translate(f, [int])
+ ra.do_ignore_memory_error()
+ result = ra.analyze_direct_call(graphof(t, f))
+ assert not result # ignore AssertionError
More information about the pypy-commit
mailing list