[llvm] r298157 - Add !associated metadata.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 17 15:17:25 PDT 2017
Author: eugenis
Date: Fri Mar 17 17:17:24 2017
New Revision: 298157
URL: http://llvm.org/viewvc/llvm-project?rev=298157&view=rev
Log:
Add !associated metadata.
This is an ELF-specific thing that adds SHF_LINK_ORDER to the global's section
pointing to the metadata argument's section. The effect of that is a reverse dependency
between sections for the linker GC.
!associated does not change the behavior of global-dce. The global
may also need to be added to llvm.compiler.used.
Since SHF_LINK_ORDER is per-section, !associated effectively enables
fdata-sections for the affected globals, the same as comdats do.
Differential Revision: https://reviews.llvm.org/D29104
Added:
llvm/trunk/test/CodeGen/X86/elf-associated.ll
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/include/llvm/IR/LLVMContext.h
llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/trunk/lib/IR/LLVMContext.cpp
llvm/trunk/test/ThinLTO/X86/lazyload_metadata.ll
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=298157&r1=298156&r2=298157&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Fri Mar 17 17:17:24 2017
@@ -5106,6 +5106,31 @@ Examples:
See :doc:`TypeMetadata`.
+'``associated``' Metadata
+^^^^^^^^^^^^^^^^^^^
+
+The ``associated`` metadata may be attached to a global object
+declaration with a single argument that references another global object.
+
+This metadata prevents discarding of the global object in linker GC
+unless the referenced object is also discarded. The linker support for
+this feature is spotty. For best compatibility, globals carrying this
+metadata may also:
+
+- Be in a comdat with the referenced global.
+- Be in @llvm.compiler.used.
+- Have an explicit section with a name which is a valid C identifier.
+
+It does not have any effect on non-ELF targets.
+
+Example:
+
+.. code-block:: llvm
+ $a = comdat any
+ @a = global i32 1, comdat $a
+ @b = internal global i32 2, comdat $a, section "abc", !associated !0
+ !0 = !{i32* @a}
+
Module Flags Metadata
=====================
Modified: llvm/trunk/include/llvm/IR/LLVMContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=298157&r1=298156&r2=298157&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
+++ llvm/trunk/include/llvm/IR/LLVMContext.h Fri Mar 17 17:17:24 2017
@@ -78,6 +78,7 @@ public:
MD_type = 19, // "type"
MD_section_prefix = 20, // "section_prefix"
MD_absolute_symbol = 21, // "absolute_symbol"
+ MD_associated = 22, // "associated"
};
/// Known operand bundle tag IDs, which always have the same value. All
Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=298157&r1=298156&r2=298157&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Fri Mar 17 17:17:24 2017
@@ -225,6 +225,20 @@ static const Comdat *getELFComdat(const
return C;
}
+static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO,
+ const TargetMachine &TM) {
+ MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);
+ if (!MD)
+ return nullptr;
+
+ auto *VM = dyn_cast<ValueAsMetadata>(MD->getOperand(0));
+ if (!VM)
+ report_fatal_error("MD_associated operand is not ValueAsMetadata");
+
+ GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue());
+ return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr;
+}
+
MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
StringRef SectionName = GO->getSection();
@@ -238,9 +252,23 @@ MCSection *TargetLoweringObjectFileELF::
Group = C->getName();
Flags |= ELF::SHF_GROUP;
}
- return getContext().getELFSection(SectionName,
- getELFSectionType(SectionName, Kind), Flags,
- /*EntrySize=*/0, Group);
+
+ // A section can have at most one associated section. Put each global with
+ // MD_associated in a unique section.
+ unsigned UniqueID = MCContext::GenericSectionID;
+ const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
+ if (AssociatedSymbol) {
+ UniqueID = NextUniqueID++;
+ Flags |= ELF::SHF_LINK_ORDER;
+ }
+
+ MCSectionELF *Section = getContext().getELFSection(
+ SectionName, getELFSectionType(SectionName, Kind), Flags,
+ /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol);
+ // Make sure that we did not get some other section with incompatible sh_link.
+ // This should not be possible due to UniqueID code above.
+ assert(Section->getAssociatedSymbol() == AssociatedSymbol);
+ return Section;
}
/// Return the section prefix name used by options FunctionsSections and
@@ -262,11 +290,10 @@ static StringRef getSectionPrefixForGlob
return ".data.rel.ro";
}
-static MCSectionELF *
-selectELFSectionForGlobal(MCContext &Ctx, const GlobalObject *GO,
- SectionKind Kind, Mangler &Mang,
- const TargetMachine &TM, bool EmitUniqueSection,
- unsigned Flags, unsigned *NextUniqueID) {
+static MCSectionELF *selectELFSectionForGlobal(
+ MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
+ unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
unsigned EntrySize = 0;
if (Kind.isMergeableCString()) {
if (Kind.isMergeable2ByteCString()) {
@@ -333,7 +360,7 @@ selectELFSectionForGlobal(MCContext &Ctx
if (Kind.isExecuteOnly())
UniqueID = 0;
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
- EntrySize, Group, UniqueID);
+ EntrySize, Group, UniqueID, AssociatedSymbol);
}
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
@@ -351,8 +378,17 @@ MCSection *TargetLoweringObjectFileELF::
}
EmitUniqueSection |= GO->hasComdat();
- return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
- EmitUniqueSection, Flags, &NextUniqueID);
+ const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
+ if (AssociatedSymbol) {
+ EmitUniqueSection = true;
+ Flags |= ELF::SHF_LINK_ORDER;
+ }
+
+ MCSectionELF *Section = selectELFSectionForGlobal(
+ getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags,
+ &NextUniqueID, AssociatedSymbol);
+ assert(Section->getAssociatedSymbol() == AssociatedSymbol);
+ return Section;
}
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
@@ -365,8 +401,9 @@ MCSection *TargetLoweringObjectFileELF::
return ReadOnlySection;
return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
- getMangler(), TM, EmitUniqueSection, ELF::SHF_ALLOC,
- &NextUniqueID);
+ getMangler(), TM, EmitUniqueSection,
+ ELF::SHF_ALLOC, &NextUniqueID,
+ /* AssociatedSymbol */ nullptr);
}
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
Modified: llvm/trunk/lib/IR/LLVMContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=298157&r1=298156&r2=298157&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContext.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContext.cpp Fri Mar 17 17:17:24 2017
@@ -58,6 +58,7 @@ LLVMContext::LLVMContext() : pImpl(new L
{MD_type, "type"},
{MD_section_prefix, "section_prefix"},
{MD_absolute_symbol, "absolute_symbol"},
+ {MD_associated, "associated"},
};
for (auto &MDKind : MDKinds) {
Added: llvm/trunk/test/CodeGen/X86/elf-associated.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/elf-associated.ll?rev=298157&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/elf-associated.ll (added)
+++ llvm/trunk/test/CodeGen/X86/elf-associated.ll Fri Mar 17 17:17:24 2017
@@ -0,0 +1,39 @@
+; RUN: llc -data-sections=1 -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
+; RUN: llc -data-sections=0 -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
+
+ at a = global i32 1
+ at b = global i32 2, !associated !0
+!0 = !{i32* @a}
+; CHECK-DAG: .section .data.b,"awm", at progbits,a
+
+; Loop is OK. Also, normally -data-sections=0 would place @c and @d in the same section. !associated prevents that.
+ at c = global i32 2, !associated !2
+ at d = global i32 2, !associated !1
+!1 = !{i32* @c}
+!2 = !{i32* @d}
+; CHECK-DAG: .section .data.c,"awm", at progbits,d
+; CHECK-DAG: .section .data.d,"awm", at progbits,c
+
+; BSS is OK.
+ at e = global i32 0
+ at f = global i32 0, !associated !3
+ at g = global i32 1, !associated !3
+!3 = !{i32* @e}
+; CHECK-DAG: .section .bss.f,"awm", at nobits,e
+; CHECK-DAG: .section .data.g,"awm", at progbits,e
+
+; Explicit sections.
+ at h = global i32 1, section "aaa"
+ at i = global i32 1, section "bbb", !associated !4
+ at j = global i32 1, section "bbb", !associated !4
+ at k = global i32 1, !associated !4
+!4 = !{i32* @h}
+; CHECK-DAG: .section aaa,"aw", at progbits
+; CHECK-DAG: .section bbb,"awm", at progbits,h,unique,1
+; CHECK-DAG: .section bbb,"awm", at progbits,h,unique,2
+; CHECK-DAG: .section .data.k,"awm", at progbits,h
+
+; Non-GlobalObject metadata.
+ at l = global i32 1, section "ccc", !associated !5
+!5 = !{i32* null}
+; CHECK-DAG: .section ccc,"aw", at progbits
Modified: llvm/trunk/test/ThinLTO/X86/lazyload_metadata.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/lazyload_metadata.ll?rev=298157&r1=298156&r2=298157&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/lazyload_metadata.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/lazyload_metadata.ll Fri Mar 17 17:17:24 2017
@@ -10,13 +10,13 @@
; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc \
; RUN: -o /dev/null -stats \
; RUN: 2>&1 | FileCheck %s -check-prefix=LAZY
-; LAZY: 49 bitcode-reader - Number of Metadata records loaded
+; LAZY: 51 bitcode-reader - Number of Metadata records loaded
; LAZY: 2 bitcode-reader - Number of MDStrings loaded
; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc \
; RUN: -o /dev/null -disable-ondemand-mds-loading -stats \
; RUN: 2>&1 | FileCheck %s -check-prefix=NOTLAZY
-; NOTLAZY: 58 bitcode-reader - Number of Metadata records loaded
+; NOTLAZY: 60 bitcode-reader - Number of Metadata records loaded
; NOTLAZY: 7 bitcode-reader - Number of MDStrings loaded
@@ -55,4 +55,4 @@ declare i1 @llvm.type.test(i8* %ptr, met
!6 = !{!9}
!7 = !{!"7"}
!8 = !{!"8"}
-!9 = !{!6}
\ No newline at end of file
+!9 = !{!6}
More information about the llvm-commits
mailing list