Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8441,6 +8441,29 @@ The ``nofree`` metadata indicates the memory pointed by the pointer will not be
freed after the attached instruction.


'``rename.key``' Metadata
^^^^^^^^^^^^^^^^^^^^^^^^^
The rename key may be attached to a global variable definition that has an
explicit section attribute. It is used as a flag so the associated node
must be empty. It only takes effect when function sections is enabled, and
only on XCOFF targets. The metadata will casue the global to be emitted to a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: cause

control section (CSECT) with a name that is an amalgamation of both the section
attribute and the global variables identifier. After the control section is
defined it will be renamed to match the name of the section attribute. This
allows the linker to aggressively garbage collect the symbol if unreferenced,
while directing the linker to merge any control sections with the same name
that remain after garbage collecting into the same CSECT in the output binary.
Commonly used where there is a feature that uses a runtime to walk over a
section using the linker-defined encapsulation symbols
``__start_<section_name>`` and ``__stop_<section_name>``.

Example:

.. code-block:: llvm

@a = global i32 1, section "abc", !rename.key !0
!0 = !{}

Module Flags Metadata
=====================

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/FixedMetadataKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ LLVM_FIXED_MD_KIND(MD_mmra, "mmra", 40)
LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41)
LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42)
LLVM_FIXED_MD_KIND(MD_nofree, "nofree", 43)
LLVM_FIXED_MD_KIND(MD_rename_key, "rename.key", 44)
14 changes: 11 additions & 3 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2431,16 +2431,24 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
if (!GO->hasSection())
report_fatal_error("#pragma clang section is not yet supported");

StringRef SectionName = GO->getSection();
std::string SectionName(GO->getSection());

// Handle the XCOFF::TD case first, then deal with the rest.
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
// Have to check for either attributes or metadata that can affect the
// section type or section name.
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO)) {
if (GVar->hasAttribute("toc-data"))
return getContext().getXCOFFSection(
SectionName, Kind,
XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD),
/* MultiSymbolsAllowed*/ true);

if (TM.getFunctionSections() &&
GVar->hasMetadata(LLVMContext::MD_rename_key)) {
SectionName += ".";
SectionName += GO->getName();
}
}

XCOFF::StorageMappingClass MappingClass;
if (Kind.isText())
MappingClass = XCOFF::XMC_PR;
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,15 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
DL.getIntPtrType(GO->getType()),
RangeLikeMetadataKind::AbsoluteSymbol);
}

if (GO->hasMetadata(LLVMContext::MD_rename_key)) {
SmallVector<MDNode *, 1> MDs;
GO->getMetadata(LLVMContext::MD_rename_key, MDs);
Check(MDs.size() == 1,
"global value cannot have more then 1 rename metadata", GO);
Check(MDs[0]->getNumOperands() == 0,
"rename metadata must have no operands", GO);
}
}

Check(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
Expand Down
106 changes: 64 additions & 42 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2970,58 +2970,80 @@ void PPCAIXAsmPrinter::emitGCOVRefs() {
}

void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
// If there are no functions and there are no toc-data definitions in this
// module, we will never need to reference the TOC base.
if (M.empty() && TOCDataGlobalVars.empty())
return;

emitPGORefs(M);
emitGCOVRefs();

// Switch to section to emit TOC base.
OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
// If there are no functions and there are no toc-data definitions in this
// module, we will never need to reference the TOC base.
if (!M.empty() || !TOCDataGlobalVars.empty()) {
// Switch to section to emit TOC base.
OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());

PPCTargetStreamer *TS =
static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
PPCTargetStreamer *TS =
static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

for (auto &I : TOC) {
MCSectionXCOFF *TCEntry;
// Setup the csect for the current TC entry. If the variant kind is
// VK_AIX_TLSGDM the entry represents the region handle, we create a
// new symbol to prefix the name with a dot.
// If TLS model opt is turned on, create a new symbol to prefix the name
// with a dot.
if (I.first.second == PPC::S_AIX_TLSGDM ||
(Subtarget->hasAIXShLibTLSModelOpt() &&
I.first.second == PPC::S_AIX_TLSLD)) {
SmallString<128> Name;
StringRef Prefix = ".";
Name += Prefix;
Name += static_cast<const MCSymbolXCOFF *>(I.first.first)
->getSymbolTableName();
MCSymbol *S = OutContext.getOrCreateSymbol(Name);
TCEntry = static_cast<MCSectionXCOFF *>(
getObjFileLowering().getSectionForTOCEntry(S, TM));
} else {
TCEntry = static_cast<MCSectionXCOFF *>(
getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
}
OutStreamer->switchSection(TCEntry);

for (auto &I : TOC) {
MCSectionXCOFF *TCEntry;
// Setup the csect for the current TC entry. If the variant kind is
// VK_AIX_TLSGDM the entry represents the region handle, we create a
// new symbol to prefix the name with a dot.
// If TLS model opt is turned on, create a new symbol to prefix the name
// with a dot.
if (I.first.second == PPC::S_AIX_TLSGDM ||
(Subtarget->hasAIXShLibTLSModelOpt() &&
I.first.second == PPC::S_AIX_TLSLD)) {
SmallString<128> Name;
StringRef Prefix = ".";
Name += Prefix;
Name += static_cast<const MCSymbolXCOFF *>(I.first.first)
->getSymbolTableName();
MCSymbol *S = OutContext.getOrCreateSymbol(Name);
TCEntry = static_cast<MCSectionXCOFF *>(
getObjFileLowering().getSectionForTOCEntry(S, TM));
} else {
TCEntry = static_cast<MCSectionXCOFF *>(
getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
OutStreamer->emitLabel(I.second);
TS->emitTCEntry(*I.first.first, I.first.second);
}
OutStreamer->switchSection(TCEntry);

OutStreamer->emitLabel(I.second);
TS->emitTCEntry(*I.first.first, I.first.second);
// Traverse the list of global variables twice, emitting all of the
// non-common global variables before the common ones, as emitting a
// .comm directive changes the scope from .toc to the common symbol.
for (const auto *GV : TOCDataGlobalVars) {
if (!GV->hasCommonLinkage())
emitGlobalVariableHelper(GV);
}
for (const auto *GV : TOCDataGlobalVars) {
if (GV->hasCommonLinkage())
emitGlobalVariableHelper(GV);
}
}

// Traverse the list of global variables twice, emitting all of the
// non-common global variables before the common ones, as emitting a
// .comm directive changes the scope from .toc to the common symbol.
for (const auto *GV : TOCDataGlobalVars) {
if (!GV->hasCommonLinkage())
emitGlobalVariableHelper(GV);
}
for (const auto *GV : TOCDataGlobalVars) {
if (GV->hasCommonLinkage())
emitGlobalVariableHelper(GV);
// Renames only take effect when function sections is enabled.
if (!TM.getFunctionSections())
return;

for (const GlobalVariable &GV : M.globals()) {
if (GV.hasMetadata(LLVMContext::MD_rename_key)) {
// Get orginal csect.
SectionKind GVKind = getObjFileLowering().getKindForGlobal(&GV, TM);
auto *CSect = static_cast<MCSectionXCOFF *>(
getObjFileLowering().SectionForGlobal(&GV, GVKind, TM));

// Get the section to rename to.
if (!GV.hasSection())
reportFatalInternalError(
"rename.key metadata used without a section attribute");

StringRef SectionName = GV.getSection();
OutStreamer->emitXCOFFRenameDirective(CSect->getQualNameSymbol(),
SectionName);
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions llvm/test/CodeGen/PowerPC/aix-rename.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; RUN: llc --function-sections -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck --check-prefix=NOFUNCSECT %s

@a = global i32 1, section "abcd", !rename.key !0
@b = global i32 2, section "abcd", !rename.key !0
@c = global i32 3, section "abcd", !rename.key !0
@d = global i32 4, section "abcd", !rename.key !0

!0 = !{}

;CHECK: .csect abcd.a[RW]
;CHECK: .globl a

;CHECK: .csect abcd.b[RW]
;CHECK: .globl b

;CHECK: .csect abcd.c[RW]
;CHECK: .globl c

;CHECK: .csect abcd.d[RW]
;CHECK: .globl d

;CHECK: .rename abcd.a[RW],"abcd"
;CHECK: .rename abcd.b[RW],"abcd"
;CHECK: .rename abcd.c[RW],"abcd"
;CHECK: .rename abcd.d[RW],"abcd"

;NOFUNCSECT: .csect abcd[RW],2
;NOFUNCSECT-NOT: .csect
;NOFUNCSECT: .globl a
;NOFUNCSECT-NOT: .csect
;NOFUNCSECT: .globl b
;NOFUNCSECT-NOT: .csect
;NOFUNCSECT: .globl c
;NOFUNCSECT-NOT: .csect
;NOFUNCSECT: .globl d

;NOFUNCSECT-NOT: .rename
2 changes: 2 additions & 0 deletions llvm/test/Verifier/PowerPC/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
if not "PowerPC" in config.root.targets:
config.unsupported = True
8 changes: 8 additions & 0 deletions llvm/test/Verifier/PowerPC/multiple_rename.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s

@a = global i32 1, section "abc", !rename.key !0, !rename.key !1

!0 = !{}
!1 = !{}

; CHECK: global value cannot have more then 1 rename metadata
6 changes: 6 additions & 0 deletions llvm/test/Verifier/PowerPC/rename_operands.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s

@a = global i32 1, section "abc", !rename.key !0

!0 = !{!"Hello World!"}
; CHECK: rename metadata must have no operands
Loading