Skip to content

assorted performance optimizations - #6724

Closed
thestinger wants to merge 8 commits into
rust-lang:incomingfrom
thestinger:swap_fast
Closed

assorted performance optimizations#6724
thestinger wants to merge 8 commits into
rust-lang:incomingfrom
thestinger:swap_fast

Conversation

@thestinger

Copy link
Copy Markdown
Contributor

Passing higher alignment values gives the optimization passes more freedom since it can copy in larger chunks. This change results in rustc outputting the same post-optimization IR as clang for swaps and most copies excluding the lack of information about padding.

Code snippet:

#[inline(never)]fnswap<T>(x:&mutT,y:&mutT){
util::swap(x, y);}

Original IR (for int):

defineinternalfastccvoid@_ZN9swap_283417_a71830ca3ed2d65d3_00E(i64*, i64*) #1 {
static_allocas:
%2 = icmpeqi64*%0, %1bri1%2, label%_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit, label%3; <label>:3 ; preds = %static_allocas%4 = loadi64*%0, align1%5 = loadi64*%1, align1storei64%5, i64*%0, align1storei64%4, i64*%1, align1brlabel%_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit
_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit: ; preds = %3, %static_allocasretvoid
}

After #6710:

defineinternalfastccvoid@_ZN9swap_283017_a71830ca3ed2d65d3_00E(i64*nocapture, i64*nocapture) #1 {
static_allocas:
%2 = loadi64*%0, align1%3 = loadi64*%1, align1storei64%3, i64*%0, align1storei64%2, i64*%1, align1retvoid
}

After this change:

defineinternalfastccvoid@_ZN9swap_283017_a71830ca3ed2d65d3_00E(i64*nocapture, i64*nocapture) #1 {
static_allocas:
%2 = loadi64*%0, align8%3 = loadi64*%1, align8storei64%3, i64*%0, align8storei64%2, i64*%1, align8retvoid
}

Another example:

#[inline(never)]fnset<T>(x:&mutT,y:T){*x = y;}

Before, with (int, int) (align 1):

defineinternalfastccvoid@_ZN8set_282517_8fa972e3f9e451983_00E({ i64, i64 }* nocapture, { i64, i64 }* nocapture) #1 {
static_allocas:
%2 = bitcast { i64, i64 }* %1toi8*%3 = bitcast { i64, i64 }* %0toi8*tailcallvoid@llvm.memcpy.p0i8.p0i8.i64(i8*%3, i8*%2, i6416, i321, i1false)
retvoid
}

After, with (int, int) (align 8):

defineinternalfastccvoid@_ZN8set_282617_8fa972e3f9e451983_00E({ i64, i64 }* nocapture, { i64, i64 }* nocapture) #1 {
static_allocas:
%2 = bitcast { i64, i64 }* %1toi8*%3 = bitcast { i64, i64 }* %0toi8*tailcallvoid@llvm.memcpy.p0i8.p0i8.i64(i8*%3, i8*%2, i6416, i328, i1false)
retvoid
}

@thestinger

Copy link
Copy Markdown
ContributorAuthor

Note that since #6742 landed, the parameters are also marked as noalias so the IR is strictly better than clang, but it results in pretty much the same assembly for these cases.

@graydon

Copy link
Copy Markdown
Contributor

This is wonderful. Thanks.

bors added a commit that referenced this pull request May 27, 2013
Passing higher alignment values gives the optimization passes more freedom since it can copy in larger chunks. This change results in rustc outputting the same post-optimization IR as clang for swaps and most copies excluding the lack of information about padding.
Code snippet:
```rust
#[inline(never)]
fn swap<T>(x: &mut T, y: &mut T) {
util::swap(x, y);
}
```
Original IR (for `int`):
```llvm
define internal fastcc void @_ZN9swap_283417_a71830ca3ed2d65d3_00E(i64*, i64*) #1 {
static_allocas:
%2 = icmp eq i64* %0, %1
br i1 %2, label %_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit, label %3
; <label>:3 ; preds = %static_allocas
%4 = load i64* %0, align 1
%5 = load i64* %1, align 1
store i64 %5, i64* %0, align 1
store i64 %4, i64* %1, align 1
br label %_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit
_ZN4util9swap_283717_a71830ca3ed2d65d3_00E.exit: ; preds = %3, %static_allocas
ret void
}
```
After #6710:
```llvm
define internal fastcc void @_ZN9swap_283017_a71830ca3ed2d65d3_00E(i64* nocapture, i64* nocapture) #1 {
static_allocas:
%2 = load i64* %0, align 1
%3 = load i64* %1, align 1
store i64 %3, i64* %0, align 1
store i64 %2, i64* %1, align 1
ret void
}
```
After this change:
```llvm
define internal fastcc void @_ZN9swap_283017_a71830ca3ed2d65d3_00E(i64* nocapture, i64* nocapture) #1 {
static_allocas:
%2 = load i64* %0, align 8
%3 = load i64* %1, align 8
store i64 %3, i64* %0, align 8
store i64 %2, i64* %1, align 8
ret void
}
```
Another example:
```rust
#[inline(never)]
fn set<T>(x: &mut T, y: T) {
*x = y;
}
```
Before, with `(int, int)` (align 1):
```llvm
define internal fastcc void @_ZN8set_282517_8fa972e3f9e451983_00E({ i64, i64 }* nocapture, { i64, i64 }* nocapture) #1 {
static_allocas:
%2 = bitcast { i64, i64 }* %1 to i8*
%3 = bitcast { i64, i64 }* %0 to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 1, i1 false)
ret void
}
```
After, with `(int, int)` (align 8):
```llvm
define internal fastcc void @_ZN8set_282617_8fa972e3f9e451983_00E({ i64, i64 }* nocapture, { i64, i64 }* nocapture) #1 {
static_allocas:
%2 = bitcast { i64, i64 }* %1 to i8*
%3 = bitcast { i64, i64 }* %0 to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
ret void
}
```
@borsbors closed this May 27, 2013
flip1995 pushed a commit to flip1995/rust that referenced this pull request Mar 11, 2021
Refactor types lints
Ref rust-lang#6724.
As described in rust-lang#6724, `types.rs` contains many groups inside it.
In this PR, I reorganize the lints of the `types` group into their own modules.
changelog: none
flip1995 pushed a commit to flip1995/rust that referenced this pull request Mar 11, 2021
Refactor casts lint
Ref: rust-lang#6724
Changes:
1. Separate the `casts` group from the `types` group.
2. Reorganize the lints of the `casts` group into their own modules.
Notes:
1. I didn't `fix` rust-lang#6874 in order to maintain this PR as small as possible.
---
changelog: none
flip1995 pushed a commit to flip1995/rust that referenced this pull request Mar 25, 2021
Refactor unit types
Ref: rust-lang#6724
r? `@flip1995`
Changes:
1. Extract `unit_types` from `types` group.
2. Move lints of `unit_types` to their own modules.
Notes:
Other lints of `unit_types` is still scattered around the `clippy_lints`, e.g. `result_unit_err` or `option_map_unit_fn`.
These should be addressed in another PR.
changelog: none
flip1995 pushed a commit to flip1995/rust that referenced this pull request Apr 8, 2021
Refactor types
r? `@flip1995`
This is the last PR to closerust-lang#6724 🎉
Also, this fixesrust-lang#6936.
changelog: `vec_box`: Fix FN in `const` or `static`
changelog: `linkedlist`: Fix FN in `const` or `static`
changelog: `option_option`: Fix FN in `const` or `static`
U007D pushed a commit to U007D/rust-mos that referenced this pull request Aug 21, 2026
6724: Fix `diagnostics` subcommand, look at all modules r=jonas-schievink a=jonas-schievink
The `diagnostics` subcommand used to only compute diagnostics for `lib.rs` / the root module of all workspace crates. This fixed it and makes it look at every module.
bors r+
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@thestinger@graydon@bors