summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMAsmPrinter.cpp33
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();
OpenPOWER on IntegriCloud