[llvm] XCOFF associated metadata (PR #159096)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 16 06:43:14 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-powerpc

Author: Sean Fertile (mandlebug)

<details>
<summary>Changes</summary>

Extend the implementation of the associated fixed metadata node to support XCOFF. On AIX the metadata gets lowered to a relocation that adds an explicit link between the section the global that the metadata is placed on is allocated in, to the asscoiated symbol. This relocation wil cause the associated symbol to remain live if the section is not garbage collected. This is used mainly for compiler features where there is some hidden runtime dependancy between the symbols that isn't otherwise obvious to the linker.

---
Full diff: https://github.com/llvm/llvm-project/pull/159096.diff


3 Files Affected:

- (modified) llvm/docs/LangRef.rst (+24-6) 
- (modified) llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (+19) 
- (added) llvm/test/CodeGen/PowerPC/aix-associated-metadata.ll (+23) 


``````````diff
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index d61ea07830123..f89ffd7118869 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -8124,6 +8124,13 @@ See :doc:`CalleeTypeMetadata`.
 
 The ``associated`` metadata may be attached to a global variable definition with
 a single argument that references a global object (optionally through an alias).
+The metadata is often used with an explicit section consisting of valid C
+identifiers so that the runtime can find the metadata section with
+linker-defined encapsulation symbols ``__start_<section_name>`` and
+``__stop_<section_name>``.
+
+ELF Targets
+"""""""""""
 
 This metadata lowers to the ELF section flag ``SHF_LINK_ORDER`` which prevents
 discarding of the global variable in linker GC unless the referenced object is
@@ -8141,12 +8148,6 @@ alive, but this many-to-one relationship is not representable. Moreover, if the
 metadata is retained while the function is discarded, the linker will report an
 error of a relocation referencing a discarded section.
 
-The metadata is often used with an explicit section consisting of valid C
-identifiers so that the runtime can find the metadata section with
-linker-defined encapsulation symbols ``__start_<section_name>`` and
-``__stop_<section_name>``.
-
-It does not have any effect on non-ELF targets.
 
 Example:
 
@@ -8157,6 +8158,23 @@ Example:
     @b = internal global i32 2, comdat $a, section "abc", !associated !0
     !0 = !{ptr @a}
 
+XCOFF Targets
+"""""""""""""
+
+This metadata lowers to the .ref assembly directive which will add a relocation
+representing an implicit reference from the section the global belongs to, to
+the associated symbol. This link will keep the associated symbol alive if the
+section is not garbage collected. More than one associated node can be attached
+to the same global variable.
+
+Example:
+.. code-block:: text
+
+    @a = global i32 1
+    @b = global i32 2
+    @c = global i32 3, section "abc", !associated !0, !associated !1
+    !0 = !{ptr @a}
+    !1 = !{ptr @b}
 
 '``prof``' Metadata
 ^^^^^^^^^^^^^^^^^^^
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 023fd147535ec..be99346752cb2 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -305,6 +305,8 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
   void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
 
   void emitModuleCommandLines(Module &M) override;
+
+  void emitAssociatedMetadata(const GlobalObject *);
 };
 
 } // end anonymous namespace
@@ -2797,6 +2799,10 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
   // Switch to the containing csect.
   OutStreamer->switchSection(Csect);
 
+  if (GV->hasMetadata(LLVMContext::MD_associated)) {
+    emitAssociatedMetadata(GV);
+  }
+
   const DataLayout &DL = GV->getDataLayout();
 
   // Handle common and zero-initialized local symbols.
@@ -3332,6 +3338,19 @@ void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
     OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
 }
 
+void PPCAIXAsmPrinter::emitAssociatedMetadata(const GlobalObject *GO) {
+  SmallVector<MDNode *> MDs;
+  GO->getMetadata(LLVMContext::MD_associated, MDs);
+  assert(MDs.size() && "Expected asscoiated metadata nodes");
+
+  for (const MDNode *MD : MDs) {
+    const ValueAsMetadata *VAM = cast<ValueAsMetadata>(MD->getOperand(0).get());
+    const GlobalValue *Associated = cast<GlobalValue>(VAM->getValue());
+    MCSymbol *Referenced = TM.getSymbol(Associated);
+    OutStreamer->emitXCOFFRefDirective(Referenced);
+  }
+}
+
 // Return a pass that prints the PPC assembly code for a MachineFunction to the
 // given output stream.
 static AsmPrinter *
diff --git a/llvm/test/CodeGen/PowerPC/aix-associated-metadata.ll b/llvm/test/CodeGen/PowerPC/aix-associated-metadata.ll
new file mode 100644
index 0000000000000..edf157934b205
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-associated-metadata.ll
@@ -0,0 +1,23 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+
+ at a = global i32 1
+ at b = global i32 2
+ at c = global i32 3, section "custom_section_c"
+ at d = global i32 4, !associated !0
+ at e = constant i32 5, !associated !1, !associated !2
+ at f = global i32 6, section "custom_section_f", !associated !1
+
+
+!0 = !{ptr @a}
+!1 = !{ptr @b}
+!2 = !{ptr @c}
+
+; CHECK: .csect d[RW]
+; CHECK: .ref a[RW]
+
+; CHECK: .csect e[RO]
+; CHECK: .ref b[RW]
+; CHECK: .ref c
+
+; CHECK: .csect custom_section_f[RW]
+; CHECK: .ref b[RW]

``````````

</details>


https://github.com/llvm/llvm-project/pull/159096


More information about the llvm-commits mailing list