Skip to content

Commit 3e4c238

Browse files
author
Zaara Syeda
committed
[AIX] [XCOFF] Add support for common and local common symbols in the TOC
This patch adds support for common and local symbols in the TOC for AIX. Note that we need to update isVirtualSection so as a common symbol in TOC will have the symbol type XTY_CM and will be initialized when placed in the TOC so sections with this type are no longer virtual.
1 parent 47df391 commit 3e4c238

File tree

5 files changed

+43
-16
lines changed

5 files changed

+43
-16
lines changed

llvm/lib/MC/MCSectionXCOFF.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
8282
}
8383

8484
if (isCsect() && getMappingClass() == XCOFF::XMC_TD) {
85+
// Common csect type (uninitialized storage) does not have to print csect
86+
// directive for section switching unless it is local.
87+
if (getKind().isCommon() && !getKind().isBSSLocal())
88+
return;
89+
8590
assert((getKind().isBSSExtern() || getKind().isBSSLocal()) &&
8691
"Unexepected section kind for toc-data");
8792
printCsectDirective(OS);
@@ -135,5 +140,7 @@ bool MCSectionXCOFF::isVirtualSection() const {
135140
return false;
136141
assert(isCsect() &&
137142
"Handling for isVirtualSection not implemented for this section!");
138-
return XCOFF::XTY_CM == CsectProp->Type;
143+
// XTY_CM sections are virtual except for toc-data symbols.
144+
return (XCOFF::XTY_CM == CsectProp->Type) &&
145+
(getMappingClass() != XCOFF::XMC_TD);
139146
}

llvm/lib/MC/XCOFFObjectWriter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,15 @@ CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
533533
return TOCCsects;
534534
case XCOFF::XMC_TC:
535535
case XCOFF::XMC_TE:
536-
case XCOFF::XMC_TD:
537536
assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
538-
"Only an initialized csect can contain TC entry.");
537+
"A TOC symbol must be an initialized csect.");
538+
assert(!TOCCsects.empty() &&
539+
"We should at least have a TOC-base in this CsectGroup.");
540+
return TOCCsects;
541+
case XCOFF::XMC_TD:
542+
assert((XCOFF::XTY_SD == MCSec->getCSectType() ||
543+
XCOFF::XTY_CM == MCSec->getCSectType()) &&
544+
"Symbol type incompatible with toc-data.");
539545
assert(!TOCCsects.empty() &&
540546
"We should at least have a TOC-base in this CsectGroup.");
541547
return TOCCsects;

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,12 +2571,18 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
25712571
GVSym->setStorageClass(
25722572
TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
25732573

2574-
if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal())
2574+
if (GVKind.isBSSLocal() && Csect->getMappingClass() == XCOFF::XMC_TD) {
2575+
OutStreamer->emitZeros(Size);
2576+
} else if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) {
2577+
assert(Csect->getMappingClass() != XCOFF::XMC_TD &&
2578+
"BSS local toc-data already handled and TLS variables "
2579+
"incompatible with XMC_TD");
25752580
OutStreamer->emitXCOFFLocalCommonSymbol(
25762581
OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
25772582
GVSym, Alignment);
2578-
else
2583+
} else {
25792584
OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
2585+
}
25802586
return;
25812587
}
25822588

@@ -2737,8 +2743,17 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
27372743
TS->emitTCEntry(*I.first.first, I.first.second);
27382744
}
27392745

2740-
for (const auto *GV : TOCDataGlobalVars)
2741-
emitGlobalVariableHelper(GV);
2746+
// Traverse the list of global variables twice, emitting all of the
2747+
// non-common global variables before the common ones, as emitting a
2748+
// .comm directive changes the scope from .toc to the common symbol.
2749+
for (const auto *GV : TOCDataGlobalVars) {
2750+
if (!GV->hasCommonLinkage())
2751+
emitGlobalVariableHelper(GV);
2752+
}
2753+
for (const auto *GV : TOCDataGlobalVars) {
2754+
if (GV->hasCommonLinkage())
2755+
emitGlobalVariableHelper(GV);
2756+
}
27422757
}
27432758

27442759
bool PPCAIXAsmPrinter::doInitialization(Module &M) {

llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,10 @@ static bool hasTocDataAttr(SDValue Val, unsigned PointerSize) {
551551
"A GlobalVariable with size larger than a TOC entry is not currently "
552552
"supported by the toc data transformation.");
553553

554-
if (GV->hasLocalLinkage() || GV->hasPrivateLinkage())
555-
report_fatal_error("A GlobalVariable with private or local linkage is not "
554+
if (GV->hasPrivateLinkage())
555+
report_fatal_error("A GlobalVariable with private linkage is not "
556556
"currently supported by the toc data transformation.");
557557

558-
assert(!GV->hasCommonLinkage() &&
559-
"Tentative definitions cannot have the mapping class XMC_TD.");
560-
561558
return true;
562559
}
563560

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs \
1+
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs \
22
; RUN: < %s 2>&1 | FileCheck %s
3-
; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs \
3+
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs \
44
; RUN: < %s 2>&1 | FileCheck %s
55

66
@ilocal = internal global i32 0, align 4 #0
@@ -11,6 +11,8 @@ define dso_local i32 @read_i32_local_linkage() {
1111
ret i32 %0
1212
}
1313

14-
; CHECK: LLVM ERROR: A GlobalVariable with private or local linkage is not currently supported by the toc data transformation.
15-
1614
attributes #0 = { "toc-data" }
15+
16+
; CHECK: .toc
17+
; CHECK-NEXT: .csect ilocal[TD],2
18+
; CHECK-NEXT: .space 4

0 commit comments

Comments
 (0)