Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup backwards compat layer for use_vectorcall and use_method_vectorcall #18548

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -892,11 +890,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 @@ -971,13 +967,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
Loading