<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Nick, <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
that had me thinking, how do we accomplish the same for unused C++<br>
classes or member functions within classes.  I figured we could<br>
accomplish that by changing the linkage type within the llvm IR.  But it<br>
turns out these already get linkonce_odr linkage.<br>
<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_docs_LangRef.html&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=Mfk2qtn1LTDThVkh6-oGglNfMADXfJdty4_bhmuhMHA&m=3RY3z6rPdxy_0Oy4CEi-jBdt2sMSz7N8TMY-iRwu_iA&s=agzyvxE3l0JUyMq3vVgIGnhxBTueawe1mNN-sX0XOZ4&e=" rel="noreferrer" target="_blank">http://llvm.org/docs/LangRef.html</a> states "Unreferenced linkonce globals<br>
are allowed to be discarded"<br>
</blockquote>
<br></span>
The answer is still internalize. Don't include their names in the list of public APIs and they'll be switched to 'internal' linkage, then deleted by the LTO passes.<br></blockquote><div><br></div><div>Thanks, someone else suggested this but I didn't realize this affected the link step vs the opt step so I felt it wasn't working.</div><div>I'm looking at this now but to be clear, is this known to work with llvm-lld or just gnu-ld? Your previous answer of "t<span style="font-size:12.8000001907349px">he right future is a world where lld performs llvm lto for you" had me thinking not to expect any LTO from lld which is why I've been focused on opt.</span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
There is no representation of a class in llvm or .o files. Instead, there's a plain struct which represents the typed memory (ie., storage for the non-static data members only), plus a pile of functions which take a pointer to that memory as their first argument (the member functions taking their 'this' argument).<br></blockquote><div><br></div><div>Got it.. You do see a lot of class.xyz references in the llvm assembly so it's clear what it represents in the C++ code. But I came to C++ from C so I always think of classes that way anyway ;)</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Note that 'static' functions also just change the linkage to internal. So does putting code in an anonymous namespace. The main thing you get out of linker integration into LLVM LTO is that the linker can look at the pile of non-llvm code and determine which symbols are required by the rest of the system and compute that public API list for internalize.<br></blockquote><div><br></div><div>What I was surprised about was the effect "inline" has on linkage in C++ and the fact that defining a member function or constructor within the class body makes it inline.  While I don't understand the choice of the name inline semantically, it makes sense that member functions defined within the class body can be removed when not referenced locally since libraries would certainly provide a header with the definitions in separate C++ files (how the compiler knew to discard all traces of an unused class without knowledge of the whole program is what baffled me earlier but makes sense now).  </div><div><br></div><div>Thanks,</div><div>Ed</div></div></div></div>