diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index db6eefdb999..27d2c4b356d 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -97,6 +97,13 @@ void ARMAsmPrinter::EmitXXStructor(const DataLayout &DL, const Constant *CV) { OutStreamer->EmitValue(E, Size); } +void ARMAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { + if (PromotedGlobals.count(GV)) + // The global was promoted into a constant pool. It should not be emitted. + return; + AsmPrinter::EmitGlobalVariable(GV); +} + /// runOnMachineFunction - This uses the EmitInstruction() /// method to print assembly for each instruction. /// @@ -109,6 +116,12 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { const Function* F = MF.getFunction(); const TargetMachine& TM = MF.getTarget(); + // Collect all globals that had their storage promoted to a constant pool. + // Functions are emitted before variables, so this accumulates promoted + // globals from all functions in PromotedGlobals. + for (auto *GV : AFI->getGlobalsPromotedToConstantPool()) + PromotedGlobals.insert(GV); + // Calculate this function's optimization goal. unsigned OptimizationGoal; if (F->hasFnAttribute(Attribute::OptimizeNone)) @@ -1002,6 +1015,26 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); + if (ACPV->isPromotedGlobal()) { + // This constant pool entry is actually a global whose storage has been + // promoted into the constant pool. This global may be referenced still + // by debug information, and due to the way AsmPrinter is set up, the debug + // info is immutable by the time we decide to promote globals to constant + // pools. Because of this, we need to ensure we emit a symbol for the global + // with private linkage (the default) so debug info can refer to it. + // + // However, if this global is promoted into several functions we must ensure + // we don't try and emit duplicate symbols! + auto *ACPC = cast<ARMConstantPoolConstant>(ACPV); + auto *GV = ACPC->getPromotedGlobal(); + if (!EmittedPromotedGlobalLabels.count(GV)) { + MCSymbol *GVSym = getSymbol(GV); + OutStreamer->EmitLabel(GVSym); + EmittedPromotedGlobalLabels.insert(GV); + } + return EmitGlobalConstant(DL, ACPC->getPromotedGlobalInit()); + } + MCSymbol *MCSym; if (ACPV->isLSDA()) { MCSym = getCurExceptionSym(); |