Skip to content

Commit 49f835c

Browse files
committed
[MC][ELF] Emit instructions directly into fragment
Avoid needless copying of instructions and fixups.
1 parent cc158d4 commit 49f835c

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

llvm/lib/MC/MCELFStreamer.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -549,12 +549,6 @@ static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
549549
void MCELFStreamer::emitInstToData(const MCInst &Inst,
550550
const MCSubtargetInfo &STI) {
551551
MCAssembler &Assembler = getAssembler();
552-
SmallVector<MCFixup, 4> Fixups;
553-
SmallString<256> Code;
554-
Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
555-
556-
for (auto &Fixup : Fixups)
557-
fixSymbolsInTLSFixups(Fixup.getValue());
558552

559553
// There are several possibilities here:
560554
//
@@ -573,7 +567,16 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
573567
// the group, though.
574568
MCDataFragment *DF;
575569

570+
// When bundling is enabled, we can't just append to the data fragment, as it
571+
// might need to be a MCCompactEncodedInstFragment for zero fixups.
576572
if (Assembler.isBundlingEnabled()) {
573+
SmallVector<MCFixup, 4> Fixups;
574+
SmallString<256> Code;
575+
Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
576+
577+
for (auto &Fixup : Fixups)
578+
fixSymbolsInTLSFixups(Fixup.getValue());
579+
577580
MCSection &Sec = *getCurrentSectionOnly();
578581
if (Assembler.getRelaxAll() && isBundleLocked()) {
579582
// If the -mc-relax-all flag is used and we are bundle-locked, we re-use
@@ -596,6 +599,9 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
596599
// Optimize memory usage by emitting the instruction to a
597600
// MCCompactEncodedInstFragment when not in a bundle-locked group and
598601
// there are no fixups registered.
602+
//
603+
// Apparently, this is not just a performance optimization? Using an
604+
// MCDataFragment at this point causes test failures.
599605
MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment();
600606
insert(CEIF);
601607
CEIF->getContents().append(Code.begin(), Code.end());
@@ -616,28 +622,44 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
616622
// We're now emitting an instruction in a bundle group, so this flag has
617623
// to be turned off.
618624
Sec.setBundleGroupBeforeFirstInst(false);
619-
} else {
620-
DF = getOrCreateDataFragment(&STI);
625+
626+
for (auto &Fixup : Fixups) {
627+
Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
628+
DF->getFixups().push_back(Fixup);
629+
}
630+
631+
DF->setHasInstructions(STI);
632+
if (!Fixups.empty() && Fixups.back().getTargetKind() ==
633+
getAssembler().getBackend().RelaxFixupKind)
634+
DF->setLinkerRelaxable();
635+
636+
DF->getContents().append(Code.begin(), Code.end());
637+
638+
if (Assembler.getRelaxAll() && !isBundleLocked()) {
639+
mergeFragment(getOrCreateDataFragment(&STI), DF);
640+
delete DF;
641+
}
642+
return;
621643
}
622644

623-
// Add the fixups and data.
645+
DF = getOrCreateDataFragment(&STI);
646+
647+
// Emit instruction directly into data fragment.
648+
size_t FixupStartIndex = DF->getFixups().size();
649+
size_t CodeOffset = DF->getContents().size();
650+
Assembler.getEmitter().encodeInstruction(Inst, DF->getContents(),
651+
DF->getFixups(), STI);
652+
653+
auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex);
624654
for (auto &Fixup : Fixups) {
625-
Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
626-
DF->getFixups().push_back(Fixup);
655+
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
656+
fixSymbolsInTLSFixups(Fixup.getValue());
627657
}
628658

629659
DF->setHasInstructions(STI);
630660
if (!Fixups.empty() && Fixups.back().getTargetKind() ==
631661
getAssembler().getBackend().RelaxFixupKind)
632662
DF->setLinkerRelaxable();
633-
DF->getContents().append(Code.begin(), Code.end());
634-
635-
if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
636-
if (!isBundleLocked()) {
637-
mergeFragment(getOrCreateDataFragment(&STI), DF);
638-
delete DF;
639-
}
640-
}
641663
}
642664

643665
void MCELFStreamer::emitBundleAlignMode(Align Alignment) {

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,10 +477,8 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
477477
MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
478478
insert(IF);
479479

480-
SmallString<128> Code;
481-
getAssembler().getEmitter().encodeInstruction(Inst, Code, IF->getFixups(),
482-
STI);
483-
IF->getContents().append(Code.begin(), Code.end());
480+
getAssembler().getEmitter().encodeInstruction(Inst, IF->getContents(),
481+
IF->getFixups(), STI);
484482
}
485483

486484
#ifndef NDEBUG

0 commit comments

Comments
 (0)