Skip to content

Commit

Permalink
Cleanup backwards compat layer for use_vectorcall and use_method_vect…
Browse files Browse the repository at this point in the history
…orcall (#18548)

Followup to #18341 and #18546

We only support Python 3.9+, so `PyObject_Vectorcall` and
`PyObject_VectorcallMethod` are always available. Remove backwards
compatibility layer.
  • Loading branch information
cdce8p authored Jan 31, 2025
1 parent bec0dd3 commit acfd53a
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 45 deletions.
4 changes: 0 additions & 4 deletions mypyc/codegen/emit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
REG_PREFIX,
STATIC_PREFIX,
TYPE_PREFIX,
use_vectorcall,
)
from mypyc.ir.class_ir import ClassIR, all_concrete_classes
from mypyc.ir.func_ir import FuncDecl
Expand Down Expand Up @@ -398,9 +397,6 @@ def _emit_attr_bitmap_update(
if value:
self.emit_line("}")

def use_vectorcall(self) -> bool:
return use_vectorcall(self.capi_version)

def emit_undefined_attr_check(
self,
rtype: RType,
Expand Down
17 changes: 4 additions & 13 deletions mypyc/codegen/emitclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ def native_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
return f"{NATIVE_PREFIX}{fn.cname(emitter.names)}"


def wrapper_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
return f"{PREFIX}{fn.cname(emitter.names)}"


# We maintain a table from dunder function names to struct slots they
# correspond to and functions that generate a wrapper (if necessary)
# and return the function name to stick in the slot.
Expand Down Expand Up @@ -137,12 +133,7 @@ def wrapper_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:


def generate_call_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
if emitter.use_vectorcall():
# Use vectorcall wrapper if supported (PEP 590).
return "PyVectorcall_Call"
else:
# On older Pythons use the legacy wrapper.
return wrapper_slot(cl, fn, emitter)
return "PyVectorcall_Call"


def slot_key(attr: str) -> str:
Expand Down Expand Up @@ -333,7 +324,7 @@ def emit_line() -> None:
flags = ["Py_TPFLAGS_DEFAULT", "Py_TPFLAGS_HEAPTYPE", "Py_TPFLAGS_BASETYPE"]
if generate_full:
flags.append("Py_TPFLAGS_HAVE_GC")
if cl.has_method("__call__") and emitter.use_vectorcall():
if cl.has_method("__call__"):
fields["tp_vectorcall_offset"] = "offsetof({}, vectorcall)".format(
cl.struct_name(emitter.names)
)
Expand Down Expand Up @@ -381,7 +372,7 @@ def generate_object_struct(cl: ClassIR, emitter: Emitter) -> None:
seen_attrs: set[tuple[str, RType]] = set()
lines: list[str] = []
lines += ["typedef struct {", "PyObject_HEAD", "CPyVTableItem *vtable;"]
if cl.has_method("__call__") and emitter.use_vectorcall():
if cl.has_method("__call__"):
lines.append("vectorcallfunc vectorcall;")
bitmap_attrs = []
for base in reversed(cl.base_mro):
Expand Down Expand Up @@ -576,7 +567,7 @@ def generate_setup_for_class(
field = emitter.bitmap_field(i)
emitter.emit_line(f"self->{field} = 0;")

if cl.has_method("__call__") and emitter.use_vectorcall():
if cl.has_method("__call__"):
name = cl.method_decl("__call__").cname(emitter.names)
emitter.emit_line(f"self->vectorcall = {PREFIX}{name};")

Expand Down
3 changes: 1 addition & 2 deletions mypyc/codegen/emitmodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
TYPE_VAR_PREFIX,
shared_lib_name,
short_id_from_name,
use_vectorcall,
)
from mypyc.errors import Errors
from mypyc.ir.func_ir import FuncIR
Expand Down Expand Up @@ -1106,7 +1105,7 @@ def is_fastcall_supported(fn: FuncIR, capi_version: tuple[int, int]) -> bool:
if fn.class_name is not None:
if fn.name == "__call__":
# We can use vectorcalls (PEP 590) when supported
return use_vectorcall(capi_version)
return True
# TODO: Support fastcall for __init__.
return fn.name != "__init__"
return True
Expand Down
3 changes: 1 addition & 2 deletions mypyc/codegen/emitwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
NATIVE_PREFIX,
PREFIX,
bitmap_name,
use_vectorcall,
)
from mypyc.ir.class_ir import ClassIR
from mypyc.ir.func_ir import FUNC_STATICMETHOD, FuncIR, RuntimeArg
Expand Down Expand Up @@ -173,7 +172,7 @@ def generate_wrapper_function(
arg_ptrs += [f"&obj_{groups[ARG_STAR2][0].name}" if groups[ARG_STAR2] else "NULL"]
arg_ptrs += [f"&obj_{arg.name}" for arg in reordered_args]

if fn.name == "__call__" and use_vectorcall(emitter.capi_version):
if fn.name == "__call__":
nargs = "PyVectorcall_NARGS(nargs)"
else:
nargs = "nargs"
Expand Down
10 changes: 0 additions & 10 deletions mypyc/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,6 @@ def short_name(name: str) -> str:
return name


def use_vectorcall(capi_version: tuple[int, int]) -> bool:
# We can use vectorcalls to make calls on Python 3.8+ (PEP 590).
return capi_version >= (3, 8)


def use_method_vectorcall(capi_version: tuple[int, int]) -> bool:
# We can use a dedicated vectorcall API to call methods on Python 3.9+.
return capi_version >= (3, 9)


def get_id_from_name(name: str, fullname: str, line: int) -> str:
"""Create a unique id for a function.
Expand Down
22 changes: 8 additions & 14 deletions mypyc/irbuild/ll_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
MIN_LITERAL_SHORT_INT,
MIN_SHORT_INT,
PLATFORM_SIZE,
use_method_vectorcall,
use_vectorcall,
)
from mypyc.errors import Errors
from mypyc.ir.class_ir import ClassIR, all_concrete_classes
Expand Down Expand Up @@ -898,11 +896,9 @@ def py_call(
Use py_call_op or py_call_with_kwargs_op for Python function call.
"""
if use_vectorcall(self.options.capi_version):
# More recent Python versions support faster vectorcalls.
result = self._py_vector_call(function, arg_values, line, arg_kinds, arg_names)
if result is not None:
return result
result = self._py_vector_call(function, arg_values, line, arg_kinds, arg_names)
if result is not None:
return result

# If all arguments are positional, we can use py_call_op.
if arg_kinds is None or all(kind == ARG_POS for kind in arg_kinds):
Expand Down Expand Up @@ -977,13 +973,11 @@ def py_method_call(
arg_names: Sequence[str | None] | None,
) -> Value:
"""Call a Python method (non-native and slow)."""
if use_method_vectorcall(self.options.capi_version):
# More recent Python versions support faster vectorcalls.
result = self._py_vector_method_call(
obj, method_name, arg_values, line, arg_kinds, arg_names
)
if result is not None:
return result
result = self._py_vector_method_call(
obj, method_name, arg_values, line, arg_kinds, arg_names
)
if result is not None:
return result

if arg_kinds is None or all(kind == ARG_POS for kind in arg_kinds):
# Use legacy method call API
Expand Down

0 comments on commit acfd53a

Please sign in to comment.