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

Add #[rustc_box] and use it inside alloc #97293

Merged
merged 3 commits into from
Jun 2, 2022
Merged

Conversation

est31
Copy link
Member

@est31 est31 commented May 22, 2022

This commit adds an alternative content boxing syntax, and uses it inside alloc.

#![feature(box_syntax)]

fn foo() {
    let foo = box bar;
}

is equivalent to

#![feature(rustc_attrs)]

fn foo() {
    let foo = #[rustc_box] Box::new(bar);
}

The usage inside the very performance relevant code in
liballoc is the only remaining relevant usage of box syntax
in the compiler (outside of tests, which are comparatively easy to port).

box syntax was originally designed to be used by all Rust
developers. This introduces a replacement syntax more tailored
to only being used inside the Rust compiler, and with it,
lays the groundwork for eventually removing box syntax.

Earlier work by @nbdd0121 to lower Box::new to box during THIR -> MIR building ran into borrow checker problems, requiring the lowering to be adjusted in a way that led to performance regressions. The proposed change in this PR lowers #[rustc_box] Box::new -> box in the AST -> HIR lowering step, which is way earlier in the compiler, and thus should cause less issues both performance wise as well as regarding type inference/borrow checking/etc. Hopefully, future work can move the lowering further back in the compiler, as long as there are no performance regressions.

@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 22, 2022
@rust-highfive
Copy link
Collaborator

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with r? rust-lang/libs-api @rustbot label +T-libs-api -T-libs to request review from a libs-api team reviewer. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@rust-highfive
Copy link
Collaborator

r? @kennytm

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 22, 2022
@est31
Copy link
Member Author

est31 commented May 22, 2022

Oh right and I'd like a perf run for this.

@bors try

@bors
Copy link
Contributor

bors commented May 22, 2022

⌛ Trying commit 21b8f4c5732fa39970597845a14656dd92d5aa81 with merge c40cfb8bd5f0f25521b77d628fc502e48839db62...

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Member

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 22, 2022
@bors
Copy link
Contributor

bors commented May 22, 2022

⌛ Trying commit b3da9d276364534550d8f71c5b6f1c21d983b2ac with merge 7a4b510ef15bc589ea430b0bd23134b71f4e25d2...

@bors
Copy link
Contributor

bors commented May 23, 2022

☀️ Try build successful - checks-actions
Build commit: 7a4b510ef15bc589ea430b0bd23134b71f4e25d2 (7a4b510ef15bc589ea430b0bd23134b71f4e25d2)

@rust-timer
Copy link
Collaborator

Queued 7a4b510ef15bc589ea430b0bd23134b71f4e25d2 with parent b2eed72, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (7a4b510ef15bc589ea430b0bd23134b71f4e25d2): comparison url.

Instruction count

  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: 😿 relevant regressions found
Regressions 😿
(primary)
Regressions 😿
(secondary)
Improvements 🎉
(primary)
Improvements 🎉
(secondary)
All 😿 🎉
(primary)
count1 0 7 0 0 0
mean2 N/A 0.6% N/A N/A N/A
max N/A 0.9% N/A N/A N/A

Max RSS (memory usage)

Results
  • Primary benchmarks: 🎉 relevant improvements found
  • Secondary benchmarks: mixed results
Regressions 😿
(primary)
Regressions 😿
(secondary)
Improvements 🎉
(primary)
Improvements 🎉
(secondary)
All 😿 🎉
(primary)
count1 0 1 3 7 3
mean2 N/A 3.7% -3.0% -1.6% -3.0%
max N/A 3.7% -3.6% -3.0% -3.6%

Cycles

Results
  • Primary benchmarks: 🎉 relevant improvements found
  • Secondary benchmarks: 😿 relevant regression found
Regressions 😿
(primary)
Regressions 😿
(secondary)
Improvements 🎉
(primary)
Improvements 🎉
(secondary)
All 😿 🎉
(primary)
count1 0 1 2 0 2
mean2 N/A 1.7% -2.4% N/A -2.4%
max N/A 1.7% -2.6% N/A -2.6%

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

Footnotes

  1. number of relevant changes 2 3

  2. the arithmetic mean of the percent change 2 3

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 23, 2022
@est31
Copy link
Member Author

est31 commented May 23, 2022

Hmm so the only serious regression is in deep-vector, which is basically a single vec! call with a lot of zeroes inside. Otherwise it's all improvements. And the deep-vector regression is not that bad, considering that it used to be 20% in the earlier PR:
#87781 (comment)

Instruction count, with regressions only in deep-vector:

Screenshot_20220523_125458

Max RSS, a lot of improvements with regressions in one place:

Screenshot_20220523_125950

So this is IMO quite a good result.

@est31
Copy link
Member Author

est31 commented May 23, 2022

The weird thing is that these changes are still larger than I expected. After all, the differences are only at the start of the compilation pipeline. So regressions in later phases, which these mostly are, are a bit surprising.

One might think that the ucd library has the memory usage regression because of the many tables that it contains. And indeed it has many tables. But there is not a single usage of the vec! macro inside that library, instead it's statics... Which might mean that it's indeed due to the compiler having become more memory consuming for this specific workload, instead of passing different input to the compiler due to differences in the vec! macro.

For deep-vector, it's regressing in the same passes that it regressed back in the older attempt that just used Box::new plus a MIR pass at the end of the pipeline to recognize and special case it. But thankfully the regressions are much lower now.

Really bad deep-vector regressions in the older attempt

Screenshot_20220524_000945

Not so bad deep-vector regressions in the newer attempt upthread:

Screenshot_20220524_001157

The weird part is that this PR does not change anything what is being fed to LLVM. So why does LLVM take longer? No idea. I think I need to create a local build of the compiler as of this PR and play around with it to verify that the MIR etc. is all the same. Edit: plus, given that it's LLVM, there is also barely any Rust running in that pass so it also can't be some general issue of the rust-written part compiler being slower now, because it uses the (hypothetically) now-slower vec! or something like that.

@est31
Copy link
Member Author

est31 commented May 23, 2022

I've got an idea to narrow the performance changes down: what if one only changes the Box::new implementation? Requesting another perf run for this. And then one might do one with only vec using #[rustc_box].

@compiler-errors
Copy link
Member

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 24, 2022
@bors
Copy link
Contributor

bors commented May 24, 2022

⌛ Trying commit 704845b4efe169fa881bef052db59d163c74d433 with merge 6f102539baaab210a6d285cc923d5d22e4959ac0...

@est31
Copy link
Member Author

est31 commented May 31, 2022

Alright, the last commit is removed and pushed to a separate branch for possible future use. The PR is ready for review.

compiler/rustc_ast_lowering/src/expr.rs Outdated Show resolved Hide resolved
hir::ExprKind::Box(self.lower_expr(&inner))
let kind = hir::ExprKind::Box(self.lower_expr(&inner));
let hir_id = self.lower_node_id(e.id);
self.lower_attrs(hir_id, &e.attrs[1..]);
Copy link
Contributor

Choose a reason for hiding this comment

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

So this assumes that rustc_box is the first attribute? If rustc_box is assumed to be the only attribute, then we could just skip lowering attributes at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

My reasoning for assuming it was first was that rustc_box shouldn't appear so often and I wouldn't want to do a possibly expensive search over all attributes. Once we have rustc_box, it should be comparatively inexpensive to take care of the other attributes.

Copy link
Member Author

Choose a reason for hiding this comment

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

(When making that decision, I thought about doc attributes but function calls obviously don't have doc attributes so I was a bit misguided)

est31 added 2 commits June 1, 2022 02:28
This commit adds an alternative content boxing syntax,
and uses it inside alloc.

The usage inside the very performance relevant code in
liballoc is the only remaining relevant usage of box syntax
in the compiler (outside of tests, which are comparatively
easy to port).

box syntax was originally designed to be used by all Rust
developers. This introduces a replacement syntax more tailored
to only being used inside the Rust compiler, and with it,
lays the groundwork for eventually removing box syntax.
@est31
Copy link
Member Author

est31 commented Jun 1, 2022

r? @oli-obk

@rust-highfive rust-highfive assigned oli-obk and unassigned kennytm Jun 1, 2022
@oli-obk
Copy link
Contributor

oli-obk commented Jun 2, 2022

I'm surprised it wasn't possible to do on the THIR. Looking at the links you provided it looks like they didn't use a #[rustc_box] attribute. I'm fine merging this PR, but I think after it we should try again to move it to THIR -> MIR and eliminate the box keyword from HIR, too

@oli-obk
Copy link
Contributor

oli-obk commented Jun 2, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Jun 2, 2022

📌 Commit 0a24b94 has been approved by oli-obk

@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 Jun 2, 2022
@bors
Copy link
Contributor

bors commented Jun 2, 2022

⌛ Testing commit 0a24b94 with merge 20976ba...

@bors
Copy link
Contributor

bors commented Jun 2, 2022

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing 20976ba to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 2, 2022
@bors bors merged commit 20976ba into rust-lang:master Jun 2, 2022
@rustbot rustbot added this to the 1.63.0 milestone Jun 2, 2022
@bors bors mentioned this pull request Jun 2, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (20976ba): comparison url.

Instruction count

  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: 😿 relevant regression found
mean1 max count2
Regressions 😿
(primary)
N/A N/A 0
Regressions 😿
(secondary)
0.2% 0.2% 1
Improvements 🎉
(primary)
N/A N/A 0
Improvements 🎉
(secondary)
N/A N/A 0
All 😿🎉 (primary) N/A N/A 0

Max RSS (memory usage)

Results
  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: mixed results
mean1 max count2
Regressions 😿
(primary)
N/A N/A 0
Regressions 😿
(secondary)
2.8% 3.8% 4
Improvements 🎉
(primary)
N/A N/A 0
Improvements 🎉
(secondary)
-2.7% -3.4% 4
All 😿🎉 (primary) N/A N/A 0

Cycles

Results
  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: mixed results
mean1 max count2
Regressions 😿
(primary)
N/A N/A 0
Regressions 😿
(secondary)
2.7% 2.7% 1
Improvements 🎉
(primary)
N/A N/A 0
Improvements 🎉
(secondary)
-3.1% -3.1% 1
All 😿🎉 (primary) N/A N/A 0

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

Footnotes

  1. the arithmetic mean of the percent change 2 3

  2. number of relevant changes 2 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.