blob: 9d737cfe7388e39d13a1a328d72ff22fe26a939e [file] [log] [blame]
commit ad253446208a06902d3bc4939ac7a64f8026cc84
Author: Arthur Eubanks <aeubanks@google.com>
Date: Mon Aug 2 15:33:07 2021 -0700
[MC][CodeGen] Emit constant pools earlier
Previously we would emit constant pool entries for ldr inline asm at the
very end of AsmPrinter::doFinalization(). However, if we're emitting
dwarf aranges, that would end all sections with aranges. Then if we have
constant pool entries to be emitted in those same sections, we'd hit an
assert that the section has already been ended.
We want to emit constant pool entries before emitting dwarf aranges.
This patch splits out arm32/64's constant pool entry emission into its
own MCTargetStreamer virtual method.
Fixes PR51208
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D107314
---
llvm/include/llvm/MC/MCStreamer.h | 4 ++-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 5 ++++
llvm/lib/MC/MCParser/AsmParser.cpp | 7 +++--
llvm/lib/MC/MCStreamer.cpp | 2 ++
.../AArch64/MCTargetDesc/AArch64TargetStreamer.cpp | 6 +++--
.../AArch64/MCTargetDesc/AArch64TargetStreamer.h | 1 +
.../Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp | 4 ++-
llvm/test/CodeGen/ARM/arange-ldr.ll | 31 ++++++++++++++++++++++
8 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index fd326ff18712..5f93f972a5de 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -123,6 +123,8 @@ public:
/// This is used to emit bytes in \p Data as sequence of .byte directives.
virtual void emitRawBytes(StringRef Data);
+ virtual void emitConstantPools();
+
virtual void finish();
};
@@ -165,7 +167,7 @@ public:
virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value);
- void finish() override;
+ void emitConstantPools() override;
/// Reset any state between object emissions, i.e. the equivalent of
/// MCStreamer's reset method.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e528d33b5f8c..7171bfdd28e2 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1815,6 +1815,11 @@ bool AsmPrinter::doFinalization(Module &M) {
}
}
+ // This needs to happen before emitting debug information since that can end
+ // arbitrary sections.
+ if (auto *TS = OutStreamer->getTargetStreamer())
+ TS->emitConstantPools();
+
// Finalize debug and EH information.
for (const HandlerInfo &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index d3cb5ca59bf3..6e93e3a1bdca 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1052,11 +1052,14 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
}
}
}
-
// Finalize the output stream if there are no errors and if the client wants
// us to.
- if (!HadError && !NoFinalize)
+ if (!HadError && !NoFinalize) {
+ if (auto *TS = Out.getTargetStreamer())
+ TS->emitConstantPools();
+
Out.Finish(Lexer.getLoc());
+ }
return HadError || getContext().hadError();
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index fc7fb555f0b9..99b1290d2355 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -53,6 +53,8 @@ void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
void MCTargetStreamer::finish() {}
+void MCTargetStreamer::emitConstantPools() {}
+
void MCTargetStreamer::changeSection(const MCSection *CurSection,
MCSection *Section,
const MCExpr *Subsection,
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index 557603c24ba5..cf1a60643efd 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -48,11 +48,13 @@ void AArch64TargetStreamer::emitCurrentConstantPool() {
ConstantPools->emitForCurrentSection(Streamer);
}
+void AArch64TargetStreamer::emitConstantPools() {
+ ConstantPools->emitAll(Streamer);
+}
+
// finish() - write out any non-empty assembler constant pools and
// write out note.gnu.properties if need.
void AArch64TargetStreamer::finish() {
- ConstantPools->emitAll(Streamer);
-
if (MarkBTIProperty)
emitNoteSection(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index 9b030775094c..86c7baf8f429 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -23,6 +23,7 @@ public:
~AArch64TargetStreamer() override;
void finish() override;
+ void emitConstantPools() override;
/// Callback used to implement the ldr= pseudo.
/// Add a new entry to the constant pool for the current section and return an
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
index 1fee354cad93..3e4c97630af6 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
@@ -43,7 +43,9 @@ void ARMTargetStreamer::emitCurrentConstantPool() {
}
// finish() - write out any non-empty assembler constant pools.
-void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
+void ARMTargetStreamer::emitConstantPools() {
+ ConstantPools->emitAll(Streamer);
+}
// reset() - Reset any state
void ARMTargetStreamer::reset() {}
diff --git a/llvm/test/CodeGen/ARM/arange-ldr.ll b/llvm/test/CodeGen/ARM/arange-ldr.ll
new file mode 100644
index 000000000000..2c1d0c4f3c1e
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/arange-ldr.ll
@@ -0,0 +1,31 @@
+; RUN: llc %s -o - -generate-arange-section | FileCheck %s
+
+; Make sure that emitting constants for ldr and emitting arange work together.
+; Emitting constants must come before emitting aranges since emitting aranges can end arbitrary sections.
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7-unknown-linux-android21"
+
+; CHECK: ldr r7, .Ltmp[[#TMP:]]
+
+; CHECK: .Ltmp[[#TMP]]:
+; CHECK-NEXT: .long 83040
+
+; CHECK: .section .debug_aranges
+
+define dso_local void @a() local_unnamed_addr !dbg !4 {
+entry:
+ call void asm sideeffect " ldr r7, =${0:c}\0A", "i"(i32 83040)
+ ret void
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "/tmp/a.c", directory: "/tmp/")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "a", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!5 = !DIFile(filename: "/tmp/a.c", directory: "")
+!6 = !DISubroutineType(types: !2)