<div dir="ltr"><font face="monospace">FYI</font><div><font face="monospace"><br></font></div><div><font face="monospace">It is possible to dump branch probabilities as optimization remarks via an internal option.  Not convenient as the tool, but user can use it to inspect the code easily.  The following example shows that builtin_expect is wrongly used -- it should expect '1', instead of '0'.</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">// command line:</font></div><div><font face="monospace">clang -O2 -fprofile-use=./t.profdata -Rpass=pgo-instrumentation -mllvm -pgo-emit-branch-prob foo.c -c<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">// output:</font></div><div><font face="monospace">foo.c:3:9: remark: sgt_i32_Const is true with probability : 0x71eb851f / 0x80000000 = 89.00% (total count : 100) [-Rpass=pgo-instrumentation]<br>    if (__builtin_expect(n > 10, 0))<br>        ^<br>foo.c:11:5: remark: ult_i32_Const is true with probability : 0x7ebb907a / 0x80000000 = 99.01% (total count : 101) [-Rpass=pgo-instrumentation]<br>    for (int i = 0; i < 100; i++) {</font><br>    ^<br></div><div><br></div><div><font face="monospace">// foo.c:</font></div><div><font face="monospace">int g1, g2;<br>__attribute__((noinline)) void foo(int n) {<br>    if (__builtin_expect(n > 10, 0))<br>      g1++;<br>    else<br>       g2++;<br>}<br><br>int main() {<br>    int i;<br>    for (int i = 0; i < 100; i++) {<br>       foo(i);<br>    }<br>    return 0;<br>}</font><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 23, 2019 at 7:05 PM Paul Kirth via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-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"><div dir="ltr">We would like to propose adding a new clang based tool, clang-mispredict, for identifying potentially incorrect uses of __builtin_expect().  <br> <br>--- TLDR ---<br>What are we proposing?<br>* Adding a new tool, clang-mispredict, to the LLVM project.<br> <br>What is its purpose?<br>* Identifying potentially problematic uses of __builtin_expect(). <br> <br>Why is this important?<br>* __builtin_expect() has a high performance cost when it is used incorrectly.<br> <br>Where will the code live?<br>* clang-mispredict will live in clang-tools-extra, and there will be some additions to clang.<br> <br>Open questions<br>* What is the correct heuristic for determining a mismatch?<br> <br>Potential shortcomings<br>* The approach is sensitive to both profiling input and configuration.<br> <br> <br>--- Details ---<br> <br>We plant to build a new tool, clang-mispredict, on top of Clang’s PGO infrastructure. This tool will issue warnings about the use of _builtin_expect() when collected PGO profile data shows a mismatch with the use of __builtin_expect(). Existing solutions for validating these annotations generally follow this approach: leverage dynamic profiling to validate existing annotations. This is the approach used in the Linux kernel, for example. Unfortunately, existing solutions seem to be custom efforts specific to a particular code base. Supporting this in the LLVM ecosystem gives developers a general way to check the use of _builtin_expect() without creating custom instrumentation.<br> <br>Additionally, if _builtin_expect() is used incorrectly, then developers may notice a performance regression when switching to the new PM. This happens because the New PM follows performance annotations more closely than the legacy PM, and is therefore more likely to try and aggressively optimize these cases. Our proposed tool can help developers narrow their focus to potentially problematic areas during the transition.<br> <br>Finally, it may also be beneficial to suggest annotations when profiling suggests it would be beneficial. We consider this a desirable property not only from a performance standpoint, but also for identifying potential bugs (both in the profiling corpus and within the codebase). <br> <br>We think having clang-mispredict behave similar to clang-tidy is good approach. We can use a compile commands database in conjunction with profiling data to drive our validation tool. More concretely, we plan to use Clang’s existing PGO infrastructure to emit warnings where branch weights are assigned, but stop compilation before the IR is passed to the backend. This largely amounts to checking if the profile counters are outside of certain thresholds for 'hot' and 'cold' code. Similar to clang tidy, we plan to support suppressing warnings within the codebase through use of comment strings. <br> <br>The most obvious question about this approach is how to quantify what is ‘hot’ or ‘cold’. Initially, we plan to use the thresholds already present in LLVM; however, we are happy to use any suitable heuristic or empirically derived threshold. Input from the community about the correct heuristic are most welcome.<br> <br>Our strategy does have some shortcomings. The usefulness of the warnings are directly related to how representative the profiling input actually was when compared to its normal use. If the profile collected is not representative of typical use, then the warnings may not reflect the ground truth. Program and build configuration can also dramatically change which paths will be executed, thus affecting the quality of the profile data and the generated warnings.<br> <br>Ultimately, we are proposing adding a new standalone tool that takes a compile commands database and an instrumentation profile to emit warnings in a clang-tidy fashion.<br> <br>Please let us know if you have comments or concerns about this proposal.<div><br>Thanks!<br><div><br></div>-- <br><div dir="ltr" class="gmail-m_-4161444645927124058gmail_signature"><div dir="ltr">Paul Kirth</div></div></div></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>