Author: Armin Rigo <[email protected]>
Branch:
Changeset: r59076:c782efd2c6a1
Date: 2012-11-23 21:07 +0100
http://bitbucket.org/pypy/pypy/changeset/c782efd2c6a1/
Log: Change _always_inline_=True to crash if inlining fails. Use
_always_inline_='try' to not crash if it fails. Fixes left and
right.
diff --git a/pypy/interpreter/astcompiler/optimize.py
b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -141,7 +141,7 @@
unrolling_unary_folders = unrolling_iterable(unary_folders.items())
for folder in binary_folders.values() + unary_folders.values():
- folder._always_inline_ = True
+ folder._always_inline_ = 'try'
del folder
opposite_compare_operations = misc.dict_to_switch({
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -144,7 +144,10 @@
actionflag = self.space.actionflag
if actionflag.get_ticker() < 0:
actionflag.action_dispatcher(self, frame) # slow path
- bytecode_trace_after_exception._always_inline_ = True
+ bytecode_trace_after_exception._always_inline_ = 'try'
+ # NB. this function is not inlined right now. backendopt.inline would
+ # need some improvements to handle this case, but it's not really an
+ # issue
def exception_trace(self, frame, operationerr):
"Trace function called upon OperationError."
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -320,7 +320,7 @@
Py_DecRef(space, arg)
unwrapper.func = func
unwrapper.api_func = api_function
- unwrapper._always_inline_ = True
+ unwrapper._always_inline_ = 'try'
return unwrapper
unwrapper_catch = make_unwrapper(True)
@@ -625,7 +625,7 @@
pypy_debug_catch_fatal_exception()
rffi.stackcounter.stacks_counter -= 1
return retval
- callable._always_inline_ = True
+ callable._always_inline_ = 'try'
wrapper.__name__ = "wrapper for %r" % (callable, )
return wrapper
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -797,7 +797,7 @@
wordshift += 1
z._normalize()
return z
- rshift._always_inline_ = True # It's so fast that it's always benefitial.
+ rshift._always_inline_ = 'try' # It's so fast that it's always benefitial.
@jit.elidable
def and_(self, other):
diff --git a/pypy/rpython/lltypesystem/rffi.py
b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -250,7 +250,7 @@
return cast(lltype.Unsigned, res)
return res
wrapper._annspecialcase_ = 'specialize:ll'
- wrapper._always_inline_ = True
+ wrapper._always_inline_ = 'try'
# for debugging, stick ll func ptr to that
wrapper._ptr = funcptr
wrapper = func_with_new_name(wrapper, name)
@@ -772,7 +772,7 @@
"""
raw_buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
return raw_buf, lltype.nullptr(STRTYPE)
- alloc_buffer._always_inline_ = True # to get rid of the returned tuple
+ alloc_buffer._always_inline_ = 'try' # to get rid of the returned tuple
alloc_buffer._annenforceargs_ = [int]
# (char*, str, int, int) -> None
diff --git a/pypy/translator/backendopt/inline.py
b/pypy/translator/backendopt/inline.py
--- a/pypy/translator/backendopt/inline.py
+++ b/pypy/translator/backendopt/inline.py
@@ -676,6 +676,10 @@
n += 1
log.inlining("%d call sites instrumented" % n)
+def always_inline(graph):
+ return (hasattr(graph, 'func') and
+ getattr(graph.func, '_always_inline_', None))
+
def auto_inlining(translator, threshold=None,
callgraph=None,
call_count_pred=None,
@@ -701,8 +705,7 @@
while heap:
weight, _, graph = heap[0]
if not valid_weight.get(graph):
- if hasattr(graph, 'func') and \
- getattr(graph.func, '_always_inline_', None):
+ if always_inline(graph):
weight, fixed = 0.0, True
else:
weight, fixed = heuristic(graph)
@@ -710,7 +713,7 @@
heapreplace(heap, (weight, -len(callers[graph]), graph))
valid_weight[graph] = True
if not fixed:
- try_again[graph] = True
+ try_again[graph] = 'initial'
continue
if weight >= threshold:
@@ -745,8 +748,8 @@
call_count_pred, cleanup=False)
to_cleanup[parentgraph] = True
res = bool(subcount)
- except CannotInline:
- try_again[graph] = True
+ except CannotInline, e:
+ try_again[graph] = str(e)
res = CannotInline
if res is True:
count += subcount
@@ -762,6 +765,15 @@
del try_again[parentgraph]
heappush(heap, (0.0, -len(callers[parentgraph]),
parentgraph))
valid_weight[parentgraph] = False
+
+ invalid = [(graph, msg) for graph, msg in try_again.items()
+ if always_inline(graph) is True]
+ if invalid:
+ message = '\n'.join([
+ "%s has _always_inline_=True but inlining failed:\n\t%s" %
+ (graph, msg) for (graph, msg) in invalid])
+ raise CannotInline(message)
+
for graph in to_cleanup:
cleanup_graph(graph)
return count
diff --git a/pypy/translator/backendopt/test/test_inline.py
b/pypy/translator/backendopt/test/test_inline.py
--- a/pypy/translator/backendopt/test/test_inline.py
+++ b/pypy/translator/backendopt/test/test_inline.py
@@ -759,3 +759,23 @@
eval_func = self.check_inline(g, f, [int, int])
res = eval_func([10, 173])
assert res == f(10, 173)
+
+ def test_cannot_inline_1(self):
+ from pypy.rpython.lltypesystem import lltype, rffi
+ for attr in [None, 'try', True]:
+ def h1(n):
+ return lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+ if attr is not None:
+ h1._always_inline_ = attr
+ def f(x):
+ try:
+ return h1(x)
+ except Exception:
+ return lltype.nullptr(rffi.INTP.TO)
+ #
+ def compile():
+ self.check_auto_inlining(f, [int])
+ if attr is True:
+ py.test.raises(CannotInline, compile)
+ else:
+ compile() # assert does not raise
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit