Skip to content
New issue

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

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

Already on GitHub? # to your account

[NFC] Refactor Heap2Local logic #6473

Merged
merged 11 commits into from
Apr 6, 2024
Merged

Conversation

kripken
Copy link
Member

@kripken kripken commented Apr 4, 2024

Separate the escape analysis portion from the part that does the optimization.
We do still record information during the analysis phase, but at least this makes
the separation clearer, and will also allow analysis without necessarily optimizing.

@kripken kripken requested a review from tlively April 4, 2024 22:08
// Analyze an allocation to see if it escapes or not. We receive a Rewriter
// instance on which we store important information as we go, which will be
// necessary if we optimize later.
bool escapes(StructNew* allocation, Rewriter& rewriter) {
Copy link
Member

Choose a reason for hiding this comment

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

It's odd that the analysis depends on the rewriter. Would it be much work to factor out the parts of the rewriter that the analysis uses as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's more a matter of efficiency. To do this in a single pass versus two passes, it makes sense to check for escaping while we note what we need to fix up if we do find nothing escapes.

Copy link
Member

Choose a reason for hiding this comment

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

Right, I don't mean that we should do this in more passes, but it would be nice to move rewriter.sets and rewriter.reaches out of the rewriter and into the analyzer instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, interesting. Yeah, maybe a larger refactoring is worthwhile here. I'll look into that and update this PR with my findings.

@kripken
Copy link
Member Author

kripken commented Apr 5, 2024

Ok, I did a larger refactoring here that I think improves things significantly.

There is now a core EscapeAnalysis class that does the actual analysis, and a separate optimizer that optimizer, and a separate parent that manages the relationship between them.

Most code did not change or only changed slightly as fields were moved around. Unfortunately the reordering of code causes the diff to be large.

This remains NFC.

Also make a few things const in the utilities this uses.

@kripken
Copy link
Member Author

kripken commented Apr 5, 2024

Btw, my goal in this refactoring is to make this pass also optimize arrays and not just structs.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +548 to +552
// Maps indexes in the struct to the local index that will replace them.
std::vector<Index> localIndexes;

// In rare cases we may need to refinalize, see below.
bool refinalize = false;
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 move these to be above the constructor so they are defined before they are used?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually I intentionally put them below. We often have that pattern that arriving stuff is on top and internals appear later, like here. In particular this way shows a nice separation between the two groups. I suppose a comment could also achieve the same goal, but again, I think it might be less consistent with other code?

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 I follow that pattern in the code I write 😅. Do we still follow that pattern when the internal data is used from the constructor? I do think it's generally nicer to have things defined before they are used, but I don't feel strongly about it here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can't say I've been thinking about whether the fields are used from the constructor or not... 😄 Maybe it is more readable that way, I'm not sure. I also don't feel very strongly here.

I already have a followup PR here, so maybe let me land this and we can consider the ordering here in that PR? This question will appear a second time there (I am adding another class much like this one).

Copy link
Member

Choose a reason for hiding this comment

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

Yep, sgtm.

@kripken kripken enabled auto-merge (squash) April 6, 2024 00:01
@kripken kripken merged commit 98f08ef into WebAssembly:main Apr 6, 2024
14 checks passed
@kripken kripken deleted the heap2local.nfc branch April 6, 2024 00:25
@gkdn gkdn mentioned this pull request Aug 31, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants