<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 15, 2016 at 11:26 AM Teresa Johnson <<a href="mailto:tejohnson@google.com">tejohnson@google.com</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" class="gmail_msg">Trying to wrap my brain around this, so a few questions below. =)<br class="gmail_msg"></div></blockquote><div><br>Sure thing - sorry, did assume a bit too much arcane context here.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg">On Thu, Dec 15, 2016 at 10:54 AM, David Blaikie <span dir="ltr" class="gmail_msg"><<a href="mailto:dblaikie@gmail.com" class="gmail_msg" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">Branching off from a discussion of improvements to DIGlobalVariable representations that Adrian's working on - got me thinking about related changes that have already been made to DISubprogram.<br class="gmail_msg"><br class="gmail_msg">To reduce duplicate debug info when things like linkonce_odr functions were deduplicated in LTO linking, the relationship between a CU and DISubprogram was inverted (instead of a CU maintaining a list of subprograms, subprograms specify which CU they come from - and the llvm::Function references the DISubprogram, so if the llvm::Function goes away, so does the associated DISubprogram)<br class="gmail_msg"><br class="gmail_msg">I'm not sure if this caused a regression, but at least seems to miss a possible improvement:<br class="gmail_msg"><br class="gmail_msg">During IR linking (for LTO, ThinLTO, etc) these distinct DISubprogram definitions (& their CU link, even if they weren't marked 'distinct', the CU link would cause them to effectively be so) remain separate - this means that inlined versions in one CU don't refer to an existing subprogram definition in another CU.<br class="gmail_msg"><br class="gmail_msg">To demonstrate:<br class="gmail_msg">inl.h:<br class="gmail_msg"><div class="gmail_msg">void f1();</div><div class="gmail_msg">inline __attribute__((always_inline)) void f2() {</div><div class="gmail_msg">  f1();</div><div class="gmail_msg">}<br class="gmail_msg">inl1.cpp:<br class="gmail_msg"><div class="gmail_msg">#include "inl.h"</div><div class="gmail_msg">void c1() {</div><div class="gmail_msg">  f2();</div><div class="gmail_msg">}<br class="gmail_msg">inl2.cpp:<br class="gmail_msg"><div class="gmail_msg">#include "inl.h"</div><div class="gmail_msg">void c2() {</div><div class="gmail_msg">  f2();</div><div class="gmail_msg">}<br class="gmail_msg"><br class="gmail_msg">Compile to IR, llvm-link the result. The DWARF you get is basically the same as the DWARF you'd get without linking:<br class="gmail_msg"><br class="gmail_msg">DW_TAG_compile_unit<br class="gmail_msg">  DW_AT_name "inl1.cpp"<br class="gmail_msg">  DW_TAG_subprogram #0<br class="gmail_msg">    DW_AT_name "f2"</div></div></div><div class="gmail_msg">  DW_TAG_subprogram<br class="gmail_msg">    DW_AT_name "c1"<br class="gmail_msg">    DW_TAG_inlined_subroutine<br class="gmail_msg">      DW_TAG_abstract_origin #0 "f2"<div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">DW_TAG_compile_unit<br class="gmail_msg">  DW_AT_name "inl2.cpp"<br class="gmail_msg">  DW_TAG_subprogram #1<br class="gmail_msg">    DW_AT_name "f2"</div></div></div><div class="gmail_msg">  DW_TAG_subprogram<br class="gmail_msg">    DW_AT_name "c2"<br class="gmail_msg">    DW_TAG_inlined_subroutine<br class="gmail_msg">      DW_TAG_abstract_origin #1 "f2"<br class="gmail_msg"><br class="gmail_msg">Instead of something more like this:<br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">DW_TAG_compile_unit<br class="gmail_msg">  DW_AT_name "inl1.cpp"<br class="gmail_msg">  DW_TAG_subprogram #0<br class="gmail_msg">    DW_AT_name "f2"</div></div></div><div class="gmail_msg">  DW_TAG_subprogram<br class="gmail_msg">    DW_AT_name "c1"<br class="gmail_msg">    DW_TAG_inlined_subroutine<br class="gmail_msg">      DW_TAG_abstract_origin #0 "f2"<div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">DW_TAG_compile_unit<br class="gmail_msg">  DW_AT_name "inl2.cpp"</div></div></div><div class="gmail_msg">  DW_TAG_subprogram<br class="gmail_msg">    DW_AT_name "c2"<br class="gmail_msg">    DW_TAG_inlined_subroutine<br class="gmail_msg">      DW_TAG_abstract_origin #0 "f2"</div></div></div><br class="m_-3681109979486123769m_-6809783484898340448inbox-inbox-Apple-interchange-newline gmail_msg"></div>(note that only one abstract definition of f2 is produced here)<br class="gmail_msg"></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">I think I understand what you are saying. Essentially, having the SP->CU link allows the SP to be deduplicated when multiple *outline* copies of the corresponding function are deduplicated. But not when the multiple copies are inlined, as it looks like we need all the copies, right?</div></div></div></div></blockquote><div><br>Not quite - having the SP->CU link (well,h onestly, marking the SP as "distinct" does this, but even if we didn't do that, the SP->CU link would still do it) causes SPs /not/ to be deduplicated on IR linking.<br><br>Each SP is distinct/not considered duplicate with any other. (if we didn't mark it 'distinct', the fact that each SP refers to its corresponding CU would produce the same effect - they wouldn't be deduplicated because they aren't identical - they refer to different CUs)<br><br>For non-inlined cases, this is fine.<br><br>Before we inverted the SP<>CU link, what would happen is that all copies of the llvm::Function would be dropped, but their SPs would be left around. So two CUs that both used the same linkonce_odr function (let's say no inlining actually occurred though) would both have a SP description in the DWARF - but one would actual have a proper definition (with a high/low PC, etc) the other would be missing those features, as though the function had been optimized away (which it sort of had)<br><br>So by reversing the link, we got rid of those extra SP descriptions in the DWARF (and the extra SP descriptions in the metadata - I think they were duplicate back then because they still had a scope chain leading back to their CU (maybe we had gotten rid of that chain - if we had, then adding it back in may've actually caused more metadata, but less DWARF))<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> </div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><br class="gmail_msg">Any thoughts? I imagine this is probably worth a reasonable amount of savings in an optimized build. Not huge, but not nothing. (probably not the top of anyone's list though, I realize)<br class="gmail_msg"><br class="gmail_msg">Should we remove the CU link from a non-internal linkage subprogram (& this may have an effect on the GV representation issue originally being discussed) and just emit it into whichever CU happens to need it first?<br class="gmail_msg"></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">I can see how this would be done in LTO where the compiler has full visibility. For ThinLTO presumably we would need to do some index-based marking? Can we at least do something when we import an inlined SP and drop it since we know it is defined elsewhere?</div></div></div></div></blockquote><div><br></div><div>Complete visibility isn't required to benefit here - and unfortunately there's nothing fancier (that I know of) that we can do to avoid emitting one definition of each used inline function in each thinlto object file we produce (we can't say "oh, the name of the function, its mangled name, the names and types of its parameters are over in that other object file/somewhere else" - but we can avoid emitting those descriptions in each /CU/ that uses the inlined function within a single ThinLTO object)<br><br>I can provide some more thorough examples if that'd be helpful :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Thanks,</div><div class="gmail_msg">Teresa</div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> <br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><br class="gmail_msg">This might be slightly sub-optimal, due to, say, the namespace being foreign to that CU. But it's how we do types currently, I think? So at least it'd be consistent and probably cheap enough/better.</div>
</blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><br class="gmail_msg"><br clear="all" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div>-- <br class="gmail_msg"><div class="m_-3681109979486123769gmail_signature gmail_msg" data-smartmail="gmail_signature"><span style="font-family:Times;font-size:medium" class="gmail_msg"><table cellspacing="0" cellpadding="0" class="gmail_msg"><tbody class="gmail_msg"><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small" class="gmail_msg"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px" class="gmail_msg">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px" class="gmail_msg"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px" class="gmail_msg"> <a href="mailto:tejohnson@google.com" class="gmail_msg" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px" class="gmail_msg"> <a href="tel:(408)%20460-2413" value="+14084602413" class="gmail_msg" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div></div></blockquote></div></div>