<div dir="ltr"><div dir="ltr">(came across this while looking for other things)<br><br>This is still an issue:<br><br>





<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">$ cat a.cpp</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">#include "a.h"</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">void f3() { f2(); }</span></p>
<p class="gmail-p2" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(57,192,38)"><span class="gmail-s2" style="font-variant-ligatures:no-common-ligatures;color:rgb(0,0,0)">$ cat b.cpp</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">#include "a.h"</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">void f3();</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">void f1() { }</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">int main() {</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>f3();</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>f2();</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">}</span></p>
<p class="gmail-p2" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(57,192,38)"><span class="gmail-s2" style="font-variant-ligatures:no-common-ligatures;color:rgb(0,0,0)">$ cat a.h</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">void f1();</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">struct t1 { int x; };</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">inline __attribute__((always_inline)) void f2(t1 = t1()) { f1(); }<br>$ </span><span style="font-variant-ligatures:no-common-ligatures">$ clang++-tot -fuse-ld=lld -flto a.cpp b.cpp -g && llvm-dwarfdump-tot a.out -debug-info | grep "DW_AT_name\|DW_TAG_\|DW_AT_type" | sed -e </span><span style="font-variant-ligatures:no-common-ligatures">"s/^............//"</span></p>












<p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">DW_TAG_compile_unit</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_AT_name<span class="gmail-Apple-converted-space">    </span>("a.cpp")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("f2")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_formal_parameter</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_type<span class="gmail-Apple-converted-space">        </span>(0x0000003e "t1")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_structure_type</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("t1")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_member</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_name<span class="gmail-Apple-converted-space">        </span>("x")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_type<span class="gmail-Apple-converted-space">        </span>(0x00000054 "int")<br>  ...</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">DW_TAG_compile_unit</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_AT_name<span class="gmail-Apple-converted-space">    </span>("b.cpp")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("f2")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_formal_parameter</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_type<span class="gmail-Apple-converted-space">        </span>(0x000000000000003e "t1")</span></p><p class="gmail-p1" style="margin:0px;font:11px Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  ...</span><br></span></p></div><br>The type (t1) gets deduplicated/shared across CUs (the DW_AT_type in b.cpp uses FORM_ref_addr) but the f2 subprogram is duplicated - though b.cpp's use of it could use ref_addr, and would if the function hadn't been inlined away.<br><br>eg: if we move 'f2' to be defined in a.cpp but attributed always_inline, so it does get cross-unit inlined due to LTO:<br><br>





<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">DW_TAG_compile_unit</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_AT_name<span class="gmail-Apple-converted-space">    </span>("a.cpp")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("f2")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_formal_parameter</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_type<span class="gmail-Apple-converted-space">        </span>(0x0000003e "t1")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_structure_type</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("t1")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_member</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_name<span class="gmail-Apple-converted-space">        </span>("x")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_type<span class="gmail-Apple-converted-space">        </span>(0x00000054 "int")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_base_type</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("int")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("f3")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_inlined_subroutine</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_abstract_origin <span class="gmail-Apple-converted-space">    </span>(0x0000002a "_Z2f22t1")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_TAG_formal_parameter</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">        </span>DW_AT_abstract_origin <span class="gmail-Apple-converted-space">  </span>(0x00000036)</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures">DW_TAG_compile_unit</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_AT_name<span class="gmail-Apple-converted-space">    </span>("b.cpp")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("f1")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">  </span>DW_TAG_subprogram</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_name<span class="gmail-Apple-converted-space">  </span>("main")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_AT_type<span class="gmail-Apple-converted-space">  </span>(0x0000000000000054 "int")</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">    </span>DW_TAG_inlined_subroutine</span></p>
<p class="gmail-p1" style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span class="gmail-s1" style="font-variant-ligatures:no-common-ligatures"><span class="gmail-Apple-converted-space">      </span>DW_AT_abstract_origin <span class="gmail-Apple-converted-space">    </span>(0x000000000000002a "_Z2f22t1")</span></p><br>So now because the cross-CU inlining happened during LTO after module merging - the merging happens when the function's not inlined, module merge picks one llvm::Function, dropping the other one and dropping the other DISubprogram - and then the inlining kicks in, referencing just that single DIsubprogram.<br><br>Not sure if it's of interest to anyone/a priority.<br><br>(side note: Anyone interested in making ThinLTO home type definitions? That'd be great to reduce type duplication - would mean ThinLTO could turn off type units and/or that .o/.dwo/etc files would just generally be smaller anyway)<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Dec 24, 2016 at 10:18 AM David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.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 dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 23, 2016 at 7:25 PM Duncan Exon Smith <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.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 dir="auto"><div><br></div><div><br>On Dec 23, 2016, at 18:36, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 23, 2016 at 11:47 AM Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.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 style="overflow-wrap: break-word;">A few disjoint thoughts; sorry they're so delayed (I skimmed the responses below, and I think these are still relevant/not covered elsewhere).<div><br></div><div>Firstly, why *should* DISubprogram definitions be distinct?  There were two reasons this was valuable (this was from before there was a cu: link).</div><div><br></div><div>- It helped to fix long-standing bugs in the IRLinker, where uniqued-DISubprograms in different compile units would coalesce.</div></div></blockquote><div><br></div><div>Any idea why that ^ was a problem/bugs?</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 style="overflow-wrap: break-word;"><div>  Now that the Function <-> DISubprogram connection has been reversed, I'm not entirely sure it's still a necessary precaution.</div><div><br></div><div>- It broke a several uniquing cycles involving DISubprogram.  The existence of the uniquing cycles meant that affected DISubprograms weren't really uniqued, anyway (since we don't bother to solve graph isomorphism); and breaking the cycles sped up the IRLinker and reduced memory waste.</div></div></blockquote><div><br>Ah, fair point - my trivial example didn't have any local variables, so didn't hit this problem. They do indeed form cycles and I haven't tested, but seems totally reasonable/likely that that would break my simple example because cycles break uniquing and all that.<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 style="overflow-wrap: break-word;"><div>  Making DISubprogram uniqued again would either have no real effect (because distinct nodes they reference aren't uniqued anymore either) or bring back uniquing cycles (which would have effects... but not the desired one).</div><div><br></div><div>But there ought to be a way to get coalescing in the right places.  We just need to ensure that the uniqued/coalesced parts of the graph:</div><div>- are acyclic, and</div><div>- reference only coalesced nodes (note that leaves can happily include the strangely-coalesced distinct DICompositeType beast I created).</div></div></blockquote><div><br>Perhaps before I dive into your suggestion (which, it seems, is to separate out the definition but let the declaration/locals form cycles</div></div></div></div></blockquote><div><br></div></div><div dir="auto"><div>No (new) cycles; in fact this breaks some. </div><div>- the Function itself references the defn and the locals;</div><div>- the locals and the defn reference (transitively) the decl; and</div><div>- the decl doesn't reference any of those.</div><div><br></div><div>The only cycle is the decl <-> composite type one that already exists (and that odr magic (mostly) fixes).  Maybe that one could be removed somehow too, but it isn't directly relevant to the problem you're looking at. </div></div></blockquote><div><br>Oh, yeah - I've an aside there too, maybe for another thread. (punchy summary: anonymous enums in headers used for constants are technically ODR violations (well, if they're ever used in an ODR entity - like an inline function) - they're not public types, so we don't put the mangled name on them & don't deduplicate them in DWARF type units - and probably similarly don't deduplicate them in the IR... - not sure what the right answer is there)<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 dir="auto"><div>(Note that this is somewhat inspired by Reid's point in his recent debug info talk, that CodeView avoids type cycles by breaking types into two records.)</div></div></blockquote><div><br></div><div>Ah, thanks, that helps with me picture it!</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 dir="auto"><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div> - that would at least be dropped because the definition would only be kept due to it being referenced from the llvm::Function), what about something simpler:<br><br>What if scope chains didn't go all the way to the top (the subprogram) but stopped short of that?<br><br>Now, granted - this was part of the great assertion I added several years back that caught all kinds of silliness - mostly around inlined call sites not having debugloc and leading to scope chains that lead to distinct roots. But the alternative to having and maintaining an invariant - is just to make things true by construction. All debug info scope chains within a function with an associated DISubprogram have an implicit last element of that DISubprogram?<br></div></div></div></div></blockquote><div><br></div></div><div dir="auto"><div><div><span style="background-color:rgba(255,255,255,0)">That seems reasonable, I think, now that the function points directly at its subprogram.</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><span style="background-color:rgba(255,255,255,0)">I'm not sure it's simpler to get right though.  Dropping the scope runs the risk of coalescing things incorrectly.  I imagine the backend relies on pointer distinctness of two local variables called "a" that are in (or are parameters of) unrelated subprograms.  I think in some situations they could be coalesced incorrectly if they had no scope. </span></div></div></div></blockquote><div><br></div><div>Just no top level scope - so it'd only happen if you had two variables with the same name in the same scope. It might break in debug-having inline functions inlined into non-debug-having functions (which then might in turn be inlined into a debug-having function) - would have to check.<br><br>Also, not sure if inlined situations might introduce circularity. Yep. The scope for inlinedAt DILocations point to the DISubprogram - so that'd create a cycle. Ah well.</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 dir="auto"><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div>That would mean it'd be harder to catch the bugs I found</div></div></div></div></blockquote><div><br></div></div><div dir="auto"><div>A shame if so, but if we can find another way to catch it or design it away, as you mention, it doesn't much matter. </div></div><div dir="auto"><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><div> - but I think most of them came from that specific inlining situation (I can go back and do some archaeology and see if there's other exposure where we could sure up some defenses as well) which can be caught more directly (I forget if the inliner now catches it itself, or if we enhanced the debug info verifier to catch it after the inliner runs - if it's the verifier, then that wouldn't suffice if we made the change I'm suggesting - and we'd have to hook it up in the inliner itself)<br><br>Thoughts?</div></div></div></div></blockquote><blockquote type="cite"><div dir="ltr"><div class="gmail_quote"><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 style="overflow-wrap: break-word;"><div>I've been thinking idly whether we can/should break DISubprogram apart into uniqued (coalesce-able) and distinct parts.  Still being someone ignorant of DWARF itself (and CodeView, for that matter), I'm not entirely sure.  But...</div><div><br></div><div>Here's my understanding of the current uses of DISubprogram (where I'm using DISubprogramDecl for the usually uniqued declarations, and DISubprogramDefn for the always distinct definitions):</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="Menlo">// !dbg</font></div><div><font face="Menlo">Function -> DISubprogram</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">// Declaration (optional, only for member functions).</font></div><div><font face="Menlo">DISubprogramDefn -> DISubprogramDecl</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">// Variables:</font></div><div><font face="Menlo">DISubprogramDefn -> MDNode -> DILocalVariable</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">// Terminator for scope chains:</font></div><div><font face="Menlo">DILocalVariable [-> DILocalScope [-> ...]]</font><span style="font-family:Menlo"> -></span><span style="font-family:Menlo"> DISubprogramDefn</span></div><div><font face="Menlo">DILocation </font><span style="font-family:Menlo">[-> DILocalScope [-> ...]]</span><span style="font-family:Menlo"> -></span><span style="font-family:Menlo"> DISubprogramDefn</span></div><div><span style="font-family:Menlo">DICompositeType -> DISubprogramDefn // function-local type</span></div><div><br></div><div><span style="font-family:Menlo">// Elements (member functions):</span></div><div><font face="Menlo">DICompositeType -> MDNode -> DISubprogramDecl</font></div><div><div><span style="font-family:Menlo">DISubprogramDecl -> DICompositeType</span></div></div><div><span style="font-family:Menlo">DISubprogramDefn -> DICompositeType</span></div></blockquote><div><br></div><div>And here are the changes I would consider:</div><div><br></div><div>1. Split DISubprogramDecl and DISubprogramDefn into different types.</div><div><br></div><div>2. Remove definition-specific fields from DISubprogramDecl.</div><div>- variables, a "dangerous" source of uniquing cycles.</div><div>- declaration, which it will never have.</div><div>- scopeLine, which it will never have.</div><div>- unit, which the Defn will have when it's relevant.</div><div><br></div><div>3. Make a DISubprogramDecl mandatory for DISubprogramDefn.</div><div><br></div><div>4. Remove redundant fields from DISubprogramDefn.</div><div>- name and linkageName are on the declaration.</div><div>- type is redundant.</div><div>- flags is likely redundant?</div><div><br></div><div>Nothing so far has made any real changes, I think.  DISubprogramDecl should coalesce nicely between modules though.</div><div><br></div><div>5. Migrate links to point at DISubprogramDecl instead of DISubprogramDefn.</div><div>- DILocalVariable scope chain.</div><div>- DILocation scope chain.</div><div>- DICompositeType scope.</div><div><br></div><div>I don't think this will create any uniquing cycles.  DISubprogramDecl won't point at any of these.  Also, DILocalVariable should start coalescing with each other. </div><div><br></div><div>Since DISubprogramDefn is only referenced from the Function !dbg attachment, only one should survive function-coalescing.</div><div><br></div><div>One open question, since I don't know the backend code, is: can you emit the "correct" DWARF after step (5)?  I'm hoping you only need the Defn of the Function that has instructions referencing the DILocalVariable/DILocation.  In which case, we suddenly get a lot of coalescing.</div></div><div style="overflow-wrap: break-word;"><div><br></div><div><blockquote type="cite">On 2016-Dec-15, at 10:54, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br><br>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>void f1();<br>inline __attribute__((always_inline)) void f2() {<br>  f1();<br>}<br>inl1.cpp:<br>#include "inl.h"<br>void c1() {<br>  f2();<br>}<br>inl2.cpp:<br>#include "inl.h"<br>void c2() {<br>  f2();<br>}<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"<br>  DW_TAG_subprogram<br>    DW_AT_name "c1"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"<br>DW_TAG_compile_unit<br>  DW_AT_name "inl2.cpp"<br>  DW_TAG_subprogram #1<br>    DW_AT_name "f2"<br>  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>DW_TAG_compile_unit<br>  DW_AT_name "inl1.cpp"<br>  DW_TAG_subprogram #0<br>    DW_AT_name "f2"<br>  DW_TAG_subprogram<br>    DW_AT_name "c1"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"<br>DW_TAG_compile_unit<br>  DW_AT_name "inl2.cpp"<br>  DW_TAG_subprogram<br>    DW_AT_name "c2"<br>    DW_TAG_inlined_subroutine<br>      DW_TAG_abstract_origin #0 "f2"<br><br>(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.<br></blockquote><br></div></div></blockquote></div></div>
</blockquote></div></blockquote></div></div></blockquote></div></div>