[llvm-dev] Conditional references between globals in LLVM IR

Florian Hahn via llvm-dev llvm-dev at lists.llvm.org
Fri Oct 1 08:07:36 PDT 2021

> On Sep 24, 2021, at 23:15, Kuba Mracek via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 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 https://reviews.llvm.org/D104496 <https://reviews.llvm.org/D104496> (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:
> 	@type_record = internal global ...
> 	@protocol_record = internal global ...
> 	@conformance_record = internal global [...] { @type_record, @protocol_record }   ; <== this is the global we're trying to remove
> 	; We need to mention @conformance_record in @llvm.used, otherwise @conformance_record is trivially removable.
> 	@llvm.used = appending global [...] { @conformance_record }
> 	; 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 }
> 	; 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
> 	; 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
> 	!1 = !{ @conformance_record, 1, !{ @type_record, @protocol_record } }
> 	!llvm.used.conditional = !{ !1 }
> 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.
> I see at least one "obvious" alternative, which would be to extend !associated <https://llvm.org/docs/LangRef.html#associated-metadata <https://llvm.org/docs/LangRef.html#associated-metadata>> 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:

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.

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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20211001/d79dccb3/attachment.html>

More information about the llvm-dev mailing list