Commit 6b84a0fb authored by Stefan Behnel's avatar Stefan Behnel

enable method call optimisation on all simple Python calls as PyMethod_Check()...

enable method call optimisation on all simple Python calls as PyMethod_Check() should be cheap enough
parent 7ab811ce
......@@ -4837,7 +4837,21 @@ class PyMethodCallNode(SimpleCallNode):
arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
code.putln("%s = 0;" % arg_offset_cname)
code.putln("if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(%s))) {" % function)
if self.function.is_attribute and self.function.obj.type is not Builtin.type_type:
likely_method = 'likely'
elif self.function.is_name and self.function.cf_state:
# not an attribute itself, but might have been assigned from one (e.g. bound method)
for assignment in self.function.cf_state:
value = assignment.rhs
if value.is_attribute and value.obj.type.is_pyobject and value.obj.type is not Builtin.type_type:
likely_method = 'likely'
break
else:
likely_method = 'unlikely'
else:
likely_method = 'unlikely'
code.putln("if (CYTHON_COMPILING_IN_CPYTHON && %s(PyMethod_Check(%s))) {" % (likely_method, function))
code.putln("%s = PyMethod_GET_SELF(%s);" % (self_arg, function))
# the following is always true in Py3 (kept only for safety),
# but is false for unbound methods in Py2
......
......@@ -3763,18 +3763,7 @@ class FinalOptimizePhase(Visitor.CythonTransform, Visitor.NodeRefCleanupMixin):
node.function.type = node.function.entry.type
PyTypeObjectPtr = PyrexTypes.CPtrType(cython_scope.lookup('PyTypeObject').type)
node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr)
elif node.function.type.is_pyobject and node.function.type is not Builtin.type_type:
# we could do it for all calls, but attributes are most likely to result in a method call
function = node.function
likely_method = function.is_attribute
if not likely_method and function.is_name and function.cf_state:
# not an attribute itself, but might have been assigned from one (e.g. bound method)
for assignment in function.cf_state:
value = assignment.rhs
if value.is_attribute and value.obj.type.is_pyobject and value.obj.type is not Builtin.type_type:
likely_method = True
break
if likely_method:
elif node.is_temp and node.function.type.is_pyobject and node.function.type is not Builtin.type_type:
if isinstance(node.arg_tuple, ExprNodes.TupleNode) and not (
node.arg_tuple.mult_factor or (node.arg_tuple.is_literal and node.arg_tuple.args)):
node = self.replace(node, ExprNodes.PyMethodCallNode.from_node(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment