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

Conversation

Fidget-Spinner
Copy link
Member
@Fidget-Spinner Fidget-Spinner commented Jun 11, 2024

From the PR's test case. This constant folds entire code like:

class MyEnum:
    A = 1

def testfunc(n):
    for i in range(n):
        x = MyEnum.A
        y = MyEnum.A

To

class MyEnum:
    A = 1

def testfunc(n):
    for i in range(n):
        x = MyEnum.A
        y = 1

Using watchers.

At the moment, it's really limited and only constant folds simple class loads. In the future we can constant fold method descriptors and more.

@Fidget-Spinner Fidget-Spinner changed the title Constant fold entire attribute loads gh-120323: Constant fold entire attribute loads Jun 11, 2024
Copy link
Member
@markshannon markshannon left a comment

Choose a reason for hiding this comment

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

The optimization looks useful, and fits in nicely with other constant propagation/removal.

A couple of general rules to follow:

Avoid side effects in functions unless that function performs only that side effect.
Keep new features and refactoring in separate PRs, where possible.

@@ -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.

@@ -489,6 +486,65 @@ optimize_uops(

}

static inline bool
op_is_simple_load(int opcode) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we avoid mixing refactorings and adding new features?

remove_unneeded_uops coould do with cleaning up, but it should be done in another PR.

}

static bool
remove_simple_pops(int num_popped, _PyUOpInstruction *curr, _PyUOpInstruction *limit){
Copy link
Member

Choose a reason for hiding this comment

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

If this removes simple pops, as its name suggests, why does it return a bool?

@bedevere-app
Copy link
bedevere-app bot commented Jun 11, 2024

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

sym_set_is_a_class(owner);
PyTypeObject *type = _PyType_LookupByVersion(type_version);
if (type) {
if (sym_set_type_version(owner, type_version)) {
Copy link
Member

Choose a reason for hiding this comment

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

This records that the object's class has the version number, not that the object itself is a class and has a version number.

@markshannon
Copy link
Member

AFAICT, this PR does a number of things which would be better in their own PRs.

  1. Optimize away _CHECK_ATTR_CLASS using a type watcher.
  2. Rename _LOAD_ATTR_CLASS to _POP_TOP_LOAD_CONST_INLINE_WITH_NULL and optimize to the "borrow" form.
  3. Some ad-hoc improvements to the remove_unneeded_uops

Can you make these separate PRs, please?
2. could also include _LOAD_ATTR_METHOD_WITH_VALUES and any other uops that replace TOS with a constant (possibly pushing NULL).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0