<div dir="ltr">It's documented: <a href="http://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable">http://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable</a><div><br></div><div>OK, I apologize, it's terse. :)</div><div><br></div><div>The third field is a global whose comdat group the initializer should be in. On Windows, this is the mechanism that prevents double initialization of static data members of class templates. On Linux, it is an optimization that improves startup time and code size.</div><div><br></div><div>If the third field would be null, then we lump the initialization into the __GLOBAL_sub_I... function to allow for inilining, etc, as David explained.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 7, 2016 at 1:36 AM, Andrew Parker via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I'm trying to understand more about global constructors generated by clang. As far as I understand it, any compilation unit which requires static constructors will cause clang to generate LLVM IR to append to the array:<div><br></div><div>@llvm.global_ctors</div><div><br></div><div>This is an array of structs with 3 elements: a priority, a function pointer and an unknown (seemingly undocumented) member.</div><div><br></div><div>In most cases I only ever see one element in this array (per compilation unit) with name _GLOBAL__sub_I_Filename.cpp. </div><div><br></div><div>However in some more complex cases - which I've yet to pin down but I think relates to templates - I see multiple members. Those members always seem to look something like:</div><div><br></div><div>__cxx_global_var_init89<br></div><div>__cxx_global_var_init90</div><div>_GLOBAL__sub_I_Filename.cpp<br></div><div><br></div><div>Furthermore, the last function usually just wraps other functions with names prefixed by __cxx_global_var_init, e.g.</div><div><br></div><div><div>declare i8* @memset(i8*, i32, i64) #0</div><div>define internal void @__s3e__GLOBAL__sub_I_Filename.cpp() #0 {</div><div>  call void @__cxx_global_var_init(), !dbg !32933</div><div>  call void @__cxx_global_var_init1(), !dbg !32933</div><div>  call void @__cxx_global_var_init2(), !dbg !32933</div><div>  ret void</div><div>}</div></div><div><br></div><div>I'd just like to understand what the logic is behind the generation of these functions. It looks to me like there's implicit constructor priority however the priority member of the @llvm.global_ctors array is never used (well, it's always 65535).</div><div><br></div><div>Does anyone know the secrets behind this?</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>