<div dir="ltr">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><br>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><br>I'm not sure if this caused a regression, but at least seems to miss a possible improvement:<br><br>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><br>To demonstrate:<br>inl.h:<br><div>void f1();</div><div>inline __attribute__((always_inline)) void f2() {</div><div>  f1();</div><div>}<br>inl1.cpp:<br><div>#include "inl.h"</div><div>void c1() {</div><div>  f2();</div><div>}<br>inl2.cpp:<br><div>#include "inl.h"</div><div>void c2() {</div><div>  f2();</div><div>}<br><br>Compile to IR, llvm-link the result. The DWARF you get is basically the same as the DWARF you'd get without linking:<br><br>DW_TAG_compile_unit<br>  DW_AT_name "inl1.cpp"<br>  DW_TAG_subprogram #0<br>    DW_AT_name "f2"</div></div></div><div>  DW_TAG_subprogram<br>    DW_AT_name "c1"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"<div><div><div>DW_TAG_compile_unit<br>  DW_AT_name "inl2.cpp"<br>  DW_TAG_subprogram #1<br>    DW_AT_name "f2"</div></div></div><div>  DW_TAG_subprogram<br>    DW_AT_name "c2"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #1 "f2"<br><br>Instead of something more like this:<br><br><div><div><div>DW_TAG_compile_unit<br>  DW_AT_name "inl1.cpp"<br>  DW_TAG_subprogram #0<br>    DW_AT_name "f2"</div></div></div><div>  DW_TAG_subprogram<br>    DW_AT_name "c1"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"<div><div><div>DW_TAG_compile_unit<br>  DW_AT_name "inl2.cpp"</div></div></div><div>  DW_TAG_subprogram<br>    DW_AT_name "c2"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"</div></div></div><br class="inbox-inbox-Apple-interchange-newline"></div>(note that only one abstract definition of f2 is produced here)<br><br>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><br>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><br>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>