<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 12, 2019 at 2:18 AM Michael Woerister via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi everyone,<br>
<br>
As part of my work for Mozilla's Low Level Tools team I've<br>
implemented PGO in the Rust compiler. The feature is<br>
available since Rust 1.37 [1]. However, so far we have not<br>
seen any actual performance gains from enabling PGO for<br>
Rust code. Performance even seems to drop 1-3% with PGO<br>
enabled. I wonder why that is and I'm hoping that someone<br>
here might have experience debugging PGO effectiveness.<br>
<br>
<br>
PGO in the Rust compiler<br>
------------------------<br>
<br>
The Rust compiler uses IR-level instrumentation (the<br>
equivalent of Clang's `-fprofile-generate`/`-fprofile-use`).<br>
This has worked pretty well and even enables doing PGO for<br>
mixed Rust/C++ codebases when also using Clang.<br>
<br>
The Rust compiler has regression tests that make sure that:<br>
<br>
- instrumentation shows up in LLVM IR for the `generate` phase,<br>
  and that<br>
<br>
- profiling data is actually used during the `use` phase, i.e.<br>
  that cold functions get marked with `cold` and hot functions<br>
  get marked with `inline`.<br>
<br>
I also verified manually that `branch_weights` are being set<br>
in IR. So, from my perspective, the PGO implementation does<br>
what it is supposed to do.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Are the 'function_entry_count' and the 'ProfileSummary' metadata included in the IR? I think some PGO passes may expect them to trigger.</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
However, as already mentioned, in all benchmarks I've seen so<br>
far performance seems to stay the same at best and often even<br>
suffers slightly. Which is suprising because for C++ code<br>
using Clang's version of IR-level instrumentation & PGO brings<br>
signifcant gains (up to 5-10% from what I've seen in<br>
benchmarks for Firefox).<br>
<br>
One thing we noticed early on is that disabling the<br>
pre-inlining pass (`-disable-preinline`) seems to consistently<br>
improve the situation for Rust code. Doing that we sometimes<br>
see performance wins of almost 1% over not using PGO. This<br>
again is very different to C++ where disabling this pass<br>
causes dramatic performance loses for the Firefox benchmarks.<br>
And 1% performance improvement is still well below<br>
expectations, I think.<br>
<br>
So my questions to you are:<br>
<br>
- Has anybody here observed something similar while<br>
  wokring on or with PGO?<br>
<br>
- Are there certain known characteristics of LLVM IR code<br>
  that inhibit PGO's effectiveness and that IR produced by<br>
  `rustc` might exhibit?<br>
<br>
- Does anybody know of a good source that describes how to<br>
  effectively debug a problem like this?<br>
<br>
- Does anybody know of a small example program in C/C++<br>
  that is known to profit from PGO and that could be<br>
  re-implemented in Rust for comparison?<br>
<br>
Thanks a lot for reading! Any help is appreciated.<br>
<br>
-Michael<br>
<br>
[1] <a href="https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#profile-guided-optimization" rel="noreferrer" target="_blank">https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#profile-guided-optimization</a><br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>