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

Identical code folding #38

Open
Kobzol opened this issue Jul 8, 2022 · 2 comments
Open

Identical code folding #38

Kobzol opened this issue Jul 8, 2022 · 2 comments

Comments

@Kobzol
Copy link
Contributor

Kobzol commented Jul 8, 2022

Since Rust can't do polymorphization properly yet, using generics generates a lot of duplicated functions because of monomorphization. These functions take space in the binary, even though they have completely the same instructions.

Some linkers (gold, lld) can deduplicate these identical functions using Identical Code Folding, and thus reduce binary size (and potentially also improve usage of the i-cache).

You can specify this linker option using a linker flag, for example like this:

$ RUSTFLAGS="-Clink-args=-fuse-ld=lld -Clink-args=-Wl,--icf=all" cargo build

I measured the binary size change for the following program:

fn foo() {
    let mut a: Vec<u8> = vec![1, 2, 3];
    a.pop();

    let mut b: Vec<u32> = vec![1, 2, 3];
    b.pop();

    let mut c: Vec<i32> = vec![1, 2, 3];
    c.pop();
}

fn main() {
    foo();
}

Here are binary sizes are after running strip on them:

Linker Mode Binary size (B) ICF (Identical Code Folding)
gold debug 342696 No
gold debug 330408 Yes
gold release 322216 No
gold release 318120 Yes
lld debug 330968 No
lld debug 321840 Yes
lld release 310616 No
lld release 306848 Yes
@johnthagen
Copy link
Owner

johnthagen commented Jul 8, 2022

It would be interesting to see how this interacts with -Z build-std=std,panic_abort as then the linker might also be able to fold identical code in std as well? 🤔

@Kobzol
Copy link
Contributor Author

Kobzol commented Jul 8, 2022

I tried it, but it didn't change the binary size. I suppose that's expected, since the program links statically to libstd, the code of libstd is already inside the binary when ICF runs, so it's applied to it even without build-std. It's done on the linker/binary level, so it won't do much for libstd unless we link to it as a dynamic library I guess :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants