<div dir="ltr">Beefed up the prototype to use a unit if it's there, and manually modified some IR to drop the unit and distinct on the linkonce_odr functions in the example - linked them (did the right thin, deduplicated the subprograms) & codegen'd the result, got the right answer (like the original improved output I proposed)<br><br>Just an FYI/idea/thing.<br><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 15, 2016 at 11:53 AM David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.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"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Thu, Dec 15, 2016 at 11:35 AM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<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"><br class="gmail_msg">
> On Dec 15, 2016, at 10:54 AM, David Blaikie via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br class="gmail_msg">
><br 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">
> void f1();<br class="gmail_msg">
> inline __attribute__((always_inline)) void f2() {<br class="gmail_msg">
> f1();<br class="gmail_msg">
> }<br class="gmail_msg">
> inl1.cpp:<br class="gmail_msg">
> #include "inl.h"<br class="gmail_msg">
> void c1() {<br class="gmail_msg">
> f2();<br class="gmail_msg">
> }<br class="gmail_msg">
> inl2.cpp:<br class="gmail_msg">
> #include "inl.h"<br class="gmail_msg">
> void c2() {<br class="gmail_msg">
> f2();<br 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"<br 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"<br 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"<br 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">
> 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"<br 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"<br class="gmail_msg">
> DW_TAG_compile_unit<br class="gmail_msg">
> DW_AT_name "inl2.cpp"<br 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"<br class="gmail_msg">
><br class="gmail_msg">
> (note that only one abstract definition of f2 is produced here)<br 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">
I should see the IR metadata in both cases to really know how it worked before, but it seems that to be able to merge the two subprogram definitions when linking, we’d need to be able to have a list of CU per subprogram instead of a single one, right?<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">
<br class="gmail_msg">
Looks like this should work as well, but I don’t enough about the way we emit Dwarf...<br class="gmail_msg"></blockquote></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"><br class="gmail_msg">Trying a simple prototype, I think the only thing that went really screwy, was once we don't have that link, how do we pick which CU to put it in? Does it matter?<br class="gmail_msg"><br class="gmail_msg">So my really rough prototype (that just used the first CU in the CUMap for all subprograms) of course ended up with this:<br class="gmail_msg"><br class="gmail_msg">DW_TAG_compile_unit</div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"><br class="gmail_msg"> DW_TAG_subprogram #0<br class="gmail_msg"> DW_AT_name "f2"<br 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"></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> DW_AT_abstract_origin #0<br 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_AT_abstract_origin #0<br class="gmail_msg">DW_TAG_compile_unit<br class="gmail_msg"><br class="gmail_msg">So I suppose we could use the unit when present - and make it present (& use distinct) when the function definition has external linkage. There's nothing we intend to deduplicate there & that means external linkage definitions will go in the right CU, and inline definitions just go wherever their first use is.<br class="gmail_msg"><br class="gmail_msg">Hmm - I guess that doesn't quite work for ThinLTO? Oh, maybe it does - it'd mean we'd have to drop the CU reference and un-distinct when we import.<br class="gmail_msg"><br class="gmail_msg">Hmm - that might simplify importing greatly - then we wouldn't actually need to import CUs at all? <br class="gmail_msg"><br class="gmail_msg">Don't know if that's a good thing.<br class="gmail_msg"><br class="gmail_msg">- Dave<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">
<br class="gmail_msg">
—<br class="gmail_msg">
Mehdi<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div></div></blockquote></div></div>