<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 24, 2021, at 23:15, Kuba Mracek via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I'd like to reach an agreement on what's the path forward from here. I am happy to iterate on and refine the "llvm.used.conditional" proposal, and update the patch at <a href="https://reviews.llvm.org/D104496" class="">https://reviews.llvm.org/D104496</a> (enhance the summary, update LangRef to explain the exact semantics, etc.), if you think that this is the right direction? Just as a brief summary, an example of using llvm.used.conditional would be:<div class=""><br class=""></div><div class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>@type_record = internal global ...</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>@protocol_record = internal global ...</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>@conformance_record = internal global [...] { @type_record, @protocol_record }   ; <== this is the global we're trying to remove</div></div></div><div class=""><div class=""><div class=""><br class=""></div></div></div><div class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>; We need to mention @conformance_record in @llvm.used, otherwise @conformance_record is trivially removable.</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>@llvm.used = appending global [...] { @conformance_record }</div></div></div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>; the tuple is in the form of { target symbol that is being marked as removable/non-removable, type, list of other symbols that are triggering liveness }</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>; type is either 0 = if any symbol in the list is alive, the target symbol is alive, or 1 = if all symbols in the list are alive, the target is alive</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>; also can be thought of as 0 = if all the symbols from the list are removed, the target can be removed too, or 1 = if any symbol from the list is removed, the target can be removed</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>!1 = !{ @conformance_record, 1, !{ @type_record, @protocol_record } }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>!llvm.used.conditional = !{ !1 }</div><div class=""><div class=""><br class=""></div><div class="">The actual semantics of !llvm.used.conditional are meant to *allow an optional optimization*, not to have any required behavior from LLVM. So it would be correct for any optimization/transformation to ignore !llvm.used.conditional altogether or be oblivious to it. We'd only extend GlobalDCE to actually perform this optimization (removal of the target symbols) when the conditions in !llvm.used.conditional are satisfied. Also notice that all the ! metadata in the IR are "weak" uses of globals/symbols, so these metadata themselves do not keep normal globals alive.</div><div class=""><br class=""></div><div class="">I see at least one "obvious" alternative, which would be to extend !associated <<a href="https://llvm.org/docs/LangRef.html#associated-metadata" class="">https://llvm.org/docs/LangRef.html#associated-metadata</a>> to be able to express the semantics we need here. The flip side of doing that is that !associated is an existing IR feature with existing semantics, which if extended to be handled by GlobalDCE could potentially break some existing client. But I certainly do see it as possible to extend !associated to:</div></div></div></div></blockquote><br class=""></div><div>I think it would be better to keep it separate from the `!associated` metadata. Given that the “llvm.used.conditional” is there solely to enable an optional additional optimization it shouldn’t impact other users and dropping it should always be a valid transform. Having it completely separate makes it easier to ensure that.</div><div><br class=""></div><div>From the discussion so far, it seems to me like there are no real alternatives at the moment to achieve the kind of code-elimination that will be enabled by “llvm.used.conditional”. This takes into accounts the Swift compiler’s need to use ‘llvm.used” generously for correctness. Therefore I think it might be a good time to try to formalize the semantics of llvm.used.conditional in the linked patch. That should make it easier to see the exact scope of the proposal. Spelling things out may also be helpful to see if llvm.used.conditional is the best possible name.</div><div><br class=""></div><div>Cheers,</div><div>Florian</div><div><br class=""></div><div><br class=""></div></body></html>