Skip to content

Commit

Permalink
[XCOFF][AIX] Fix getSymbol to return the correct qualname when necessary
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jasonliudev committed Apr 17, 2020
1 parent 96712d6 commit 77618cc
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 92 deletions.
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
Expand Up @@ -258,6 +258,10 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
MCSection *
getSectionForExternalReference(const GlobalObject *GO,
const TargetMachine &TM) const override;

/// For functions, this will always return a function descriptor symbol.
MCSymbol *getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const override;
};

} // end namespace llvm
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/Target/TargetLoweringObjectFile.h
Expand Up @@ -237,6 +237,13 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
return nullptr;
}

/// Targets that have a special convention for their symbols could use
/// this hook to return a specialized symbol.
virtual MCSymbol *getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const {
return nullptr;
}

protected:
virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
SectionKind Kind,
Expand Down
34 changes: 34 additions & 0 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Expand Up @@ -1966,6 +1966,40 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
//===----------------------------------------------------------------------===//
// XCOFF
//===----------------------------------------------------------------------===//
MCSymbol *
TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
const TargetMachine &TM) const {
if (TM.getDataSections())
report_fatal_error("XCOFF unique data sections not yet implemented");

// We always use a qualname symbol for a GV that represents
// a declaration, a function descriptor, or a common symbol.
// It is inherently ambiguous when the GO represents the address of a
// function, as the GO could either represent a function descriptor or a
// function entry point. We choose to always return a function descriptor
// here.
if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {
if (GO->isDeclaration())
return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM))
->getQualNameSymbol();

SectionKind GOKind = getKindForGlobal(GO, TM);
if (GOKind.isText())
return cast<MCSectionXCOFF>(
getSectionForFunctionDescriptor(cast<Function>(GO), TM))
->getQualNameSymbol();
if (GOKind.isCommon() || GOKind.isBSSLocal())
return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
->getQualNameSymbol();
}

// For all other cases, fall back to getSymbol to return the unqualified name.
// This could change for a GV that is a GlobalVariable when we decide to
// support -fdata-sections since we could avoid having label symbols if the
// linkage name is applied to the csect symbol.
return nullptr;
}

MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
report_fatal_error("XCOFF explicit sections not yet implemented.");
Expand Down
112 changes: 20 additions & 92 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Expand Up @@ -83,8 +83,6 @@ class PPCAsmPrinter : public AsmPrinter {
const PPCSubtarget *Subtarget = nullptr;
StackMaps SM;

virtual MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO);

public:
explicit PPCAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
Expand Down Expand Up @@ -150,8 +148,6 @@ class PPCLinuxAsmPrinter : public PPCAsmPrinter {
class PPCAIXAsmPrinter : public PPCAsmPrinter {
private:
static void ValidateGV(const GlobalVariable *GV);
protected:
MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO) override;

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

void SetupMachineFunction(MachineFunction &MF) override;

const MCExpr *lowerConstant(const Constant *CV) override;

void emitGlobalVariable(const GlobalVariable *GV) override;

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

/// Map a machine operand for a TOC pseudo-machine instruction to its
/// corresponding MCSymbol.
MCSymbol *PPCAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
AsmPrinter &AP) {
switch (MO.getType()) {
case MachineOperand::MO_GlobalAddress:
return getSymbol(MO.getGlobal());
return AP.getSymbol(MO.getGlobal());
case MachineOperand::MO_ConstantPoolIndex:
return GetCPISymbol(MO.getIndex());
return AP.GetCPISymbol(MO.getIndex());
case MachineOperand::MO_JumpTableIndex:
return GetJTISymbol(MO.getIndex());
return AP.GetJTISymbol(MO.getIndex());
case MachineOperand::MO_BlockAddress:
return GetBlockAddressSymbol(MO.getBlockAddress());
return AP.GetBlockAddressSymbol(MO.getBlockAddress());
default:
llvm_unreachable("Unexpected operand type to get symbol.");
}
Expand Down Expand Up @@ -664,7 +659,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
"Invalid operand for LWZtoc.");

// Map the operand to its corresponding MCSymbol.
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO);
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

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

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

// Map the machine operand to its corresponding MCSymbol.
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

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

// Map the machine operand to its corresponding MCSymbol.
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

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

const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

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

const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

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

const MCExpr *Exp =
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO),
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO, *this),
MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
Expand Down Expand Up @@ -1599,18 +1594,6 @@ void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
report_fatal_error("COMDAT not yet supported by AIX.");
}

const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) {
if (const Function *F = dyn_cast<Function>(CV)) {
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
F->isDeclaration()
? getObjFileLowering().getSectionForExternalReference(F, TM)
: getObjFileLowering().getSectionForFunctionDescriptor(F, TM));

return MCSymbolRefExpr::create(Csect->getQualNameSymbol(), OutContext);
}
return PPCAsmPrinter::lowerConstant(CV);
}

static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
return StringSwitch<bool>(GV->getName())
.Cases("llvm.global_ctors", "llvm.global_dtors", true)
Expand All @@ -1632,25 +1615,18 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
GVSym->setStorageClass(
TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));

SectionKind GVKind;

// Create the containing csect and set it. We set it for externals as well,
// since this may not have been set elsewhere depending on how they are used.
MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
GV->isDeclaration()
? getObjFileLowering().getSectionForExternalReference(GV, TM)
: getObjFileLowering().SectionForGlobal(
GV, GVKind = getObjFileLowering().getKindForGlobal(GV, TM),
TM));

// External global variables are already handled.
if (GV->isDeclaration())
return;

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

MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
getObjFileLowering().SectionForGlobal(GV, GVKind, TM));

// Switch to the containing csect.
OutStreamer->SwitchSection(Csect);

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

if (GVKind.isBSSLocal())
OutStreamer->emitXCOFFLocalCommonSymbol(
GVSym, Size, Csect->getQualNameSymbol(), Align);
OutContext.getOrCreateSymbol(GVSym->getUnqualifiedName()), Size,
GVSym, Align);
else
OutStreamer->emitCommonSymbol(Csect->getQualNameSymbol(), Size, Align);
OutStreamer->emitCommonSymbol(GVSym, Size, Align);
return;
}

Expand Down Expand Up @@ -1733,55 +1710,6 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
}
}

MCSymbol *
PPCAIXAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
const GlobalObject *GO = nullptr;

// If the MO is a function or certain kind of globals, we want to make sure to
// refer to the csect symbol, otherwise we can just do the default handling.
if (MO.getType() != MachineOperand::MO_GlobalAddress ||
!(GO = dyn_cast<const GlobalObject>(MO.getGlobal())))
return PPCAsmPrinter::getMCSymbolForTOCPseudoMO(MO);

// Do an early error check for globals we don't support. This will go away
// eventually.
const auto *GV = dyn_cast<const GlobalVariable>(GO);
if (GV) {
ValidateGV(GV);
}

// If the global object is a global variable without initializer or is a
// declaration of a function, then XSym is an external referenced symbol.
// Hence we may need to explictly create a MCSectionXCOFF for it so that we
// can return its symbol later.
if (GO->isDeclaration()) {
return cast<MCSectionXCOFF>(
getObjFileLowering().getSectionForExternalReference(GO, TM))
->getQualNameSymbol();
}

// Handle initialized global variables and defined functions.
SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);

if (GOKind.isText()) {
// If the MO is a function, we want to make sure to refer to the function
// descriptor csect.
return cast<MCSectionXCOFF>(
getObjFileLowering().getSectionForFunctionDescriptor(
cast<const Function>(GO), TM))
->getQualNameSymbol();
} else if (GOKind.isCommon() || GOKind.isBSSLocal()) {
// If the operand is a common then we should refer to the csect symbol.
return cast<MCSectionXCOFF>(
getObjFileLowering().SectionForGlobal(GO, GOKind, TM))
->getQualNameSymbol();
}

// Other global variables are refered to by labels inside of a single csect,
// so refer to the label directly.
return getSymbol(GV);
}

/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
/// for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/TargetMachine.cpp
Expand Up @@ -258,6 +258,10 @@ void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,

MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
const TargetLoweringObjectFile *TLOF = getObjFileLowering();
// XCOFF symbols could have special naming convention.
if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
return TargetSymbol;

SmallString<128> NameStr;
getNameWithPrefix(NameStr, GV, TLOF->getMangler());
return TLOF->getContext().getOrCreateSymbol(NameStr);
Expand Down

0 comments on commit 77618cc

Please sign in to comment.