<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi llvm-dev!<div class=""><br class=""></div><div class="">I'm trying to add dead-stripability of types into the Swift compiler, and for that I need some new affordance in the LLVM IR to be able to express the condition that says "this global can be removed if either of these other globals are removable" -- for a concrete example see below. As pcc has pointed out to me, we already have a !associated metadata, and what I'm looking for is basically a generalization of this concept.</div><div class=""><br class=""></div><div class="">  @a = internal global i32 1</div><div class="">  @b = internal global i32 2</div><div class="">  @assoc = internal global [2 x i32*] { i32* @a, i32* @b } !1</div><div class=""><br class=""></div><div class="">  ... other code here possibly using or not using @a and @b ...</div><div class="">  </div><div class="">  ; Somehow I want to express that the references from @assoc to @a and @b are not to be taken into account</div><div class="">  ; when doing global liveness analysis, and presence of @assoc in @llvm.used and @llvm.compiler.used should</div><div class="">  ; be ignored as well. Instead the references from @assoc to @a and @b are conceptually supposed to be "weak"</div><div class="">  ; references that will not keep targets alive if there are no "strong" (regular) references. And if either @a or @b</div><div class="">  ; (or both) do get removed, then @assoc should also be removed.</div><div class="">  !1 = !{ ... }</div><div class=""><br class=""></div><div class="">  ; We need to mention @assoc in @llvm.used or @llvm.compiler.used, otherwise @assoc is trivially removable.</div><div class="">  @llvm.used = appending global [...] { @assoc }</div><div class=""><br class=""></div><div class="">This example above basically shows the situation of Swift's Protocol Conformance Records, which don't have any incoming static references and instead they are scanned and processed by the runtime (by looking those records up via APIs from the dynamic linker), so they need the @llvm.used marker to survive into the final binary. They reference two other globals, a type record and a protocol record, which means that today they actually keep both the type and the protocol alive transitively, and therefore prohibit dead-stripping of those. So practically, the @llvm.used marker is necessary but also too conservative at the same time, and I want to relax removal rules on these globals -- specifically these Protocol Conformance Records and some other records in similar situations.</div><div class=""><br class=""></div><div class="">What I'm looking for is 1) a design for how to represent this in LLVM IR, 2) and an implementation in GlobalDCE that would actually follow these rules and remove globals whenever allowed. For the latter, me and Manman have prepared a patch, see <<a href="https://reviews.llvm.org/D104496" class="">https://reviews.llvm.org/D104496</a>>, which does the job by adding a new specially named metadata -- !llvm.used.conditional -- that has a specific structure that can express these "conditionally used globals". But mainly I'd like to figure out the former -- what should this look like in the IR. Should we try to extend the existing !associated metadata? If yes, can we teach GlobalDCE to optimize based on !associated markers? Should we have a list like !llvm.used.conditional instead? Should it subsume !associated metadata and replace it?</div><div class=""><br class=""></div><div class="">Thanks ahead for any feedback!</div><div class=""><br class=""></div><div class="">Kuba</div><div class=""><br class=""></div></body></html>