<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 5, 2020 at 3:51 PM Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</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 lang="EN-US">
<div class="gmail-m_6393933260431128458WordSection1">
<p class="MsoNormal">I’m not a fan of keeping important data outside the IR in an analysis.  If we’re planning to emit it, it should be represented directly in the IR.  Is there some reason we can’t just stick the data in a global variable?</p></div></div></blockquote><div> </div><div>The analysis in the scenarios here is external to LLVM - ML training, for example. It's really a way to do printf, but where the data could be large (challenging in a distributed build env, where IO may be throttled), or non-textual (for instance, capture IR right before a pass). An alternative would be to produce a side-file, but then (again, distributed build), you have to collect those files and concatenate them, and modify the build system to be aware of all that.</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"><div lang="EN-US"><div class="gmail-m_6393933260431128458WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I’m not sure it’s helpful to have a generic mechanism for this; it’s not clear how this would work if multiple different features were trying to emit data into the llvm_dump section at the same time.</p></div></div></blockquote><div><br></div><div>You could layer the approach: the one llvm_dump section has a pluggable reader.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div lang="EN-US"><div class="gmail-m_6393933260431128458WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">-Eli <u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-left:0.5in"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>>
<b>On Behalf Of </b>Kazu Hirata via llvm-dev<br>
<b>Sent:</b> Wednesday, August 5, 2020 3:36 PM<br>
<b>To:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>; Mircea Trofin <<a href="mailto:mtrofin@google.com" target="_blank">mtrofin@google.com</a>>; Wei Mi <<a href="mailto:wmi@google.com" target="_blank">wmi@google.com</a>>; <a href="mailto:james.henderson@sony.com" target="_blank">james.henderson@sony.com</a><br>
<b>Subject:</b> [EXT] [llvm-dev] [RFC] Introduce Dump Accumulator<u></u><u></u></p>
</div>
<p class="MsoNormal" style="margin-left:0.5in"><u></u> <u></u></p>
<div>
<pre style="margin-left:0.5in"><span style="color:black">Introduction<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">============<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">This RFC proposes a mechanism to dump arbitrary messages into object<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">files during compilation and retrieve them from the final executable.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Background<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">==========<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">We often need to collect information from all object files of<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">applications.  For example:<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- Mircea Trofin needs to collect information from the function<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  inlining pass so that he can train the machine learning model with<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  the information.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- I sometimes need to dump messages from optimization passes to see<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  where and how they trigger.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Now, this process becomes challenging when we build large applications<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">with a build system that caches and distributes compilation jobs.  If<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">we were to dump messages to stderr, we would have to be careful not to<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">interleave messages from multiple object files.  If we were to modify<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">a source file, we would have to flush the cache and rebuild the entire<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">application to collect dump messages from all relevant object files.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">High Level Design<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">=================<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- LLVM: We provide machinery for individual passes to dump arbitrary<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  messages into a special ELF section in a compressed manner.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- Linker: We simply concatenate the contents of the special ELF<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  section.  No change is needed.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- llvm-readobj: We add an option to retrieve the contents of the<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  special ELF section.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Detailed Design<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">===============<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">DumpAccumulator analysis pass<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">-----------------------------<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">We create a new analysis pass called DumpAccumulator.  We add the<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">analysis pass right at the beginning of the pass pipeline.  The new<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">analysis pass holds the dump messages throughout the pass pipeline.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">If you would like to dump messages from some pass, you would obtain<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">the result of DumpAccumulator in the pass:<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  DumpAccumulator::Result *DAR = MAMProxy.getCachedResult<DumpAccumulator>(M);<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Then dump messages:<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  if (DAR) {<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">    DAR->Message += "Processing ";<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">    DAR->Message += F.getName();<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">    DAR->Message += "\n";<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">  }<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">AsmPrinter<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">----------<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">We dump the messages from DumpAccumulator into a section called<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">".llvm_dump" in a compressed manner.  Specifically, the section<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">contains:<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- LEB128 encoding of the original size in bytes<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- LEB128 encoding of the compressed size in bytes<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">- the message compressed by zlib::compressed<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">in that order.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">llvm-readobj<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">------------<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">We read the .llvm_dump section.  We dump each chunk of compressed data<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">one after another.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Existing Implementation<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">=======================<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><a href="https://reviews.llvm.org/D84473" target="_blank">https://reviews.llvm.org/D84473</a><u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Future Directions<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">=================<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">The proposal above does not support the ThinLTO build flow.  To<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">support that, I am thinking about putting the message as metadata in<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">the IR at the prelink stage.<u></u><u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black"><u></u> <u></u></span></pre>
<pre style="margin-left:0.5in"><span style="color:black">Thoughts?<u></u><u></u></span></pre>
</div>
</div>
</div>

</blockquote></div></div>