aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2025-07-18 09:51:21 -0700
committerGitHub <noreply@github.com>2025-07-18 09:51:21 -0700
commit73e4b589ba9526c72f495ca6898ed18d730d2db4 (patch)
treecb47ed45a62ea47be7eb0aef515d044f9b7b9a0a /llvm/lib/MC/MCObjectStreamer.cpp
parent01213141357e4a79d2d97187ff0cb89d8d173634 (diff)
downloadllvm-73e4b589ba9526c72f495ca6898ed18d730d2db4.zip
llvm-73e4b589ba9526c72f495ca6898ed18d730d2db4.tar.gz
llvm-73e4b589ba9526c72f495ca6898ed18d730d2db4.tar.bz2
MC: Simplify fragment reuse determination
First, avoid checking MCSubtargetInfo by reducing unnecessary overhead introduced in https://reviews.llvm.org/D44928 . That change passed STI to both FT_Data and FT_Relaxable fragments, but STI is only necessary for FT_Relaxable. The use of STI in FT_Data was added for: * Bundle alignment mode, which has been removed (#148781). * ARM, which inappropriately uses STI in `ARMAsmBackend::applyFixup` due to tech debt, unlike other targets. All tests passed even without the `copySTI` change. To ensure safety, `copySTI` now starts a new fragment to prevent mixed STI values. Second, avoid checking LinkerRelaxable by eagerly starting a new fragment when a FT_Data/FT_Align fragment is marked linker-relaxable. There is currently an extra empty FT_Data if an alignment immediately follows a linker-relaxable fragment, which will be improved in the future when FT_Align information is moved to the variable-tail. Pull Request: https://github.com/llvm/llvm-project/pull/149471
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp43
1 files changed, 19 insertions, 24 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 67433f2..d5b8f22 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -106,26 +106,12 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
MCDwarfFrameEmitter::Emit(*this, MAB, false);
}
-static bool canReuseDataFragment(const MCFragment &F,
- const MCAssembler &Assembler,
- const MCSubtargetInfo *STI) {
- if (!F.hasInstructions())
- return true;
- // Do not add data after a linker-relaxable instruction. The difference
- // between a new label and a label at or before the linker-relaxable
- // instruction cannot be resolved at assemble-time.
- if (F.isLinkerRelaxable())
- return false;
- // If the subtarget is changed mid fragment we start a new fragment to record
- // the new STI.
- return !STI || F.getSubtargetInfo() == STI;
-}
-
-MCFragment *
-MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
+MCFragment *MCObjectStreamer::getOrCreateDataFragment() {
+ // TODO: Start a new fragment whenever finalizing the variable-size tail of a
+ // previous one, so that all getOrCreateDataFragment calls can be replaced
+ // with getCurrentFragment
auto *F = getCurrentFragment();
- if (F->getKind() != MCFragment::FT_Data ||
- !canReuseDataFragment(*F, *Assembler, STI)) {
+ if (F->getKind() != MCFragment::FT_Data) {
F = getContext().allocFragment<MCFragment>();
insert(F);
}
@@ -363,16 +349,23 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
F->doneAppending();
if (!Fixups.empty())
F->appendFixups(Fixups);
+ F->setHasInstructions(STI);
+ bool MarkedLinkerRelaxable = false;
for (auto &Fixup : MutableArrayRef(F->getFixups()).slice(FixupStartIndex)) {
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
- if (Fixup.isLinkerRelaxable()) {
- F->setLinkerRelaxable();
+ if (!Fixup.isLinkerRelaxable())
+ continue;
+ F->setLinkerRelaxable();
+ // Do not add data after a linker-relaxable instruction. The difference
+ // between a new label and a label at or before the linker-relaxable
+ // instruction cannot be resolved at assemble-time.
+ if (!MarkedLinkerRelaxable) {
+ MarkedLinkerRelaxable = true;
getCurrentSectionOnly()->setLinkerRelaxable();
+ newFragment();
}
}
-
- F->setHasInstructions(STI);
}
void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
@@ -568,8 +561,10 @@ void MCObjectStreamer::emitCodeAlignment(Align Alignment,
// if the alignment is larger than the minimum NOP size.
unsigned Size;
if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F,
- Size))
+ Size)) {
getCurrentSectionOnly()->setLinkerRelaxable();
+ newFragment();
+ }
}
void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,