<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Just to add one more simple use-case to the mix, although it sounds like the main requirements are already captured.  We're using opt-bisect-limit from clang and lld in <a href="https://github.com/SNSystems/dexter">https://github.com/SNSystems/dexter</a> to build up a picture of how different optimization passes affect the user debugging experience (see slide 19 onwards in <a href="http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf">http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf</a> ) which provides us useful data for writing useful small targeted tests (resulting in PR38768) as well as hopefully allowing us to tune a useful -Og mode once we've dealt with the obvious cases of fixable DI loss.</div><div dir="ltr"><br></div><div>For en example of inspecting a small two-file example at -O2 -flto the tool would first do the following in order to work out how many bisectable passes are run for each stage by inspecting the "BISECT: running pass" lines in the stderr output:</div><div><br></div><div>clang++ a.cpp -c -O2 -flto -o a.o -mllvm -opt-bisect-limit=999999</div><div>clang++ b.cpp -c -O2 -flto -o b.o -mllvm -opt-bisect-limit=999999  <br></div><div>clang++ a.o b.o -fuse-ld=lld -Wl,-mllvm -Wl,-opt-bisect-limit=999999<br></div><div><br></div><div>Then we'll just keep rebuilding the code with increasing opt-bisect-limit values:</div><div><br></div><div><div>clang++ a.cpp -c -O2 -flto -o a.o -mllvm -opt-bisect-limit=1</div><div>clang++ b.cpp -c -O2 -flto -o b.o -mllvm -opt-bisect-limit=0<br></div><div>clang++ a.o b.o -fuse-ld=lld -Wl,-mllvm -Wl,-opt-bisect-limit=0<br></div><br class="gmail-Apple-interchange-newline"></div><div><div>clang++ a.cpp -c -O2 -flto -o a.o -mllvm -opt-bisect-limit=2</div><div>clang++ b.cpp -c -O2 -flto -o b.o -mllvm -opt-bisect-limit=0<br></div><div>clang++ a.o b.o -fuse-ld=lld -Wl,-mllvm -Wl,-opt-bisect-limit=0<br></div><br class="gmail-Apple-interchange-newline"></div><div>and so on until each opt-bisect-limit value is at the maximum, measuring the 'debugging experience score' for every build along the way.  We look for the final instance of "BISECT: running pass" on the combined stderr output to figure out the name of the pass that we're attaching that score to so that we can build up a picture of which passes actually have an effect on the score.  Obviously we'll modify the tool to cope with whatever changes to interface/debug output occur, but I'd be very keen that any new solutions didn't totally break the use-case!</div><div><br></div><div><br></div><div dir="ltr"><br></div><div dir="ltr"><br></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, 5 Oct 2018 at 09:31, Chandler Carruth 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, Oct 4, 2018 at 4:11 PM Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple">
<div class="m_9153286365471006847m_-6620373477974391098WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">We (Intel) use opt-bisect most often in conjunction with clang and frequently with applications that have non-trivial compilation mechanisms. If there isn’t a
 way to get something hooked up through code generation, it doesn’t really meet the needs of the way we are using it.  As an interim solution it would be tolerable to have two separate bisect-like options, one that works its way through the pre-codegen passes
 and a different one that bisects codegen.</span></p></div></div></blockquote><div><br></div><div>To an extent, I think that will be a very likely necessary step due to the fact that all of codegen is a separate pass manager at the moment.</div><div><br></div><div>However, given that the goal is bisection, I would imagine a somewhat simpler approach of the first step of bisection be to determine whether the regression comes before codegen or in codegen.</div><div><br></div><div>That said, I think it is interesting that you are using this directly with Clang. I'm honestly somewhat surprised that this works, but hey, nice!</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_9153286365471006847m_-6620373477974391098WordSection1"><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Skipping “necessary” passes is a somewhat different matter, because you can’t skip something like register allocation on your way to executable code.  Most of
 the passes that are really significant in this way are codegen passes, so we might still be able to work something out. I believe there are a few pre-codegen passes that are required but they do trivial things like removing intrinsics that don’t get lowered.</span></p></div></div></blockquote><div><br></div><div>FWIW, even the "IR" passes like this are actually run as part of codegen using the legacy PM in all cases right now. So to an extent, I think this will "just work" out of the box once you can select between the bisection occuring over the main optimization pipeline (w/ the new PM) or the code generation pipeline (still w/ legacy PM).</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_9153286365471006847m_-6620373477974391098WordSection1"><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">
 Perhaps we could have some mechanism that builds a set of clean up passes that get run under some very limited circumstances. Is that what you were suggesting in your comment about running “some minimal second set of passes” after the bisection?</span></p></div></div></blockquote><div><br></div><div>This is one approach that seems like it might be fruitful. It does make it hard to use bisection techniques to isolate issues caused by passes specifically when intermingled with those "necessary" passes like register allocation. I'm not sure how important bisection is for those passes currently though. To be honest, while I've used pass bisection a *lot* for a lot of different things, I've never really found it useful once I'm in MI-land because so few of the passes can realistically be disabled. So I was somewhat focused on solving the problem in a more simple way focused on the more flexible passes.</div><div><br></div><div>There is another approach that I think might be more interesting long-term: rather than merely bisection to isolate a single point which introduces a bug, I'd like us to generalize the debug counter pattern. Right now, you can skip N times and then run M times. What I would like is to support an arbitrary number of skip and run counts. If you combine this with a test harness that marks compilations that fail, or runs that fail differently from the bug in question, you can use this to *detect* and preserve the necessary passes because they will fail the "sanity" or "baseline" test prior to being "interesting".</div><div><br></div><div>This is a pretty common pattern in delta reduction (verifying that the reduction remains "interesting" includes verifying that it doesn't fail for unrelated reasons), and I think could be used to avoid building in complex logic to handle "required" passes.</div><div><br></div><div><br></div><div>If none of this works, and we *need* to share the logic between `optnone` and bisection because we have no other way of expressing "required" passes, my inclination would be to actually try to use "optnone" directly rather than trying to build a unified "skip" routine that somehow coordinates with the pass manager. But I'm not sure how to do that really effectively outside of function passes. Or maybe there is some other way of easily communicating "required"-ness here, but currently I struggle to see it. So I'm somewhat hoping that in practice, one of the above will be enough.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_9153286365471006847m_-6620373477974391098WordSection1"><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">The current opt-bisect mechanism really doesn’t do much more than increment a counter, but it does produce output that indicates what was run and what wasn’t. 
 This is very useful for finding the proper owner for a bug once the failure has been diagnosed with opt-bisect.  I don’t really care how the mechanism is implemented, but I’d really like to know what the last optimization was that ran in a failing case and
 which IR unit it was run on.  Knowing the highest pass count that was used is also helpful to establish a starting point.</span></p></div></div></blockquote><div><br></div><div>Having clear output would definitely be useful. Fedor was already thinking of replacing the pass manager debug output with the instrumentation, and it would seem very easy to similarly wire together helpful output from the bisection instrumentation.</div><div><br></div><div><br></div><div>Thanks for all the thoughts on different ways to use bisection!</div><div>-Chandler</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_9153286365471006847m_-6620373477974391098WordSection1"><div><div><div><div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
</blockquote>
</div>
</div>
</div>
</div></div></div></blockquote></div></div>
_______________________________________________<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="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>