Skip to content

Commit 77618cc

Browse files
committed
[XCOFF][AIX] Fix getSymbol to return the correct qualname when necessary
Summary: AIX symbol have qualname and unqualified name. The stock getSymbol could only return unqualified name, which leads us to patch many caller side(lowerConstant, getMCSymbolForTOCPseudoMO). So we should try to address this problem in the callee side(getSymbol) and clean up the caller side instead. Note: this is a "mostly" NFC patch, with a fix for the original lowerConstant behavior. Differential Revision: https://reviews.llvm.org/D78045
1 parent 96712d6 commit 77618cc

File tree

6 files changed

+164
-92
lines changed

6 files changed

+164
-92
lines changed

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
258258
MCSection *
259259
getSectionForExternalReference(const GlobalObject *GO,
260260
const TargetMachine &TM) const override;
261+
262+
/// For functions, this will always return a function descriptor symbol.
263+
MCSymbol *getTargetSymbol(const GlobalValue *GV,
264+
const TargetMachine &TM) const override;
261265
};
262266

263267
} // end namespace llvm

llvm/include/llvm/Target/TargetLoweringObjectFile.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
237237
return nullptr;
238238
}
239239

240+
/// Targets that have a special convention for their symbols could use
241+
/// this hook to return a specialized symbol.
242+
virtual MCSymbol *getTargetSymbol(const GlobalValue *GV,
243+
const TargetMachine &TM) const {
244+
return nullptr;
245+
}
246+
240247
protected:
241248
virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
242249
SectionKind Kind,

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,40 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
19661966
//===----------------------------------------------------------------------===//
19671967
// XCOFF
19681968
//===----------------------------------------------------------------------===//
1969+
MCSymbol *
1970+
TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
1971+
const TargetMachine &TM) const {
1972+
if (TM.getDataSections())
1973+
report_fatal_error("XCOFF unique data sections not yet implemented");
1974+
1975+
// We always use a qualname symbol for a GV that represents
1976+
// a declaration, a function descriptor, or a common symbol.
1977+
// It is inherently ambiguous when the GO represents the address of a
1978+
// function, as the GO could either represent a function descriptor or a
1979+
// function entry point. We choose to always return a function descriptor
1980+
// here.
1981+
if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {
1982+
if (GO->isDeclaration())
1983+
return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM))
1984+
->getQualNameSymbol();
1985+
1986+
SectionKind GOKind = getKindForGlobal(GO, TM);
1987+
if (GOKind.isText())
1988+
return cast<MCSectionXCOFF>(
1989+
getSectionForFunctionDescriptor(cast<Function>(GO), TM))
1990+
->getQualNameSymbol();
1991+
if (GOKind.isCommon() || GOKind.isBSSLocal())
1992+
return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
1993+
->getQualNameSymbol();
1994+
}
1995+
1996+
// For all other cases, fall back to getSymbol to return the unqualified name.
1997+
// This could change for a GV that is a GlobalVariable when we decide to
1998+
// support -fdata-sections since we could avoid having label symbols if the
1999+
// linkage name is applied to the csect symbol.
2000+
return nullptr;
2001+
}
2002+
19692003
MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
19702004
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
19712005
report_fatal_error("XCOFF explicit sections not yet implemented.");

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 20 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ class PPCAsmPrinter : public AsmPrinter {
8383
const PPCSubtarget *Subtarget = nullptr;
8484
StackMaps SM;
8585

86-
virtual MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO);
87-
8886
public:
8987
explicit PPCAsmPrinter(TargetMachine &TM,
9088
std::unique_ptr<MCStreamer> Streamer)
@@ -150,8 +148,6 @@ class PPCLinuxAsmPrinter : public PPCAsmPrinter {
150148
class PPCAIXAsmPrinter : public PPCAsmPrinter {
151149
private:
152150
static void ValidateGV(const GlobalVariable *GV);
153-
protected:
154-
MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO) override;
155151

156152
public:
157153
PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
@@ -161,8 +157,6 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
161157

162158
void SetupMachineFunction(MachineFunction &MF) override;
163159

164-
const MCExpr *lowerConstant(const Constant *CV) override;
165-
166160
void emitGlobalVariable(const GlobalVariable *GV) override;
167161

168162
void emitFunctionDescriptor() override;
@@ -494,16 +488,17 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
494488

495489
/// Map a machine operand for a TOC pseudo-machine instruction to its
496490
/// corresponding MCSymbol.
497-
MCSymbol *PPCAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
491+
static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
492+
AsmPrinter &AP) {
498493
switch (MO.getType()) {
499494
case MachineOperand::MO_GlobalAddress:
500-
return getSymbol(MO.getGlobal());
495+
return AP.getSymbol(MO.getGlobal());
501496
case MachineOperand::MO_ConstantPoolIndex:
502-
return GetCPISymbol(MO.getIndex());
497+
return AP.GetCPISymbol(MO.getIndex());
503498
case MachineOperand::MO_JumpTableIndex:
504-
return GetJTISymbol(MO.getIndex());
499+
return AP.GetJTISymbol(MO.getIndex());
505500
case MachineOperand::MO_BlockAddress:
506-
return GetBlockAddressSymbol(MO.getBlockAddress());
501+
return AP.GetBlockAddressSymbol(MO.getBlockAddress());
507502
default:
508503
llvm_unreachable("Unexpected operand type to get symbol.");
509504
}
@@ -664,7 +659,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
664659
"Invalid operand for LWZtoc.");
665660

666661
// Map the operand to its corresponding MCSymbol.
667-
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO);
662+
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
668663

669664
// Create a reference to the GOT entry for the symbol. The GOT entry will be
670665
// synthesized later.
@@ -723,7 +718,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
723718
// global address operand to be a reference to the TOC entry we will
724719
// synthesize later.
725720
MCSymbol *TOCEntry =
726-
lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO));
721+
lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO, *this));
727722

728723
const MCSymbolRefExpr::VariantKind VK =
729724
IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC;
@@ -749,7 +744,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
749744
"Invalid operand for ADDIStocHA.");
750745

751746
// Map the machine operand to its corresponding MCSymbol.
752-
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
747+
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
753748

754749
// Always use TOC on AIX. Map the global address operand to be a reference
755750
// to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
@@ -779,7 +774,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
779774
"Invalid operand for LWZtocL.");
780775

781776
// Map the machine operand to its corresponding MCSymbol.
782-
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
777+
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
783778

784779
// Always use TOC on AIX. Map the global address operand to be a reference
785780
// to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
@@ -807,7 +802,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
807802
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
808803
"Invalid operand for ADDIStocHA8!");
809804

810-
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
805+
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
811806

812807
const bool GlobalToc =
813808
MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
@@ -851,7 +846,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
851846
"LDtocL used on symbol that could be accessed directly is "
852847
"invalid. Must match ADDIStocHA8."));
853848

854-
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
849+
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
855850

856851
if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
857852
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
@@ -881,7 +876,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
881876
"Interposable definitions must use indirect access."));
882877

883878
const MCExpr *Exp =
884-
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO),
879+
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO, *this),
885880
MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
886881
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
887882
EmitToStreamer(*OutStreamer, TmpInst);
@@ -1599,18 +1594,6 @@ void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
15991594
report_fatal_error("COMDAT not yet supported by AIX.");
16001595
}
16011596

1602-
const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) {
1603-
if (const Function *F = dyn_cast<Function>(CV)) {
1604-
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
1605-
F->isDeclaration()
1606-
? getObjFileLowering().getSectionForExternalReference(F, TM)
1607-
: getObjFileLowering().getSectionForFunctionDescriptor(F, TM));
1608-
1609-
return MCSymbolRefExpr::create(Csect->getQualNameSymbol(), OutContext);
1610-
}
1611-
return PPCAsmPrinter::lowerConstant(CV);
1612-
}
1613-
16141597
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
16151598
return StringSwitch<bool>(GV->getName())
16161599
.Cases("llvm.global_ctors", "llvm.global_dtors", true)
@@ -1632,25 +1615,18 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
16321615
GVSym->setStorageClass(
16331616
TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
16341617

1635-
SectionKind GVKind;
1636-
1637-
// Create the containing csect and set it. We set it for externals as well,
1638-
// since this may not have been set elsewhere depending on how they are used.
1639-
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
1640-
GV->isDeclaration()
1641-
? getObjFileLowering().getSectionForExternalReference(GV, TM)
1642-
: getObjFileLowering().SectionForGlobal(
1643-
GV, GVKind = getObjFileLowering().getKindForGlobal(GV, TM),
1644-
TM));
1645-
16461618
// External global variables are already handled.
16471619
if (GV->isDeclaration())
16481620
return;
16491621

1622+
SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
16501623
if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly())
16511624
report_fatal_error("Encountered a global variable kind that is "
16521625
"not supported yet.");
16531626

1627+
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
1628+
getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
1629+
16541630
// Switch to the containing csect.
16551631
OutStreamer->SwitchSection(Csect);
16561632

@@ -1664,9 +1640,10 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
16641640

16651641
if (GVKind.isBSSLocal())
16661642
OutStreamer->emitXCOFFLocalCommonSymbol(
1667-
GVSym, Size, Csect->getQualNameSymbol(), Align);
1643+
OutContext.getOrCreateSymbol(GVSym->getUnqualifiedName()), Size,
1644+
GVSym, Align);
16681645
else
1669-
OutStreamer->emitCommonSymbol(Csect->getQualNameSymbol(), Size, Align);
1646+
OutStreamer->emitCommonSymbol(GVSym, Size, Align);
16701647
return;
16711648
}
16721649

@@ -1733,55 +1710,6 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
17331710
}
17341711
}
17351712

1736-
MCSymbol *
1737-
PPCAIXAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
1738-
const GlobalObject *GO = nullptr;
1739-
1740-
// If the MO is a function or certain kind of globals, we want to make sure to
1741-
// refer to the csect symbol, otherwise we can just do the default handling.
1742-
if (MO.getType() != MachineOperand::MO_GlobalAddress ||
1743-
!(GO = dyn_cast<const GlobalObject>(MO.getGlobal())))
1744-
return PPCAsmPrinter::getMCSymbolForTOCPseudoMO(MO);
1745-
1746-
// Do an early error check for globals we don't support. This will go away
1747-
// eventually.
1748-
const auto *GV = dyn_cast<const GlobalVariable>(GO);
1749-
if (GV) {
1750-
ValidateGV(GV);
1751-
}
1752-
1753-
// If the global object is a global variable without initializer or is a
1754-
// declaration of a function, then XSym is an external referenced symbol.
1755-
// Hence we may need to explictly create a MCSectionXCOFF for it so that we
1756-
// can return its symbol later.
1757-
if (GO->isDeclaration()) {
1758-
return cast<MCSectionXCOFF>(
1759-
getObjFileLowering().getSectionForExternalReference(GO, TM))
1760-
->getQualNameSymbol();
1761-
}
1762-
1763-
// Handle initialized global variables and defined functions.
1764-
SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
1765-
1766-
if (GOKind.isText()) {
1767-
// If the MO is a function, we want to make sure to refer to the function
1768-
// descriptor csect.
1769-
return cast<MCSectionXCOFF>(
1770-
getObjFileLowering().getSectionForFunctionDescriptor(
1771-
cast<const Function>(GO), TM))
1772-
->getQualNameSymbol();
1773-
} else if (GOKind.isCommon() || GOKind.isBSSLocal()) {
1774-
// If the operand is a common then we should refer to the csect symbol.
1775-
return cast<MCSectionXCOFF>(
1776-
getObjFileLowering().SectionForGlobal(GO, GOKind, TM))
1777-
->getQualNameSymbol();
1778-
}
1779-
1780-
// Other global variables are refered to by labels inside of a single csect,
1781-
// so refer to the label directly.
1782-
return getSymbol(GV);
1783-
}
1784-
17851713
/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
17861714
/// for a MachineFunction to the given output stream, in a format that the
17871715
/// Darwin assembler can deal with.

llvm/lib/Target/TargetMachine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
258258

259259
MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
260260
const TargetLoweringObjectFile *TLOF = getObjFileLowering();
261+
// XCOFF symbols could have special naming convention.
262+
if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
263+
return TargetSymbol;
264+
261265
SmallString<128> NameStr;
262266
getNameWithPrefix(NameStr, GV, TLOF->getMangler());
263267
return TLOF->getContext().getOrCreateSymbol(NameStr);

0 commit comments

Comments
 (0)