Skip to content

Serious binary size regression on ARMv7-M on nightly-2018-02-11 #49260

Closed
@japaric

Description

@japaric

STR

$ git clone https://github.com/japaric/stable-embedded-rust

$ cd stable-embedded-rust

$ git checkout 7cc87cff95b2d90b5cab258d912cf4692130312f
  • nightly-2018-02-11 or newer
$ rustc -V
rustc 1.26.0-nightly (75af15ee6 2018-03-20)

$ # NOTE you need to have {gcc,libnewlib}-arm-none-eabi installed
$ xargo build --example minimal --target thumbv7m-none-eabi
$ xargo build --example minimal --target thumbv7m-none-eabi --release

$ arm-none-eabi-size target/thumbv7m-none-eabi/{debug,release}/examples/minimal
   text    data     bss     dec     hex filename
    530       0       0     530     212 target/thumbv7m-none-eabi/debug/examples/minimal
    662       0       0     662     296 target/thumbv7m-none-eabi/release/examples/minimal

$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto
   text    data     bss     dec     hex filename
   1114       0       0    1114     45a target/thumbv7m-none-eabi/release/examples/minimal
  • nightly-2018-02-10
$ rustc -V
rustc 1.25.0-nightly (3bcda48a3 2018-02-09)

$ # NOTE you need to have {gcc,libnewlib}-arm-none-eabi installed
$ xargo build --example minimal --target thumbv7m-none-eabi
$ xargo build --example minimal --target thumbv7m-none-eabi --release

$ arm-none-eabi-size target/thumbv7m-none-eabi/{debug,release}/examples/minimal
   text    data     bss     dec     hex filename
    530       0       0     530     212 target/thumbv7m-none-eabi/debug/examples/minimal
    160       0       0     160      a0 target/thumbv7m-none-eabi/release/examples/minimal

$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto

$ arm-none-eabi-size target/thumbv7m-none-eabi/release/examples/minimal
   text    data     bss     dec     hex filename
    130       0       0     130      82 target/thumbv7m-none-eabi/release/examples/minimal

Basically as of nightly-2018-02-11 dev profile is better than release profile and that's better than
compiling with LTO ...

Also, in this case, today's LTO produces a 1 KB (756%) bigger binary that using LTO on
nightly-2018-02-10 . On a more real world example I see a 2.4 KB (21%) increase in binary size.

LLVM?

One notorious difference between nightly-2018-02-10 and newer nightlies is that
nightly-2018-02-10 is using LLVM 4 and everything newer than that is using LLVM 6. However, I
don't think LLVM is fully to blame: today's rustc produces much more LLVM IR than it did on
2018-02-10.

$ # nightly-2018-02-10
$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto --emit=llvm-ir
$ wc $(find -name '*.ll')
  72  393 2748 ./target/thumbv7m-none-eabi/release/examples/minimal-dd6a4842433c97ae.ll


$ # nightly-2018-03-20
$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto --emit=llvm-ir
$ wc $(find -name '*.ll')
  707  5942 34041 ./target/thumbv7m-none-eabi/release/examples/minimal-52848323be89f9be.ll

IR files for reference.

thinLTO / parallel codegen?

The problem doesn't seem to be caused by thinLTO or parallel codegen either. I tried this with both
nightly-2018-02-11 and nightly-2018-03-20:

$ tail Cargo.toml
[profile.release]
codegen-units = 1
incremental = false

$ cat .cargo/config
[target.thumbv7m-none-eabi]
runner = "arm-none-eabi-gdb" # Not required; just used for testing
rustflags = [
  "-Z", "thinlto=no", # <- NEW!
  "-C", "link-arg=-Tlink.x",
  "-C", "link-arg=-nostartfiles",
  "-C", "link-arg=-march=armv7-m",
  "-C", "link-arg=-mthumb",
]

It got slightly better but it's not on parity with nightly-2018-02-10

$ # nightly-2018-02-11
$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto

$ arm-none-eabi-size target/thumbv7m-none-eabi/release/examples/minimal
   text    data     bss     dec     hex filename
    598       0       0     598     256 target/thumbv7m-none-eabi/release/examples/minimal


$ # nightly-2018-03-20
$ xargo rustc --example minimal --target thumbv7m-none-eabi --release -- -C lto

$ arm-none-eabi-size target/thumbv7m-none-eabi/release/examples/minimal
   text    data     bss     dec     hex filename
    598       0       0     598     256 target/thumbv7m-none-eabi/release/examples/minimal

ARMv6-M

Also none of this seems to affect ARMv6-M.

$ # nightly-2018-03-20
$ xargo rustc --example minimal --target thumbv6m-none-eabi --release -- -C lto

$ arm-none-eabi-size target/thumbv6m-none-eabi/release/examples/minimal
   text    data     bss     dec     hex filename
    112       0       0     112      70 target/thumbv6m-none-eabi/release/examples/minimal

This is with the .cargo/config and Cargo.toml stuff undone.


cc @alexcrichton @nagisa any clue about what could be going wrong here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions