<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jun 20, 2012, at 12:18 AM, Chandler Carruth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family: arial, helvetica, sans-serif"><font size="2"><div class="gmail_quote">On Wed, Jun 20, 2012 at 12:11 AM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Jun 19, 2012, at 11:12 PM, Andrew Trick wrote:<br>
> On Jun 19, 2012, at 10:55 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com">chandlerc@google.com</a>> wrote:<br>
>> On Tue, Jun 19, 2012 at 8:42 PM, Andrew Trick <<a href="mailto:atrick@apple.com">atrick@apple.com</a>> wrote:<br>
>> Author: atrick<br>
>> Date: Tue Jun 19 22:42:09 2012<br>
>> New Revision: 158787<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=158787&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=158787&view=rev</a><br>
>> Log:<br>
>> Move the implementation of LoopInfo into LoopInfoImpl.h.<br>
>><br>
>> The implementation only needs inclusion from LoopInfo.cpp and<br>
>> MachineLoopInfo.cpp. Clients of the interface should only include the<br>
>> interface. This makes the interface readable and speeds up rebuilds<br>
>> after modifying the implementation.<br>
>><br>
>> Technically speaking, I think you need to declare the templates as 'extern' for this to be valid (<a href="http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=549" target="_blank">http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=549</a> is the best link I have).<br>

>><br>
>> This is a C++11 feature, but it is available with GCC since ~forever as an extension. It often "just works" without it, but my understanding is that technically it isn't valid as any old TU that uses these constructs is supposed to have a definition available.<br>

>><br>
>> At least for compilers that support it putting the various things like:<br>
>><br>
>> __extension__ extern template class LoopInfoBase<BasicBlock, Loop>;<br>
>><br>
>> Into the header would make me happier...<br>
>><br>
>> I'm OK relying on compilers to make this "just work" if they don't support the extension (MSVC likely, dunno), but where the do, this will make sure everything works together nicely.<br>
><br>
> I thought the "extern template" was purely an optimization and unlikely to have any benefit with clang in this limited setting. But I'm glad you pointed it out, because I was hoping someone could explain the situation to me.<br>

><br>
> My basis for making the change to explicit instantiation is that we've been using the pattern for a year now elsewhere in LLVM and no one has complained.  I didn't mess with "extern template" because I didn't want to introduce something confusing and compiler-specific without a good reason.<br>

<br>
</div>Short answer:  extern template is unnecessary;  it is sufficient to have an explicit instantiation somewhere in the code.<br></blockquote><div><br></div><div>I'm confused. You say this, but then after you're very thorough explanation you say:</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">An explicit instantiation declaration, e.g.<br>
  extern template llvm::LoopBase<BasicBlock, Loop>;<br>
is a declaration that there exists an explicit instantiation of that template somewhere in the translation unit.  This is a longstanding GCC feature supported both by clang (always) and MSVC (apparently since at least VS2008);  it is now officially codified into C++11.  Some versions of MSVC give extension warnings about it;  I believe GCC and clang do as well, under -pedantic.<br>

<br>
Essentially, an explicit instantiation declaration permits the compiler to not instantiate any function bodies associated with that template.  In LLVM terms, we emit these functions as external declarations at -O0, but as available_externally definitions at -O1 and above.<br>

<br>
So you should be able to get good compile performance with just an extern template declaration and a corresponding explicit instantiation, and this permits inlining/interprocedural analysis as well.</blockquote><div><br>
</div><div>Which seems to contradict this... and...</div></div></font></div></blockquote><div><br></div>I don't see the contradiction.  Andy's patch is a correct solution, but there is an alternative solution that uses extern template.  Both have their merits.</div><div><br><blockquote type="cite"><div style="font-family: arial, helvetica, sans-serif"><font size="2"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  But there's nothing incorrect about what you're doing now.<br>
</blockquote><div><br></div><div>But the definitions for all the member functions are no longer visible to the callers of those member functions... They're only defined in one TU, and only in that TU do we have the explicit instantiation</div></div></font></div></blockquote><div><br></div>That's enough.  There is a translation unit which contains definitions for those member functions and explicitly instantiates them.  That satisifies [temp]p6:  this code is well-formed.</div><div><br></div><div>John.</div></body></html>