llvm.org GIT mirror llvm / df808fe
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298157 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 3 years ago
6 changed file(s) with 119 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
51055105
51065106 See :doc:`TypeMetadata`.
51075107
5108 '``associated``' Metadata
5109 ^^^^^^^^^^^^^^^^^^^
5110
5111 The ``associated`` metadata may be attached to a global object
5112 declaration with a single argument that references another global object.
5113
5114 This metadata prevents discarding of the global object in linker GC
5115 unless the referenced object is also discarded. The linker support for
5116 this feature is spotty. For best compatibility, globals carrying this
5117 metadata may also:
5118
5119 - Be in a comdat with the referenced global.
5120 - Be in @llvm.compiler.used.
5121 - Have an explicit section with a name which is a valid C identifier.
5122
5123 It does not have any effect on non-ELF targets.
5124
5125 Example:
5126
5127 .. code-block:: llvm
5128 $a = comdat any
5129 @a = global i32 1, comdat $a
5130 @b = internal global i32 2, comdat $a, section "abc", !associated !0
5131 !0 = !{i32* @a}
5132
51085133
51095134 Module Flags Metadata
51105135 =====================
7777 MD_type = 19, // "type"
7878 MD_section_prefix = 20, // "section_prefix"
7979 MD_absolute_symbol = 21, // "absolute_symbol"
80 MD_associated = 22, // "associated"
8081 };
8182
8283 /// Known operand bundle tag IDs, which always have the same value. All
224224 return C;
225225 }
226226
227 static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO,
228 const TargetMachine &TM) {
229 MDNode *MD = GO->getMetadata(LLVMContext::MD_associated);
230 if (!MD)
231 return nullptr;
232
233 auto *VM = dyn_cast(MD->getOperand(0));
234 if (!VM)
235 report_fatal_error("MD_associated operand is not ValueAsMetadata");
236
237 GlobalObject *OtherGO = dyn_cast(VM->getValue());
238 return OtherGO ? dyn_cast(TM.getSymbol(OtherGO)) : nullptr;
239 }
240
227241 MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
228242 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
229243 StringRef SectionName = GO->getSection();
237251 Group = C->getName();
238252 Flags |= ELF::SHF_GROUP;
239253 }
240 return getContext().getELFSection(SectionName,
241 getELFSectionType(SectionName, Kind), Flags,
242 /*EntrySize=*/0, Group);
254
255 // A section can have at most one associated section. Put each global with
256 // MD_associated in a unique section.
257 unsigned UniqueID = MCContext::GenericSectionID;
258 const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
259 if (AssociatedSymbol) {
260 UniqueID = NextUniqueID++;
261 Flags |= ELF::SHF_LINK_ORDER;
262 }
263
264 MCSectionELF *Section = getContext().getELFSection(
265 SectionName, getELFSectionType(SectionName, Kind), Flags,
266 /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol);
267 // Make sure that we did not get some other section with incompatible sh_link.
268 // This should not be possible due to UniqueID code above.
269 assert(Section->getAssociatedSymbol() == AssociatedSymbol);
270 return Section;
243271 }
244272
245273 /// Return the section prefix name used by options FunctionsSections and
261289 return ".data.rel.ro";
262290 }
263291
264 static MCSectionELF *
265 selectELFSectionForGlobal(MCContext &Ctx, const GlobalObject *GO,
266 SectionKind Kind, Mangler &Mang,
267 const TargetMachine &TM, bool EmitUniqueSection,
268 unsigned Flags, unsigned *NextUniqueID) {
292 static MCSectionELF *selectELFSectionForGlobal(
293 MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
294 const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
295 unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
269296 unsigned EntrySize = 0;
270297 if (Kind.isMergeableCString()) {
271298 if (Kind.isMergeable2ByteCString()) {
332359 if (Kind.isExecuteOnly())
333360 UniqueID = 0;
334361 return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
335 EntrySize, Group, UniqueID);
362 EntrySize, Group, UniqueID, AssociatedSymbol);
336363 }
337364
338365 MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
350377 }
351378 EmitUniqueSection |= GO->hasComdat();
352379
353 return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
354 EmitUniqueSection, Flags, &NextUniqueID);
380 const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM);
381 if (AssociatedSymbol) {
382 EmitUniqueSection = true;
383 Flags |= ELF::SHF_LINK_ORDER;
384 }
385
386 MCSectionELF *Section = selectELFSectionForGlobal(
387 getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags,
388 &NextUniqueID, AssociatedSymbol);
389 assert(Section->getAssociatedSymbol() == AssociatedSymbol);
390 return Section;
355391 }
356392
357393 MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
364400 return ReadOnlySection;
365401
366402 return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(),
367 getMangler(), TM, EmitUniqueSection, ELF::SHF_ALLOC,
368 &NextUniqueID);
403 getMangler(), TM, EmitUniqueSection,
404 ELF::SHF_ALLOC, &NextUniqueID,
405 /* AssociatedSymbol */ nullptr);
369406 }
370407
371408 bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
5757 {MD_type, "type"},
5858 {MD_section_prefix, "section_prefix"},
5959 {MD_absolute_symbol, "absolute_symbol"},
60 {MD_associated, "associated"},
6061 };
6162
6263 for (auto &MDKind : MDKinds) {
0 ; RUN: llc -data-sections=1 -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
1 ; RUN: llc -data-sections=0 -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
2
3 @a = global i32 1
4 @b = global i32 2, !associated !0
5 !0 = !{i32* @a}
6 ; CHECK-DAG: .section .data.b,"awm",@progbits,a
7
8 ; Loop is OK. Also, normally -data-sections=0 would place @c and @d in the same section. !associated prevents that.
9 @c = global i32 2, !associated !2
10 @d = global i32 2, !associated !1
11 !1 = !{i32* @c}
12 !2 = !{i32* @d}
13 ; CHECK-DAG: .section .data.c,"awm",@progbits,d
14 ; CHECK-DAG: .section .data.d,"awm",@progbits,c
15
16 ; BSS is OK.
17 @e = global i32 0
18 @f = global i32 0, !associated !3
19 @g = global i32 1, !associated !3
20 !3 = !{i32* @e}
21 ; CHECK-DAG: .section .bss.f,"awm",@nobits,e
22 ; CHECK-DAG: .section .data.g,"awm",@progbits,e
23
24 ; Explicit sections.
25 @h = global i32 1, section "aaa"
26 @i = global i32 1, section "bbb", !associated !4
27 @j = global i32 1, section "bbb", !associated !4
28 @k = global i32 1, !associated !4
29 !4 = !{i32* @h}
30 ; CHECK-DAG: .section aaa,"aw",@progbits
31 ; CHECK-DAG: .section bbb,"awm",@progbits,h,unique,1
32 ; CHECK-DAG: .section bbb,"awm",@progbits,h,unique,2
33 ; CHECK-DAG: .section .data.k,"awm",@progbits,h
34
35 ; Non-GlobalObject metadata.
36 @l = global i32 1, section "ccc", !associated !5
37 !5 = !{i32* null}
38 ; CHECK-DAG: .section ccc,"aw",@progbits
99 ; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc \
1010 ; RUN: -o /dev/null -stats \
1111 ; RUN: 2>&1 | FileCheck %s -check-prefix=LAZY
12 ; LAZY: 49 bitcode-reader - Number of Metadata records loaded
12 ; LAZY: 51 bitcode-reader - Number of Metadata records loaded
1313 ; LAZY: 2 bitcode-reader - Number of MDStrings loaded
1414
1515 ; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc \
1616 ; RUN: -o /dev/null -disable-ondemand-mds-loading -stats \
1717 ; RUN: 2>&1 | FileCheck %s -check-prefix=NOTLAZY
18 ; NOTLAZY: 58 bitcode-reader - Number of Metadata records loaded
18 ; NOTLAZY: 60 bitcode-reader - Number of Metadata records loaded
1919 ; NOTLAZY: 7 bitcode-reader - Number of MDStrings loaded
2020
2121
5454 !6 = !{!9}
5555 !7 = !{!"7"}
5656 !8 = !{!"8"}
57 !9 = !{!6}
57 !9 = !{!6}