Skip to content

Commit 65b3b46

Browse files
committed
[MC][ELF] Emit instructions directly into fragment
Avoid needless copying of instructions and fixups.
1 parent 54f040f commit 65b3b46

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

llvm/lib/MC/MCELFStreamer.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,6 @@ static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
511511
void MCELFStreamer::emitInstToData(const MCInst &Inst,
512512
const MCSubtargetInfo &STI) {
513513
MCAssembler &Assembler = getAssembler();
514-
SmallVector<MCFixup, 4> Fixups;
515-
SmallString<256> Code;
516-
Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
517-
518-
for (auto &Fixup : Fixups)
519-
fixSymbolsInTLSFixups(Fixup.getValue());
520514

521515
// There are several possibilities here:
522516
//
@@ -535,7 +529,16 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
535529
// the group, though.
536530
MCDataFragment *DF;
537531

532+
// When bundling is enabled, we can't just append to the data fragment, as it
533+
// might need to be a MCCompactEncodedInstFragment for zero fixups.
538534
if (Assembler.isBundlingEnabled()) {
535+
SmallVector<MCFixup, 4> Fixups;
536+
SmallString<256> Code;
537+
Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
538+
539+
for (auto &Fixup : Fixups)
540+
fixSymbolsInTLSFixups(Fixup.getValue());
541+
539542
MCSection &Sec = *getCurrentSectionOnly();
540543
if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) {
541544
// If we are bundle-locked, we re-use the current fragment.
@@ -546,6 +549,9 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
546549
// Optimize memory usage by emitting the instruction to a
547550
// MCCompactEncodedInstFragment when not in a bundle-locked group and
548551
// there are no fixups registered.
552+
//
553+
// Apparently, this is not just a performance optimization? Using an
554+
// MCDataFragment at this point causes test failures.
549555
MCCompactEncodedInstFragment *CEIF =
550556
getContext().allocFragment<MCCompactEncodedInstFragment>();
551557
insert(CEIF);
@@ -567,21 +573,39 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
567573
// We're now emitting an instruction in a bundle group, so this flag has
568574
// to be turned off.
569575
Sec.setBundleGroupBeforeFirstInst(false);
570-
} else {
571-
DF = getOrCreateDataFragment(&STI);
576+
577+
for (auto &Fixup : Fixups) {
578+
Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
579+
DF->getFixups().push_back(Fixup);
580+
}
581+
582+
DF->setHasInstructions(STI);
583+
if (!Fixups.empty() && Fixups.back().getTargetKind() ==
584+
getAssembler().getBackend().RelaxFixupKind)
585+
DF->setLinkerRelaxable();
586+
587+
DF->getContents().append(Code.begin(), Code.end());
588+
return;
572589
}
573590

574-
// Add the fixups and data.
591+
DF = getOrCreateDataFragment(&STI);
592+
593+
// Emit instruction directly into data fragment.
594+
size_t FixupStartIndex = DF->getFixups().size();
595+
size_t CodeOffset = DF->getContents().size();
596+
Assembler.getEmitter().encodeInstruction(Inst, DF->getContents(),
597+
DF->getFixups(), STI);
598+
599+
auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex);
575600
for (auto &Fixup : Fixups) {
576-
Fixup.setOffset(Fixup.getOffset() + DF->getContents().size());
577-
DF->getFixups().push_back(Fixup);
601+
Fixup.setOffset(Fixup.getOffset() + CodeOffset);
602+
fixSymbolsInTLSFixups(Fixup.getValue());
578603
}
579604

580605
DF->setHasInstructions(STI);
581606
if (!Fixups.empty() && Fixups.back().getTargetKind() ==
582607
getAssembler().getBackend().RelaxFixupKind)
583608
DF->setLinkerRelaxable();
584-
DF->getContents().append(Code.begin(), Code.end());
585609
}
586610

587611
void MCELFStreamer::emitBundleAlignMode(Align Alignment) {

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,8 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
393393
getContext().allocFragment<MCRelaxableFragment>(Inst, STI);
394394
insert(IF);
395395

396-
SmallString<128> Code;
397-
getAssembler().getEmitter().encodeInstruction(Inst, Code, IF->getFixups(),
398-
STI);
399-
IF->getContents().append(Code.begin(), Code.end());
396+
getAssembler().getEmitter().encodeInstruction(Inst, IF->getContents(),
397+
IF->getFixups(), STI);
400398
}
401399

402400
#ifndef NDEBUG

llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ uint64_t SystemZMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNum,
172172
uint32_t BitOffset = MIBitSize - RawBitOffset - OpBitSize;
173173
Fixups.push_back(MCFixup::create(BitOffset >> 3, MO.getExpr(),
174174
(MCFixupKind)Kind, MI.getLoc()));
175-
assert(Fixups.size() <= 2 && "More than two memory operands in MI?");
176175
return 0;
177176
}
178177
llvm_unreachable("Unexpected operand type!");

0 commit comments

Comments
 (0)