8000 gh-120323: Constant fold entire attribute loads by Fidget-Spinner · Pull Request #120344 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-120323: Constant fold entire attribute loads #120344

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

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
only remove second type check
  • Loading branch information
Fidget-Spinner committed Jun 11, 2024
commit 8c0d50c40b9710cdd64b8f20378bf95a833e5214
1 change: 1 addition & 0 deletions Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ typedef int(*PyType_WatchCallback)(PyTypeObject *);
PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback);
PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id);
PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type);
PyAPI_FUNC(int) PyType_IsWatched(int watcher_id, PyObject *type);
PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type);

/* Attempt to assign a version tag to the given type.
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1494,11 +1494,11 @@ def testfunc(n):
""")
exec(src, ns, ns)
testfunc = ns['testfunc']
_, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD + 1)
_, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD * 2)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertNotIn("_LOAD_ATTR_CLASS_0", uops)
self.assertNotIn("_CHECK_ATTR_CLASS", uops)
self.assertLessEqual(uops.count("_LOAD_ATTR_CLASS_0"), 1)
self.assertLessEqual(uops.count("_CHECK_ATTR_CLASS"), 1)


if __name__ == "__main__":
Expand Down
11 changes: 11 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,17 @@ PyType_Watch(int watcher_id, PyObject* obj)
return 0;
}

int
PyType_IsWatched(int watcher_id, PyObject* obj)
{
if (!PyType_Check(obj)) {
PyErr_SetString(PyExc_ValueError, "Cannot check non-type");
return -1;
}
PyTypeObject *type = (PyTypeObject *)obj;
return type->tp_watched & (1 << watcher_id);
}

int
PyType_Unwatch(int watcher_id, PyObject* obj)
{
Expand Down
4 changes: 4 additions & 0 deletions Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ dummy_func(void) {

op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
assert(type_version);
if (sym_is_type_subclass(owner)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be necessary.
If this case isn't handled correctly by sym_matches_type_version and sym_set_type_version below, then those need fixing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this because it might have a type version that matches, but is a type subclass, not a normal object.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_GUARD_TYPE_VERSION guards the version number of owner's class. Whether owner is a class or not seems irrelevant.

ctx->done = true;
break;
}
if (sym_matches_type_version(owner, type_version)) {
REPLACE_OP(this_instr, _NOP, 0, 0);
} else {
Expand Down
4 changes: 4 additions & 0 deletions Python/optimizer_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions Python/optimizer_symbols.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#define NOT_NULL 1 << 1
#define NO_SPACE 1 << 2
#define IS_TYPE_SUBCLASS 1 << 3
#define HAS_TYPE_VERSION_GUARD 1 << 4
#define HAS_CLASS_VERSION_GUARD 1 << 5

#ifdef Py_DEBUG
static inline int get_lltrace(void) {
Expand Down Expand Up @@ -199,15 +201,15 @@ _Py_uop_sym_set_const(_Py_UOpsContext *ctx, _Py_UopsSymbol *sym, PyObject *const

if (PyType_Check(const_val)) {
sym_set_flag(sym, IS_TYPE_SUBCLASS);
_Py_BloomFilter_Add(ctx->dependencies, const_val);
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)const_val);
sym->type_version = ((PyTypeObject *)const_val)->tp_version_tag;
if (PyType_IsWatched(TYPE_WATCHER_ID, const_val)) {
sym->type_version = ((PyTypeObject *)const_val)->tp_version_tag;
}
}
else {
PyTypeObject *ty = Py_TYPE(const_val);
_Py_BloomFilter_Add(ctx->dependencies, ty);
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)ty);
sym->type_version = ty->tp_version_tag;
if (PyType_IsWatched(TYPE_WATCHER_ID, (PyObject *)ty)) {
sym->type_version = ty->tp_version_tag;
}
}

}
Expand Down
Loading
0