
Firefox switching to clang-cl for Windows builds - sohkamyung
https://groups.google.com/forum/m/#!topic/mozilla.dev.platform/wwO48xXFx0A
======
glymor
A reply in the thread from David Major about performance:

 _" At the moment, performance is a mixed bag. Some tests are up and some are
down. In particular I believe Speedometer is down a few percent."_

 _" Note however that clang-cl is punching above its weight. These builds
currently have neither LTO nor PGO, while our MSVC builds use both of those.
Any regressions that we're seeing ought to be short-lived. Once we enable
LTO[1] and PGO[2], I expect clang to be a clear performance win."_

[1] "LTO (Link Time Optimization) is a method for achieving better runtime
performance through whole-program analysis and cross-module optimization."
[http://blog.llvm.org/2016/06/thinlto-scalable-and-
incrementa...](http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-
lto.html)

[2] PGO = Profile Guided Optimization

~~~
krasin
LTO can be particularly handy when doing devirtualization. Our experience
([1]) with Chromium demonstrated that there's a fair amount of virtual methods
which have exactly two implementation in the code: one for production and
another one for tests. While linking production code, it's trivial for this
optimization to spot that, replace a virtual call with regular invocation and
then often inline and allow for other in-place optimizations. In many cases of
the renderer (Blink), that gives 3%-7% speedup out of nowhere.

1\.
[https://bugs.chromium.org/p/chromium/issues/detail?id=580389...](https://bugs.chromium.org/p/chromium/issues/detail?id=580389#c25)

~~~
mehrdadn
Out of curiosity, why use virtual calls in those cases? Why not just have two
different implementation files -- one for tests, and one for production -- and
choose one based on which one you're doing? It seems like a win all around.

~~~
krasin
>Out of curiosity, why use virtual calls in those cases? Why not just have two
different implementation files -- one for tests, and one for production -- and
choose one based on which one you're doing? It seems like a win all around.

I don't fully understand the proposal here. Do you have an example of a code
in the wild that uses the proposed scheme?

~~~
mehrdadn
I'm just saying do conditional compilation instead of virtual dispatch, since
you generally shouldn't really need both the test and production
implementations to run inside the same program. So if you have reason to
require

    
    
      // widget.h
      class Widget { virtual void throb(); };
      // widget.cc
      class WidgetImpl : public Widget { void throb() { ... } };
      class WidgetTest : public Widget { void throb() { ... } };
    

then, instead of that, just do

    
    
      // widget.h
      class Widget { void throb(); };
      // widget.cc
      void Widget::throb() { ... }
      // widget.test.cc
      void Widget::throb() { ... }
    

where you only compile widget.cc for the production build, and only compile
widget.test.cc for the test build.

Feel free to post a more specific example and I can take a stab at seeing if I
can make this transformation to it (or why it might not be possible, if you
think it's not).

~~~
krasin
Thank you for elaborating your proposal. It might work in a theoretical
scenario, but unlikely to be practical for existing projects with millions
lines of codes.

Essentially, it was easier to write a compiler / linker optimization, than
change the source code. On the bright side, everyone wins!

~~~
mehrdadn
> It might work in a theoretical scenario, but unlikely to be practical for
> existing projects with millions lines of codes.

I mean there's no reason you have to change everything by tomorrow. You could
introduce it as a policy moving forward, the same way I'm sure you make any
other changes to other patterns that need to be followed. I'm sure you have a
process for this?

> Essentially, it was easier to write a compiler / linker optimization, than
> change the source code.

I agree, but see above and below.

> On the bright side, everyone wins!

Well, you waste space, time, and energy making the compiler and linker do work
that doesn't inherently need to be done. You also lose parallelizability of
the compilation of the two implementations if they currently reside in the
same file. Finally the compiler (er, linker) might not be able to actually
apply the devirtualizations you expect, whereas in this case it's just a
matter of inlining since the target method is already known.

~~~
lmm
> Well, you waste space, time, and energy making the compiler and linker do
> work that doesn't inherently need to be done.

It's repetitive, error-prone work, better to have the compiler and linker do
it than rely on the programmer getting their use of the preprocessor right.

And even if the programmer gets it right, doing it via macros means every tool
that you want to apply to your codebase - IDEs, profilers, coverage,
instrumentation - needs to understand your macro. Are you sure they'll all get
it right?

Better to write plain old standard code that every tool will work correctly
with, and the worst thing that can ever happen is a slight performance
penalty.

~~~
mehrdadn
Are you replying to the correct comment? Not once did I even mention macros or
the preprocessor.

~~~
lmm
I misunderstood, but what you're actually advocating has all the problems I
mentioned only even more so. Any tool that you want to apply to your codebase
will have to understand not just a macro, but your build configuration.

------
kibwen
_> Watch for more toolchain changes to come. The next steps after this will be
to switch to lld-link and enable ThinLTO. That will open the door to a cross-
language LTO that could inline calls between Rust and C++. In the longer term
we can look into cross-compiling from Linux._

Very cool. The potential to inline Rust and C++ (and C, of course) code
together at the LLVM level is one of those things that's been theoretically
possible for a long time now but has yet to really mature in practice (at
least, I'm not aware of anyone aside from Mozilla attempting it at scale).
Really curious to see how this affects Firefox performance once they get it
all wired up.

~~~
timClicks
Rust's performance benefits won't be immediate, as single-threaded C++ is
already very fast and safe parallelism benefits of Rust would be difficult
(impossible?) to leverage across language boundaries.

I'm more interested in seeing whether the maintainability of Firefox will
increase over time as the proportion of Rust code increases. That is, will
Mozilla be able to accelerate Firefox's development because the source code is
in a safer language?

~~~
agumonkey
I'm trying firefox nightly these days and I notice my cpu has burning peaks
(60 -> 80 C) I wonder if rust parallelism isn't kill my poor laptop
heatsink/fan.

~~~
dblohm7
Are you on a Mac by any chance?

~~~
Reason077
Funny you mention this. While Firefox’s interactive performance on Mac feels
absolutely fine, it’s energy consumption is dramatically worse compared to
Safari.

Using Firefox over Safari can cost _hours_ of battery life, so it’s very hard
to recommend it. Is this just a Mac issue?

~~~
lars_francke
I know of one issue with Firefox when you are using a scaled resolution. It
absolutely destroys battery and performance for me. I _think_ it has gotten
better with the latest versions but the tickets are still open.

[https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=...](https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=1404042)

[https://bugzilla.mozilla.org/show_bug.cgi?id=1407536](https://bugzilla.mozilla.org/show_bug.cgi?id=1407536)

[https://news.ycombinator.com/item?id=17365510](https://news.ycombinator.com/item?id=17365510)

------
simula67
[https://bugzilla.mozilla.org/show_bug.cgi?id=1443590](https://bugzilla.mozilla.org/show_bug.cgi?id=1443590)
has info on why :

> We've discussed this on several occasions but apparently nobody ever filed a
> bug.

> There are a number of reasons using clang-cl for our official builds would
> be good:

> * The ability to patch the toolchain as we do on other platforms

> * The ability to diagnose and upstream fixes for compiler bugs we encounter

> * It would provide motivation to switch to clang on all platforms, which
> would make it so we only have to worry about a single compiler for things
> like performance optimization (I don't assume we would drop support for MSVC
> or gcc, we just wouldn't have to worry as much about compiler quirks)

------
stuartd
Today's Nightly build about:buildconfig

    
    
      Compiler 	Version 	Compiler flags
      z:/build/build/src/clang/bin/clang-cl.exe -Xclang -std=gnu99 -fms-compatibility-version=19.13.26128 	19.13.26128 	-Qunused-arguments -nologo -wd4091 -D_HAS_EXCEPTIONS=0 -W3 -Gy -Zc:inline -Gw -wd4244 -wd4267 -Wno-unknown-pragmas -Wno-ignored-pragmas -Wno-deprecated-declarations -Wno-invalid-noreturn -we4553
      z:/build/build/src/clang/bin/clang-cl.exe -fms-compatibility-version=19.13.26128 	19.13.26128 	-Qunused-arguments -Qunused-arguments -TP -nologo -w15038 -wd5026 -wd5027 -Zc:sizedDealloc- -wd4091 -wd4577 -D_HAS_EXCEPTIONS=0 -W3 -Gy -Zc:inline -Gw -wd4251 -wd4244 -wd4267 -wd4800 -wd4595 -wd4065 -Wno-inline-new-delete -Wno-invalid-offsetof -Wno-microsoft-enum-value -Wno-microsoft-include -Wno-unknown-pragmas -Wno-ignored-pragmas -Wno-deprecated-declarations -Wno-invalid-noreturn -Wno-inconsistent-missing-override -Wno-implicit-exception-spec-mismatch -Wno-unused-local-typedef -Wno-ignored-attributes -Wno-used-but-marked-unused -we4553 -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING -GR- -Zi -O2 -Oy-

------
teddyh
Note that they're switching from _MSVC_ to clang-cl.

Since the headline doesn't mention MSVC, this could be interpreted as relevant
to the old GCC vs. Clang issue, but it really isn't in this case.

~~~
sohkamyung
The headline does say _for Windows builds_. Would that imply MSVC being the
original compiler being used, since that is the usual default compiler under
Windows?

------
gregwtmtno
This is in the latest nightly. Open "about:buildconfig" to see if you're using
it.

------
yeukhon
Why do i have to sign into Google in order to view this?

~~~
bArray
It's not about being signed into Google, it's about running JS.

~~~
krick
Is it? JS in enabled, but I'm still required to login (both with or without
uBlock running). Works in a Private Browsing Mode though.

~~~
jwilk
It's not the problem you're seeing, but the page does require JS:

 _To use Google Groups Discussions, please enable JavaScript in your browser
settings, and then refresh this page._

NoScript users will be automatically redirected to this version (which doesn't
require it):

[https://groups.google.com/forum/m/?_escaped_fragment_=topic/...](https://groups.google.com/forum/m/?_escaped_fragment_=topic/mozilla.dev.platform/wwO48xXFx0A)

------
bluecalm
It would be great if they switched to MinGW as well so both Clang and GCC
work. MinGW needs some support as well and then they control the while
toolchain.

Sadly it probably doesn't make sense for them to allocate resources to that.
On the other hand in my experience at least GCC dominates in performance
department so that would help with not worrying about compiler switch causing
performance regression.

~~~
fithisux
I second that. clang-mingw could be another viable choice.

~~~
bluecalm
It would be great because then the builds would be independent of Microsoft VS
infrastructure which is a total mess on Windows. Both Clang and GCC work with
MinGW (I use MinGW64) headers so then you would have two modern open source
compilers to cross-reference and open source toolchain you could fix or
improve as needed.

~~~
dblohm7
I'm fine with being able to compile with mingw (and we already can on GCC),
but we can't ship our release builds with it; it's too far behind the official
Windows SDK in terms of supporting new platform features.

~~~
bluecalm
Yeah, I realize that supporting MinGW64 is a big task and probably not worth
for one single player even as big as Mozilla. Still, I hope one day it gets
picked up. Visual Studio dependency is painful and I think it will be quite a
while till Clang catches GCC in performance department.

------
electricwater
No idea what is going on but interested in the commotion...

