-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Returns values up to 2*usize by value #77434
Returns values up to 2*usize by value #77434
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
r? @nagisa |
@bors try @rust-timer queue cc @eddyb |
Awaiting bors try build completion |
⌛ Trying commit b01694e with merge af826c3de514b426f1172de2883db4a251e45c65... |
Perf runs only on x86_64 so there should be no noticeable change. |
☀️ Try build successful - checks-actions, checks-azure |
Queued af826c3de514b426f1172de2883db4a251e45c65 with parent 8fe73e8, future comparison URL. |
Finished benchmarking try commit (af826c3de514b426f1172de2883db4a251e45c65): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
match spec.target_spec().arch.as_str() { | ||
// System-V will pass return values up to 128 bits in RAX/RDX. | ||
"x86_64" => Size::from_bits(128), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping removing this string comparison would help perf but I guess not?
if is_ret { call::max_ret_by_val(cx) } else { Pointer.size(cx) }; | ||
// Return structures up to 2 pointers in size by value, matching `ScalarPair`. LLVM | ||
// will usually return these in 2 registers, which is more efficient than by-ref. | ||
let max_by_val_size = if is_ret { Pointer.size(cx) * 2 } else { Pointer.size(cx) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it makes sense to limit this to returns, but also whether 3
might work better than 2
as the multiplier.
But I guess there's a risk it might get downgraded from registers... I really wish LLVM modeled ABIs more precisely so we can control that.
@bors r+ |
📌 Commit b01694e has been approved by |
☀️ Test successful - checks-actions, checks-azure |
Pass arguments up to 2*usize by value In rust-lang#77434 (comment), `@eddyb` said: > I wonder if it makes sense to limit this to returns [...] Let's do a perf run and find out. It seems the `extern "C"` ABI will pass arguments up to 2*usize in registers: https://godbolt.org/z/n8E6zc. (modified from rust-lang#26494 (comment)) r? `@nagisa`
Addresses #76986 (comment) and #76986 (comment) by doing the optimization on all targets.
This matches what we do for functions returning
&[T]
and other fat pointers, so it should be Harmless™