Closed Bug 1269440 Opened 8 years ago Closed 3 years ago

Twiddle compiler flags and measure impacts on APK size.

Categories

(Firefox for Android Graveyard :: General, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED INCOMPLETE

People

(Reporter: mrrrgn, Unassigned, NeedInfo)

Details

Lars Bergstrom mentioned that Mozilla Research recently shrunk their binaries by ~20% just by modifying gcc/llvm flags. It would be worthwhile to poke around with Android builds and see if we can free up some bytes with minimal effort.
s/their binaries/rust\/servo/
Lars - Do you have more details? What flags?
Flags: needinfo?(larsberg)
Mark, 

I'll have to defer to Gabor Loki (loki@inf.u-szeged.hu) and his group at the University of Szeged here! Gabor, I know the Servo notes aren't written up yet, but do you have any initial info that we can pass on to Mark for what specific flags and tricks you've used to reduce Servo's binary size?

We're working with his group at the University of Szeged, which owns the CSiBE (https://github.com/szeged/csibe) code size benchmarking suites used by GCC and LLVM. They've done also done some ARM code size reduction work for WebKit in the past, too.

I'll get one of them here on bugzilla and ni? them shortly.
Hi All,

Well, I can admit that it's not rocket scientist what we did with Servo.
As you might know Servo contains several c and c++ libraries, some rust ones and of course the engine itself in rust. The compilation is done with gcc and rustc and at the end everything is built into a single standalone binary.

We just checked the current Servo's build environment and saw each projects are optimized for speed (using -O3 and opt-level=3). So, the easiest thing was to change the optimization for code size.

You can do it by changing the compile flags for every dependencies and Servo itself, or you can use compiler wrapper (like one from CSiBE: https://github.com/szeged/csibe/blob/master/bin/compiler.py ). Either way, changing a compilation flags in a project is the first step to reduce the code size. :)

Here is some preliminary results what we've measured changing the compilation flags (relative to default optimizations):

Android
Change, CXX flags                              ,  Rustc flags
 0.29%, <no change>                            , -C opt-level=2  (this can be done simple in Servo)
12.53%, -Os                                    , -C opt-level=2 -C llvm-args=-inline-threshold=25 -C llvm-args=-unroll-threshold=50
12.73%, -Os -ffunction-sections -fdata-sections, -C opt-level=2 -C llvm-args=-inline-threshold=25 -C llvm-args=-unroll-threshold=50

x86_64
Change, CXX flags,  Rustc flags
(default binary)
25.89%, -Os      , -C opt-level=2 -C llvm-args=-inline-threshold=25 -C llvm-args=-unroll-threshold=50
(stripped)
10.50%, -Os      , -C opt-level=2 -C llvm-args=-inline-threshold=25 -C llvm-args=-unroll-threshold=50

Currently we are working two main topics:
* one is to create a script which tries out several possible compiler optimizations for Servo (using CSiBE),
* the other is that we are working on two LLVM passes which reduce code size (procedure abstraction and local factoring).

If I have more detailed information about them I will share with you.

On the other hand we are interested in you opinion and experiences about this topic. :)
Flags: needinfo?(larsberg)
A quick update on this topic:
* I have updated my old greedy script which tries out compiler flag candidates to optimize code size (even more than the simple -Os flag can do).
* The best result was 13.36% code size save on android with these flags:
* C/CXX flags:
** -Os -ffunction-sections -finline-limit=1 -fdata-sections -fno-if-conversion -fno-thread-jumps -fomit-frame-pointer -fno-schedule-insns
* Rustc/LLVM flags:
** -C llvm-args=-inline-threshold=5 -C llvm-args=-loop-unswitch-threshold=1 -C llvm-args=-disable-tail-duplicate -C llvm-args=-unroll-threshold=10 -C llvm-args=-disable-cgp-select2branch

I hope you can use these flags (or any other combination of them) to optimize your code size.
glandium, are you or anyone else on the build team interested in incorporating these changes to our build system? It would be amazing to see this reduction in APK size!
tracking-fennec: --- → ?
Flags: needinfo?(mh+mozilla)
We were already using -Os, so I think the big changes from your flags would be that it basically disables inlining, right (through -finline-limit=1)? I am not sure that's something we want to do, as I would expect a noticeable performance penalty. I don't know why you would want -fno-thread-jumps, as it doesn't look like that should really affect code size. I don't really know what no-if-conversion and no-schedule-insns do.
(In reply to Gabor Loki from comment #5)
> A quick update on this topic:
> * I have updated my old greedy script which tries out compiler flag
> candidates to optimize code size (even more than the simple -Os flag can do).
> * The best result was 13.36% code size save on android with these flags:
> * C/CXX flags:
> ** -Os -ffunction-sections -finline-limit=1 -fdata-sections
> -fno-if-conversion -fno-thread-jumps -fomit-frame-pointer -fno-schedule-insns
> * Rustc/LLVM flags:
> ** -C llvm-args=-inline-threshold=5 -C llvm-args=-loop-unswitch-threshold=1
> -C llvm-args=-disable-tail-duplicate -C llvm-args=-unroll-threshold=10 -C
> llvm-args=-disable-cgp-select2branch
> 
> I hope you can use these flags (or any other combination of them) to
> optimize your code size.

Gabor, silly question, but you ran this against Firefox for Android or Servo for Android?
tracking-fennec: ? → ---
With respect to comment 5 ^
Flags: needinfo?(loki)
We're already building with those flags: -Os -ffunction-sections -fdata-sections -fomit-frame-pointer

As for the remaining ones:
 -finline-limit=1 is virtually equivalent to -fno-inline. That sounds bad for performance.
 -fno-if-conversion disables the use of branch-less tests. IOW, this will increase the number of branches, and that can have a bad impact on performance too.
 -fno-thread-jumps doesn't sound, from the description of it, like it should save a lot in terms of space. I'd expect it to have a performance impact too.
 -fno-schedule-insns effectively does nothing at -Os (-fschedule-insns is only enabled at -O2 and -O3 according to gcc docs)
Flags: needinfo?(mh+mozilla)
We have completed our launch of our new Firefox on Android. The development of the new versions use GitHub for issue tracking. If the bug report still reproduces in a current version of [Firefox on Android nightly](https://play.google.com/store/apps/details?id=org.mozilla.fenix) an issue can be reported at the [Fenix GitHub project](https://github.com/mozilla-mobile/fenix/). If you want to discuss your report please use [Mozilla's chat](https://wiki.mozilla.org/Matrix#Connect_to_Matrix) server https://chat.mozilla.org and join the [#fenix](https://chat.mozilla.org/#/room/#fenix:mozilla.org) channel.
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → INCOMPLETE
Product: Firefox for Android → Firefox for Android Graveyard
You need to log in before you can comment on or make changes to this bug.