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

Split match exhaustiveness into two files #79284

Merged
merged 7 commits into from
Nov 28, 2020

Conversation

Nadrieril
Copy link
Member

I feel the constructor-related things in the _match module make enough sense on their own so I split them off. It makes _match feel less like a complicated mess. I'm not aware of PRs in progress against this module apart from my own so hopefully I'm not annoying too many people.
I have a lot of questions about the conventions in naming and modules around the compiler. Like, why is the module named _match? Could I rename it to usefulness maybe? Should deconstruct_pat be a submodule of _match since only _match uses it? Is it ok to move big piles of code around even if it makes git blame more difficult?

r? @varkor
@rustbot modify labels: +A-exhaustiveness-checking

@rustbot rustbot added the A-exhaustiveness-checking Relating to exhaustiveness / usefulness checking of patterns label Nov 22, 2020
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 22, 2020
@jyn514 jyn514 added C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 22, 2020
@mark-i-m
Copy link
Member

I have a lot of questions about the conventions in naming and modules around the compiler.

My guess is it was called _match because it's about exhaustiveness and the most obvious usecase is checking match expressions, but you can't name a module match because it is a keyword...

@Nadrieril
Copy link
Member Author

@mark-i-m but there's already check_match in the same folder :/ Maybe check_match appeared later

@bors
Copy link
Contributor

bors commented Nov 26, 2020

☔ The latest upstream changes (presumably #79441) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@varkor
Copy link
Member

varkor commented Nov 26, 2020

Sorry, I know this is predisposed to merge conflicts because of its size. I will try to review soon; I just need to set aside some time to look through the changes.

@Nadrieril
Copy link
Member Author

@varkor No worries. I'm just moving code around so it should be quick to review. Do you have an opinion on whether I could rename _match to usefulness while I'm at it?

@varkor
Copy link
Member

varkor commented Nov 26, 2020

I'd be happy changing the name to usefulness.rs, considering it's not just relevant to match.

@varkor
Copy link
Member

varkor commented Nov 26, 2020

I have a lot of questions about the conventions in naming and modules around the compiler. Like, why is the module named _match? Could I rename it to usefulness maybe? Should deconstruct_pat be a submodule of _match since only _match uses it? Is it ok to move big piles of code around even if it makes git blame more difficult?

I also wondered about the name (other than the point @mark-i-m raised about it denoting the match keyword); I'm not sure the exact reasoning (maybe one could trace their way back through git blame to deduce something of the motivation. I think it could be less confusing as usefulness. I don't have a strong opinion on whether it ought to be a submodule, so whichever you find more convenient. It's fine to refactor if it makes the code more readable: it makes git blame a little more awkward to use, but I think code readability is more important here.

I'm happy with the changes, once the merge conflicts have been addressed.

@Nadrieril
Copy link
Member Author

Fixed the conflict, and renamed _match.rs to usefulness.rs. We'll have to update the dev guide since it points to _match.

@varkor
Copy link
Member

varkor commented Nov 27, 2020

Upping the priority because this is liable to conflict.

@bors r+ p=1

@bors
Copy link
Contributor

bors commented Nov 27, 2020

📌 Commit 941c6ac has been approved by varkor

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 27, 2020
@bors
Copy link
Contributor

bors commented Nov 27, 2020

⌛ Testing commit 941c6ac with merge fd6b537...

@bors
Copy link
Contributor

bors commented Nov 28, 2020

☀️ Test successful - checks-actions
Approved by: varkor
Pushing fd6b537 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 28, 2020
@bors bors merged commit fd6b537 into rust-lang:master Nov 28, 2020
@rustbot rustbot added this to the 1.50.0 milestone Nov 28, 2020
@Nadrieril Nadrieril deleted the constructor-module branch November 28, 2020 02:15
@Nadrieril
Copy link
Member Author

Thanks!

@rylev
Copy link
Member

rylev commented Dec 3, 2020

@Nadrieril @varkor This change caused a very large performance regression in the match-stress-enum stress test. It's hard to tell from the diff what the actual changes in code were (vs simple relocation). We should probably look into what caused such a large regression.

@varkor
Copy link
Member

varkor commented Dec 3, 2020

Those are very significant. There weren't very many actual changes, so hopefully it should be possible to narrow down the issue. @Nadrieril: are you able to investigate this?

@Mark-Simulacrum
Copy link
Member

Note that a very plausible answer here is "CGU changed, inlining changed" -- modules are the basis for our CGU partitioning scheme, so splitting them can have outsized effects even if you're just moving code around. Where there any actual changes made or did we just move code around?

@varkor
Copy link
Member

varkor commented Dec 3, 2020

It was just code being moved around, so I imagine it was something like this.

@Mark-Simulacrum
Copy link
Member

Would be good to see if we can add a #[inline] attribute or otherwise help LLVM out a bit to mitigate the impact here.

@Nadrieril
Copy link
Member Author

Ouch, I did not think that moving code could have such an impact. Will investigate

@Nadrieril
Copy link
Member Author

I'm super confused: I just measured the same commit range locally and I see no difference at all. Must be something in my config.toml I guess? That's what's in it, and I deleted build entirely before starting to measure.

changelog-seen = 2
[llvm]
download-ci-llvm = true
assertions = true
[rust]
debug-logging = true
debuginfo-level-rustc = 1
incremental = true
deny-warnings = false

Could incremental be the culprit?

@Mark-Simulacrum
Copy link
Member

There's a few differences: incremental bumps CGU counts to one-per-module IIRC, and I think might disable some of the merging that happens normally? We also lower the ThinLTO import limit to 10 (from 100?) IIRC for LLVM when compiling incrementally, which you can manually set in config.toml (thin-to-instr-limit I believe).

@Nadrieril
Copy link
Member Author

I tried again and yup without incremental I can reproduce. Are you saying that incremental+thin-to-instr-limit=100 might reproduce too? Or do you think it's more probably the CGU counts stuff? I'd love a reproduction with incremental because it makes it way quicker to try things

@Mark-Simulacrum
Copy link
Member

Hm, not sure, and I don't recall what the limit actually is by default w/o incremental unfortunately (100 is just a guess).

@Nadrieril
Copy link
Member Author

Nadrieril commented Dec 3, 2020

config.toml.example says that the default value is 100. I tried with that and incremental and can't reproduce anymore. So it's something else. Will have to bisect without incremental then

@Nadrieril
Copy link
Member Author

Nadrieril commented Dec 3, 2020

Unsurprisingly the commit the broke perf is the one where I move half the code to a new file. Found a fix: #79680

bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 4, 2020
…as-schievink

Fix perf regression caused by rust-lang#79284

rust-lang#79284 only moved code around but this changed inlining and caused a large perf regression. This fixes it for me, though I'm less confident than usual because the regression was not observable with my usual (i.e. incremental) compilation settings.

r? `@Mark-Simulacrum`
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 22, 2020
…g, r=varkor

Clarify constructor splitting in exhaustiveness checking

I reworked the explanation of the algorithm completely to make it properly account for the various extensions we've added. This includes constructor splitting, which was previously not clearly included in the algorithm. This makes wildcards less magical; I added some detailed examples; and this distinguishes clearly between constructors that only make sense in patterns (like ranges) and those that make sense for values (like `Some`). This reformulation had been floating around in my mind for a while, and I'm quite happy with how it turned out. Let me know how you feel about it.
I also factored out all three cases of splitting (wildcards, ranges and slices) into dedicated structs to encapsulate the complicated bits.
I measured no perf impact but I don't trust my local measurements for refactors since rust-lang#79284.

r? `@varkor`
`@rustbot` modify labels: +A-exhaustiveness-checking
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-exhaustiveness-checking Relating to exhaustiveness / usefulness checking of patterns C-cleanup Category: PRs that clean code up or issues documenting cleanup. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants