diff options
author | Fangrui Song <i@maskray.me> | 2025-07-19 16:55:29 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2025-07-19 16:55:30 -0700 |
commit | 39c8cfb70d203439e3296dfdfe3d41f1cb2ec551 (patch) | |
tree | d5cc9405d2e382022f7a641b0bf7606a1e5262e2 /llvm/lib/MC/MCObjectStreamer.cpp | |
parent | 54492c231c5d9091d086bfb767423415ea6bd0bc (diff) | |
download | llvm-39c8cfb70d203439e3296dfdfe3d41f1cb2ec551.zip llvm-39c8cfb70d203439e3296dfdfe3d41f1cb2ec551.tar.gz llvm-39c8cfb70d203439e3296dfdfe3d41f1cb2ec551.tar.bz2 |
MC: Optimize getOrCreateDataFragment
... by eagerly allocating an empty fragment when adding a fragment
with a variable-size tail.
X86AsmBackend, The JCC erratum mitigation and x86-pad-for-align set a
flag for FT_Relaxable, which needs to be moved to emitInstructionBegin.
```
if (CF->getKind() == MCFragment::FT_Relaxable)
CF->setAllowAutoPadding(canPadInst(Inst, OS));
```
Follow-up to #148544
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index f61dda6..285c0f2 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -106,18 +106,6 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) { MCDwarfFrameEmitter::Emit(*this, MAB, false); } -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) { - F = getContext().allocFragment<MCFragment>(); - insert(F); - } - return F; -} - void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { Assembler->registerSymbol(Sym); } @@ -379,6 +367,7 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, F->setVarContents(Data); F->setVarFixups(Fixups); F->setInst(Inst); + newFragment(); } void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -444,6 +433,7 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, F->Kind = MCFragment::FT_Dwarf; F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc())); F->setDwarfLineDelta(LineDelta); + newFragment(); } void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, @@ -474,6 +464,7 @@ void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, auto *F = getOrCreateDataFragment(); F->Kind = MCFragment::FT_DwarfFrame; F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc)); + newFragment(); } void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, @@ -536,32 +527,38 @@ void MCObjectStreamer::emitBytes(StringRef Data) { DF->appendContents(ArrayRef(Data.data(), Data.size())); } -void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill, - uint8_t FillLen, - unsigned MaxBytesToEmit) { +MCAlignFragment *MCObjectStreamer::createAlignFragment( + Align Alignment, int64_t Fill, uint8_t FillLen, unsigned MaxBytesToEmit) { if (MaxBytesToEmit == 0) MaxBytesToEmit = Alignment.value(); - insert(getContext().allocFragment<MCAlignFragment>(Alignment, Fill, FillLen, - MaxBytesToEmit)); + return getContext().allocFragment<MCAlignFragment>(Alignment, Fill, FillLen, + MaxBytesToEmit); +} +void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill, + uint8_t FillLen, + unsigned MaxBytesToEmit) { + auto *F = createAlignFragment(Alignment, Fill, FillLen, MaxBytesToEmit); + insert(F); // Update the maximum alignment on the current section if necessary. - MCSection *CurSec = getCurrentSectionOnly(); - CurSec->ensureMinAlignment(Alignment); + F->getParent()->ensureMinAlignment(Alignment); } void MCObjectStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit) { - emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit); - auto *F = cast<MCAlignFragment>(getCurrentFragment()); + auto *F = createAlignFragment(Alignment, 0, 1, MaxBytesToEmit); F->setEmitNops(true, STI); + insert(F); + // Update the maximum alignment on the current section if necessary. + F->getParent()->ensureMinAlignment(Alignment); + // With RISC-V style linker relaxation, mark the section as linker-relaxable // if the alignment is larger than the minimum NOP size. unsigned Size; if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F, Size)) { - getCurrentSectionOnly()->setLinkerRelaxable(); - newFragment(); + F->getParent()->setLinkerRelaxable(); } } |