If you think a bug might affect users in the 57 release, please set the correct tracking and status flags for Release Management.

Support PGO in clang-cl builds




Build Config
8 months ago
a month ago


(Reporter: dmajor, Unassigned)


Firefox Tracking Flags

(Not tracked)



(1 attachment)



8 months ago
I managed to PGO a toy program on Windows using clang-cl.exe and lld-link.exe built from LLVM trunk. Doing this for libxul would of course be much more challenging, but I think it's worth investigating. Someday this may allow us to do official builds with clang-cl.

It's possible that this work may also fix bug 1064049 (clang PGO on Linux) as a byproduct.

Comment 1

8 months ago
Created attachment 8839799 [details]
Toy program showing build steps


8 months ago
Attachment #8839799 - Attachment is patch: false
Blocks: 1384434

Comment 2

2 months ago
Does this really depend on bug 1384434?  AFAIK a project that can be compiled with clang-cl should be able to use PGO without lld, see <https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization>...

Comment 3

2 months ago
What other linker would you use? The documentation is not especially clear about this.
Presumably, clang-cl pgo doesn't work at link time like MSVC's (assuming it works like clang pgo)

Comment 5

2 months ago
MS link.exe.  clang PGO compiler doesn't use link-time code generation as far as I can tell.  It uses the profile information when doing the second round of building to perform PGO optimizations.

There is also LTO (link-time optimizations) which requires running a linker plugin to do link-time code generation, and if we want to use that we need to build with lld.  To the best of my knowledge you can use LTO and PGO either together or independently.

The MSVC's PGO compiler is weird in the sense that its PGO compiler requires LTCG as a dependency.  I never really realized why that is...

Comment 6

2 months ago
It never occurred to me that one could do PGO in any other way, because, well, link.exe is what I grew up with.

TIL. Thanks!

Comment 7

2 months ago
I confirmed that I can PGO the toy program with clang-cl and the MS linker -- just replace "lld-link.exe" with "link.exe" in the instructions. It seems like this will make things much easier!

Please correct me where I'm wrong, but I think what we need is:

  - Add "-fprofile-instr-generate" to compiler flags
  - Add "clang_rt.profile-$ARCH.lib" to linker libs

- During maybe_clobber_profiledbuild:
  - Do this phase in the gcc/clang way (as in actually clobber)
  - Call "llvm-profdata merge -o default.profdata default.profraw"  (*)

  - Add "-fprofile-instr-use" to compiler flags

(*) Or possibly something a little more fancy than this, depending on what happens with multiple binaries or multiple runs


2 months ago
No longer blocks: 1384434
Summary: Look into doing clang-cl PGO builds with lld-link → Support PGO in clang-cl builds

Comment 8

a month ago
In attempting to do this on the our tree:
>   - Add "-fprofile-instr-generate" to compiler flags
>   - Add "clang_rt.profile-$ARCH.lib" to linker libs

I get a bunch of multiply-defined symbol errors as illustrated by the reduced case below. These __profd symbols appear multiple times in a way that link.exe can't handle, but lld-link.exe can. At first glance I can't tell if this is an LLVM bug or just a consequence of the two linkers handling things in different ways (are these ELF-style weak symbols, perhaps?).

$ cat one.cpp
#include <stdio.h>

void SayHello();

int main()
  return 0;

$ cat two.cpp
#include <stdio.h>

void SayHello()
  printf("hello ");

$ clang-cl -c -fprofile-instr-generate one.cpp
$ clang-cl -c -fprofile-instr-generate two.cpp
$ link one.obj two.obj clang_rt.profile-x86_64.lib
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

two.obj : error LNK2005: __profd_printf already defined in one.obj
two.obj : error LNK2005: __profd__vfprintf_l already defined in one.obj
two.obj : error LNK2005: __profd___local_stdio_printf_options already defined in one.obj
one.exe : fatal error LNK1169: one or more multiply defined symbols found

$ lld-link one.obj two.obj clang_rt.profile-x86_64.lib
$ one.exe
hello world
You need to log in before you can comment on or make changes to this bug.