<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 14, 2013 at 6:06 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="im"><br>
<div class="gmail_quote">On Tue, Nov 12, 2013 at 7:24 PM, Sean Silva <span dir="ltr"><<a href="mailto:silvas@purdue.edu" target="_blank">silvas@purdue.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Could you maybe give an example or two to whet our testing appetite?</blockquote>
</div><br></div>It would honestly be simpler for me to write the tests after pulling it in and point at them. The GoogleMock project has some good examples as well.</div></div></blockquote><div><br></div><div>Doesn't the entire operational behavior of the passmanager entirely boil down to the ordering of particular method invocations on passes (and that particular pieces of IR are passed between them)? It seems like it would be possible to print designated strings when particular things happen, and then use FileCheck to check the order (and there's even CHECK-DAG if you want to be bulletproof in the presence of parallelism).</div>
<div><br></div><div>Or more usefully, I think it would be good to define an "introspection" C++ interface for the pass manager, with a callback for each of various interesting points in the operation of the pass manager. Not only would that would be independently useful, but a trivial "logging" one would allow you to FileCheck every nook and cranny worth looking at.</div>
<div>A number of other use cases that come to mind:</div><div>- There are a couple really hacky (but useful) -debug-pass= options to opt that would be nice to "properly implement", as well as being accessible in a clean way from C++.</div>
<div>- opt's -print-before-all, -print-after-all, etc.</div><div>- It would allow decoupling pass timing from the passmanager itself (currently time-passes is implemented !!!with a global variable!!! btw)</div><div>- non-intrusively collect detailed information/statistics about the optimization pipeline. For example, which pass is responsible for eliminating the most functions? Which pass is responsible for eliminating *this* instruction in my function?</div>
<div><br></div><div>Also, btw, a canonical machine-readable (e.g. YAML) way to represent the set of passes to be run would also be good and would go hand-in-hand as part of the logging functionality needed for testing.</div>
<div>That would end the madness of describing a set of passes as a sequence of command line options to opt, rather than having a proper canonical representation built into the PassManager.</div><div>It would have been really useful for part of the work I was doing this Summer, which involved analyzing different pass combinations for LTO, and I ended up essentially having text files with a bunch of opt commandline options and doing "opt `cat foopasses.txt | sed '/^#/d' | tr '\n' ' '` bar.bc", and communicating with colleagues involved essentially pasting opt commandline options to each other.</div>
<div>A flexible format would also open the door to later having parameterized passes (something else I could have used this Summer for various things), not to mention the ability to eliminate all the nasty cl::opt !!!global!!! configurables that the various passes have. The interface for such options would be essentially the same as cl::opt options currently, except instead of `cl::opt<bool> EnableFoo("enable-foo")`, the pass is given essentially a map of strings to values (rather than having them be ad-hoc parsed through global state); the pass then just does `this->EnableFoo = getOption<bool>(Opts, "enable-foo")` (`this` added for clarity that it is a member). A simple concrete example where this would be useful is running two inlining passes in the same pass pipeline with different inlining thresholds.</div>
<div><br></div><div><br></div><div>-- Sean Silva </div></div><br></div></div>