<div dir="ltr"><div>Representing zero flag ELF section groups as a new type of IR COMDAT is something I considered. I was originally against it because <span style="color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px">semantically it seems backwards since in ELF, COMDAT is a special kind of group, not the other way round. However, I'm definitely biased in the other, that is ELF-centric direction and I agree with you that there's value in minimizing churn. Using a new COMDAT type is by far the easiest way to achieve what we want in IR.</span></div><div><span style="color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 11, 2021 at 2:04 PM Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.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">We are already using LLVM IR comdat groups for the same purpose, linker GC association, on COFF. I think we just need a flag to mark ELF comdat groups as, essentially, not actually being common data that the linker should deduplicate by name, aka a zero flag group. See how Windows ASan uses comdat groups on internal globals for metadata registration:<div><br></div><div>$ cat t.cpp <br>int f();<br>static int gv = f();<br><br>$ clang -S t.cpp  --target=x86_64-windows-msvc -o - -emit-llvm -fsanitize=address</div><div>...<br><div>$gv = comdat noduplicates<br>...<br>@gv = internal global { i32, [60 x i8] } zeroinitializer, comdat, align 32<br>...</div><div>@__asan_global_gv = private global { i64, i64, i64, i64, i64, i64, i64, i64 } { i64 ptrtoint ({ i32, [60 x i8] }* @gv to i64), i64 4, i64 64, i64 ptrtoint ([3 x i8]* @___asan_gen_.1 to i64), i64 ptrtoint ([6 x i8]* @___asan_gen_ to i64), i64 1, i64 ptrtoint ({ [6 x i8]*, i32, i32 }* @___asan_gen_.3 to i64), i64 -1 }, section ".ASAN$GL", comdat($gv), align 64, !associated !0<br></div><div><br></div><div><br></div><div>We are using the "noduplicates" comdat flag here, but @gv has internal linkage, and COFF linkers merge symbols, not section group names, so this code does what we want it to. Maybe it would make more sense if we used some kind of portable flag, like "internal" or "unique" on the comdat group to indicate that the group doesn't participate in merging. On COFF, we'd have the limitation that this feature only works for comdat groups named after internal linkage globals, but on ELF, the group could have any name.</div><div><br></div><div>You could rename the Comdat class to Group or SectionGroup or something, but I'm not sure there's much value in it. The terminology as it is makes sense for COFF, if not for ELF. ELF makes the distinction between comdat section groups and non-comdat section groups, but MSVC and clang-cl use the IMAGE_SCN_COMDAT symbol flag and the IMAGE_COMDAT_SELECT_ASSOCIATIVE selection flag to implement these types of groups.</div><div><br></div><div>Then, there's the cost of churning the textual IR spellings and method names. We have the freedom to change these things, but we should acknowledge that it does create work for ourselves and others. IMO, it is worth living with COFF-centric naming of an IR feature to avoid paying these costs. However, I am probably biased, as I have been calling this idea of a group of sections that travel together a "comdat" for a while now.</div><div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 11, 2021 at 12:00 AM Petr Hosek via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</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">D95851 introduces support for zero flag ELF section groups to LLVM. <span style="color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px">LLVM already supports COMDAT sections, which in ELF are a </span><span style="color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px">special type of ELF section groups. </span>These are generally useful to enable linker GC where you want a group of sections to always travel together, that is to be either retained or discarded as a whole, but without the COMDAT semantics. Other ELF assemblers and linkers already support zero flag ELF section groups and this change helps us reach feature parity.<div><br><div><span style="font-size:13px;color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif">An open question is how to best represent these in LLVM IR.</span></div><div><span style="font-size:13px;color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif"><br></span></div><div><span style="font-size:13px;color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif">We represent COMDAT sections as global variables</span> and other global variables can be included in COMDAT sections, <span style="font-size:13px;color:rgb(0,0,0);font-family:"Segoe UI","Segoe UI Emoji","Segoe UI Symbol",Lato,"Helvetica Neue",Helvetica,Arial,sans-serif">see </span><a href="https://llvm.org/docs/LangRef.html#comdats" target="_blank">https://llvm.org/docs/LangRef.html#comdats</a> for details.</div><div><br></div><div>We want to capture the fact that COMDAT sections are a special type of ELF section groups and we also want to preserve the existing syntax and API for backwards compatibility, but also because other formats like COFF support COMDAT sections, but not section groups.</div><div><br></div><div>Our proposal is to introduce ELF section groups as a new type of global variable akin to COMDAT sections. We would extend the language by changing:</div><div><br></div><div>  [, comdat[($name)]]</div><div><br></div><div>when declaring a global variable to:</div><div><br></div><div>  [, \(group[($name)] | [group] comdat[($name)]\)]</div><div><br></div><div>When it comes to C++ API, we would introduce Group as a superclass of Comdat:</div><div><br></div><div>  class Group {<br>    StringRef getName() const;<br>  };<br>  class Comdat : public Group {<br>    ...<br>  };</div>  class GlobalObject : public GlobalValue {<br>    ...<br>    bool hasGroup();<br>    Group *getGroup();<br>    void setGroup(Group G);<br>    // has/get/setComdat functions re-implemented in terms of has/get/setGroup<br>    ...<br><div>  };<br><br></div></div><div>Does this make sense? Can anyone think of a better representation?</div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</blockquote></div></div>