[NFC][PowerPC]Clean up PPCAsmPrinter for TOC related pseudo opcode

Add a helper function getMCSymbolForTOCPseudoMO to clean up PPCAsmPrinter
a little bit.

Differential Revision: https://reviews.llvm.org/D68721

llvm-svn: 374420
This commit is contained in:
Xiangling Liao 2019-10-10 18:56:42 +00:00
parent 30a96d3fcb
commit 13bd3ef40d
1 changed files with 69 additions and 92 deletions

View File

@ -78,7 +78,7 @@ namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
MapVector<MCSymbol *, MCSymbol *> TOC;
MapVector<const MCSymbol *, MCSymbol *> TOC;
const PPCSubtarget *Subtarget;
StackMaps SM;
@ -89,7 +89,7 @@ public:
StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym);
bool doInitialization(Module &M) override {
if (!TOC.empty())
@ -338,7 +338,7 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
/// exists for it. If not, create one. Then return a symbol that references
/// the TOC entry.
MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) {
MCSymbol *&TOCEntry = TOC[Sym];
if (!TOCEntry)
TOCEntry = createTempSymbol("C");
@ -512,6 +512,22 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
.addExpr(SymVar));
}
/// Map the machine operand to its corresponding MCSymbol.
static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP) {
switch(MO.getType()) {
case MachineOperand::MO_GlobalAddress:
return AP.getSymbol(MO.getGlobal());
case MachineOperand::MO_ConstantPoolIndex:
return AP.GetCPISymbol(MO.getIndex());
case MachineOperand::MO_JumpTableIndex:
return AP.GetJTISymbol(MO.getIndex());
case MachineOperand::MO_BlockAddress:
return AP.GetBlockAddressSymbol(MO.getBlockAddress());
default:
llvm_unreachable("Unexpected operand type to get symbol.");
}
}
/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
/// the current output stream.
///
@ -668,16 +684,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
"Unexpected operand type for LWZtoc pseudo.");
// Map the operand to its corresponding MCSymbol.
MCSymbol *MOSymbol = nullptr;
if (MO.isGlobal())
MOSymbol = getSymbol(MO.getGlobal());
else if (MO.isCPI())
MOSymbol = GetCPISymbol(MO.getIndex());
else if (MO.isJTI())
MOSymbol = GetJTISymbol(MO.getIndex());
else if (MO.isBlockAddress())
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
const bool IsAIX = TM.getTargetTriple().isOSAIX();
// Create a reference to the GOT entry for the symbol. The GOT entry will be
@ -726,24 +733,18 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Transform %x3 = LDtoc @min1, %x2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
// Change the opcode to LD, and the global address operand to be a
// reference to the TOC entry we will synthesize later.
// Change the opcode to LD.
TmpInst.setOpcode(PPC::LD);
const MachineOperand &MO = MI->getOperand(1);
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
"Invalid operand!");
// Map symbol -> label of TOC entry
assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
MCSymbol *MOSymbol = nullptr;
if (MO.isGlobal())
MOSymbol = getSymbol(MO.getGlobal());
else if (MO.isCPI())
MOSymbol = GetCPISymbol(MO.getIndex());
else if (MO.isJTI())
MOSymbol = GetJTISymbol(MO.getIndex());
else if (MO.isBlockAddress())
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
// Map the machine operand to its corresponding MCSymbol, then map the
// global address operand to be a reference to the TOC entry we will
// synthesize later.
MCSymbol *TOCEntry =
lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO, *this));
const MCExpr *Exp =
MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
@ -757,32 +758,22 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Transform %xd = ADDIStocHA8 %x2, @sym
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
// Change the opcode to ADDIS8. If the global address is external, has
// common linkage, is a non-local function address, or is a jump table
// address, then generate a TOC entry and reference that. Otherwise
// reference the symbol directly.
// Change the opcode to ADDIS8. If the global address is the address of
// an external symbol, is a jump table address, is a block address, or is a
// constant pool index with large code model enabled, then generate a TOC
// entry and reference that. Otherwise, reference the symbol directly.
TmpInst.setOpcode(PPC::ADDIS8);
const MachineOperand &MO = MI->getOperand(2);
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
MO.isBlockAddress()) &&
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
"Invalid operand for ADDIStocHA8!");
MCSymbol *MOSymbol = nullptr;
bool GlobalToc = false;
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
MOSymbol = getSymbol(GV);
GlobalToc = Subtarget->isGVIndirectSymbol(GV);
} else if (MO.isCPI()) {
MOSymbol = GetCPISymbol(MO.getIndex());
} else if (MO.isJTI()) {
MOSymbol = GetJTISymbol(MO.getIndex());
} else if (MO.isBlockAddress()) {
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
}
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
const bool GlobalToc =
MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
TM.getCodeModel() == CodeModel::Large)
(MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
const MCExpr *Exp =
@ -803,36 +794,26 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Transform %xd = LDtocL @sym, %xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
// Change the opcode to LD. If the global address is external, has
// common linkage, or is a jump table address, then reference the
// associated TOC entry. Otherwise reference the symbol directly.
// Change the opcode to LD. If the global address is the address of
// an external symbol, is a jump table address, is a block address, or is
// a constant pool index with large code model enabled, then generate a
// TOC entry and reference that. Otherwise, reference the symbol directly.
TmpInst.setOpcode(PPC::LD);
const MachineOperand &MO = MI->getOperand(1);
assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
MO.isBlockAddress()) &&
"Invalid operand for LDtocL!");
MCSymbol *MOSymbol = nullptr;
if (MO.isJTI())
MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
else if (MO.isBlockAddress()) {
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
LLVM_DEBUG(assert(
(!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
"LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8."));
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
}
else if (MO.isCPI()) {
MOSymbol = GetCPISymbol(MO.getIndex());
if (TM.getCodeModel() == CodeModel::Large)
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
}
else if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
MOSymbol = getSymbol(GV);
LLVM_DEBUG(
assert((Subtarget->isGVIndirectSymbol(GV)) &&
"LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8."));
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
}
const MCExpr *Exp =
MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
@ -845,26 +826,21 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Transform %xd = ADDItocL %xs, @sym
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
// Change the opcode to ADDI8. If the global address is external, then
// generate a TOC entry and reference that. Otherwise reference the
// Change the opcode to ADDI8. If the global address is external, then
// generate a TOC entry and reference that. Otherwise, reference the
// symbol directly.
TmpInst.setOpcode(PPC::ADDI8);
const MachineOperand &MO = MI->getOperand(2);
assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
MCSymbol *MOSymbol = nullptr;
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
LLVM_DEBUG(assert(!(Subtarget->isGVIndirectSymbol(GV)) &&
"Interposable definitions must use indirect access."));
MOSymbol = getSymbol(GV);
} else if (MO.isCPI()) {
MOSymbol = GetCPISymbol(MO.getIndex());
}
const MachineOperand &MO = MI->getOperand(2);
assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL.");
LLVM_DEBUG(
assert(!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
"Interposable definitions must use indirect access."));
const MCExpr *Exp =
MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
OutContext);
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO, *this),
MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
EmitToStreamer(*OutStreamer, TmpInst);
return;
@ -1400,15 +1376,16 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
OutStreamer->SwitchSection(Section);
for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
E = TOC.end(); I != E; ++I) {
OutStreamer->EmitLabel(I->second);
MCSymbol *S = I->first;
for (const auto &TOCMapPair: TOC) {
const MCSymbol *const TOCEntryTarget = TOCMapPair.first;
MCSymbol *const TOCEntryLabel = TOCMapPair.second;
OutStreamer->EmitLabel(TOCEntryLabel);
if (isPPC64) {
TS.emitTCEntry(*S);
TS.emitTCEntry(*TOCEntryTarget);
} else {
OutStreamer->EmitValueToAlignment(4);
OutStreamer->EmitSymbolValue(S, 4);
OutStreamer->EmitSymbolValue(TOCEntryTarget, 4);
}
}
}