Identical code folding

Author: KobzolCreated Jul 8, 2022Updated Dec 20, 2024

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:

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

I measured the binary size change for the following program:

rust
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

Source: johnthagen/min-sized-rust