<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Sep 4, 2014 at 7:48 PM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><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">> I see. Using two comdats would still cause the same problem for us,<br>
> no? So the solution in the end is to emit:<br>
><br>
> TU1:<br>
> --------------------------------<br>
> @_ZN1UI1SE1kE = weak_odr constant i32 42, align 4, comdat _ZN1UI1SE1kE<br>
> @_ZGVN1UI1SE1kE = weak_odr global i64 1, comdat _ZN1UI1SE1kE<br>
> --------------------------------<br>
><br>
> TU2:<br>
> -----------------------------------<br>
> @_ZN1UI1SE1kE = weak_odr global i32 0, align 4, comdat _ZN1UI1SE1kE<br>
> @_ZGVN1UI1SE1kE = weak_odr global i64 0, comdat _ZN1UI1SE1kE<br>
> ...<br>
> @llvm.global_ctors = ....<br>
> define internal void @_GLOBAL__I_a() nounwind section ".text.startup" ....<br>
> -----------------------------------<br>
<br>
Restarting a really old thread now that we have comdat support in the IR.<br>
<br>
While the above idea would work, there are two problems with it<br>
<br>
* Existing compilers (clang and gcc) produce a comdat with just the<br>
constant in TU1. Linking one of those with TU2 can still cause a crash<br>
since the guard variable would be undefined.<br>
* It requires always outputting the guard variable.<br>
<br>
Since neither gcc nor clang implement this part of the ABI, I was<br>
thinking if there was a better way to do it. One interesting option is<br>
putting the .init_array of TU2 in the comdat. That is exactly what we<br>
do for windows. In fact, just passing -Xclang -mllvm -Xclang<br>
-enable-structor-comdat will avoids the crash in the above example.<br>
<br>
Given that this has been broken since forever, waiting a bit more for<br>
<a href="https://sourceware.org/bugzilla/show_bug.cgi?id=17350" target="_blank">https://sourceware.org/bugzilla/show_bug.cgi?id=17350</a> to be fixed and<br>
then flipping -enable-structor-comdat might be the best way to fix<br>
this. With that done we can add the function and the guard variable in<br>
TU2 to the comdat to remove a bit of bloat (see attached patch).<br></blockquote><div><br></div><div>Even if this doesn't address the constant vs global crash issues, I think adding the .init_array entry to the comdat is a great startup time optimization. Everything continues to work as it does today, but less code is run during dynamic initialization because all the new TU initializers get deduplicated by the linker.</div><div><br></div><div>It sounds like you are proposing to emit this sort of IR, after the linker bug is fixed:</div><div><br></div><div>// some header:</div><div>int f();</div><div>template <typename T> struct A { static int var; };</div><div>template <typename T> int A<T>::var = f();</div><div>template struct A<int>;</div><div><br></div><div>New TU1:</div><div>-------------</div><div><div>$var = comdat</div><div>@var = weak_odr global i32 0, comdat $var</div><div>@guard = weak_odr global i32 0, comdat $var<br></div><div>define weak_odr void @initializer() comdat $var {</div><div>  ; check @guard</div><div>  store i32 42, i32* @var</div><div>}</div><div>@llvm.global_ctors = [ { i32, void ()*, i8* } x 1 ] [ { i32 65535, void ()* @initializer, i8* bitcast (i32* @var to i8*) } ]</div></div><div><br></div><div>Old TU2:</div><div>--------------</div><div><div>@var = weak_odr global i32 0</div><div>@guard = weak_odr global i32 0<br></div><div>define weak_odr void @initializer() {</div><div>  ; check @guard</div><div>  store i32 42, i32* @var</div><div>}</div><div>@llvm.global_ctors = [ { i32, void ()*, i8* } x 1 ] [ { i32 65535, void ()* @initializer, i8* null } ]</div></div><div><br></div><div>It sounds like we still can't make @var into a constant if we want ABI compatibility with old object files, though.</div><div><br></div><div>However, if we wait until we don't care about old object file compatibility, we can transition to linking new TU1 with this new TU2:</div><div>-------</div><div>$var = comdat</div><div>@var = weak_odr constant i32 42, comdat $var</div><div>; no guard, no initializer, no global_ctors entry</div><div><br></div><div>Is that what you're thinking?</div><div><br></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">
What is the discussion list for the itanium abi? Should I propose a patch?<br></blockquote><div><br></div><div><a href="mailto:cxx-abi-dev@codesourcery.com">cxx-abi-dev@codesourcery.com</a></div></div></div></div>