Skip to content

Commit e28c393

Browse files
authored
[BOLT] Reduce the number of emitted symbols. NFCI. (llvm#70175)
We emit a symbol before an instruction for a number of reasons, e.g. for tracking LocSyms, debug line, or if the instruction has a label annotation. Currently, we may emit multiple symbols per instruction. Reuse the same label instead of creating and emitting new ones when possible. I'm planning to refactor EH labels as well in a separate diff. Change getLabel() to return a pointer instead of std::optional<> since an empty label should be treated identically to no label.
1 parent 565e21b commit e28c393

File tree

5 files changed

+43
-29
lines changed

5 files changed

+43
-29
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ class MCPlusBuilder {
11811181
bool clearOffset(MCInst &Inst);
11821182

11831183
/// Return the label of \p Inst, if available.
1184-
std::optional<MCSymbol *> getLabel(const MCInst &Inst) const;
1184+
MCSymbol *getLabel(const MCInst &Inst) const;
11851185

11861186
/// Set the label of \p Inst. This label will be emitted right before \p Inst
11871187
/// is emitted to MCStreamer.

bolt/lib/Core/BinaryContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,8 +1901,8 @@ void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
19011901
}
19021902
if (std::optional<uint32_t> Offset = MIB->getOffset(Instruction))
19031903
OS << " # Offset: " << *Offset;
1904-
if (auto Label = MIB->getLabel(Instruction))
1905-
OS << " # Label: " << **Label;
1904+
if (MCSymbol *Label = MIB->getLabel(Instruction))
1905+
OS << " # Label: " << *Label;
19061906

19071907
MIB->printAnnotations(Instruction, OS);
19081908

bolt/lib/Core/BinaryEmitter.cpp

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,17 @@ class BinaryEmitter {
161161
/// \p FirstInstr indicates if \p NewLoc represents the first instruction
162162
/// in a sequence, such as a function fragment.
163163
///
164+
/// If \p NewLoc location matches \p PrevLoc, no new line number entry will be
165+
/// created and the function will return \p PrevLoc while \p InstrLabel will
166+
/// be ignored. Otherwise, the caller should use \p InstrLabel to mark the
167+
/// corresponding instruction by emitting \p InstrLabel before it.
168+
/// If \p InstrLabel is set by the caller, its value will be used with \p
169+
/// \p NewLoc. If it was nullptr on entry, it will be populated with a pointer
170+
/// to a new temp symbol used with \p NewLoc.
171+
///
164172
/// Return new current location which is either \p NewLoc or \p PrevLoc.
165173
SMLoc emitLineInfo(const BinaryFunction &BF, SMLoc NewLoc, SMLoc PrevLoc,
166-
bool FirstInstr);
174+
bool FirstInstr, MCSymbol *&InstrLabel);
167175

168176
/// Use \p FunctionEndSymbol to mark the end of the line info sequence.
169177
/// Note that it does not automatically result in the insertion of the EOS
@@ -483,23 +491,28 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF,
483491
// are relaxable, we should be safe.
484492
}
485493

486-
if (!EmitCodeOnly && opts::UpdateDebugSections && BF.getDWARFUnit()) {
487-
LastLocSeen = emitLineInfo(BF, Instr.getLoc(), LastLocSeen, FirstInstr);
488-
FirstInstr = false;
489-
}
494+
if (!EmitCodeOnly) {
495+
// A symbol to be emitted before the instruction to mark its location.
496+
MCSymbol *InstrLabel = BC.MIB->getLabel(Instr);
490497

491-
// Prepare to tag this location with a label if we need to keep track of
492-
// the location of calls/returns for BOLT address translation maps
493-
if (!EmitCodeOnly && BF.requiresAddressTranslation() &&
494-
BC.MIB->getOffset(Instr)) {
495-
const uint32_t Offset = *BC.MIB->getOffset(Instr);
496-
MCSymbol *LocSym = BC.Ctx->createTempSymbol();
497-
Streamer.emitLabel(LocSym);
498-
BB->getLocSyms().emplace_back(Offset, LocSym);
499-
}
498+
if (opts::UpdateDebugSections && BF.getDWARFUnit()) {
499+
LastLocSeen = emitLineInfo(BF, Instr.getLoc(), LastLocSeen,
500+
FirstInstr, InstrLabel);
501+
FirstInstr = false;
502+
}
500503

501-
if (auto Label = BC.MIB->getLabel(Instr))
502-
Streamer.emitLabel(*Label);
504+
// Prepare to tag this location with a label if we need to keep track of
505+
// the location of calls/returns for BOLT address translation maps
506+
if (BF.requiresAddressTranslation() && BC.MIB->getOffset(Instr)) {
507+
const uint32_t Offset = *BC.MIB->getOffset(Instr);
508+
if (!InstrLabel)
509+
InstrLabel = BC.Ctx->createTempSymbol();
510+
BB->getLocSyms().emplace_back(Offset, InstrLabel);
511+
}
512+
513+
if (InstrLabel)
514+
Streamer.emitLabel(InstrLabel);
515+
}
503516

504517
Streamer.emitInstruction(Instr, *BC.STI);
505518
LastIsPrefix = BC.MIB->isPrefix(Instr);
@@ -661,7 +674,8 @@ void BinaryEmitter::emitConstantIslands(BinaryFunction &BF, bool EmitColdPart,
661674
}
662675

663676
SMLoc BinaryEmitter::emitLineInfo(const BinaryFunction &BF, SMLoc NewLoc,
664-
SMLoc PrevLoc, bool FirstInstr) {
677+
SMLoc PrevLoc, bool FirstInstr,
678+
MCSymbol *&InstrLabel) {
665679
DWARFUnit *FunctionCU = BF.getDWARFUnit();
666680
const DWARFDebugLine::LineTable *FunctionLineTable = BF.getDWARFLineTable();
667681
assert(FunctionCU && "cannot emit line info for function without CU");
@@ -711,12 +725,12 @@ SMLoc BinaryEmitter::emitLineInfo(const BinaryFunction &BF, SMLoc NewLoc,
711725
const MCDwarfLoc &DwarfLoc = BC.Ctx->getCurrentDwarfLoc();
712726
BC.Ctx->clearDwarfLocSeen();
713727

714-
MCSymbol *LineSym = BC.Ctx->createTempSymbol();
715-
Streamer.emitLabel(LineSym);
728+
if (!InstrLabel)
729+
InstrLabel = BC.Ctx->createTempSymbol();
716730

717731
BC.getDwarfLineTable(FunctionUnitIndex)
718732
.getMCLineSections()
719-
.addLineEntry(MCDwarfLineEntry(LineSym, DwarfLoc),
733+
.addLineEntry(MCDwarfLineEntry(InstrLabel, DwarfLoc),
720734
Streamer.getCurrentSectionOnly());
721735

722736
return NewLoc;

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ bool MCPlusBuilder::clearOffset(MCInst &Inst) {
268268
return true;
269269
}
270270

271-
std::optional<MCSymbol *> MCPlusBuilder::getLabel(const MCInst &Inst) const {
271+
MCSymbol *MCPlusBuilder::getLabel(const MCInst &Inst) const {
272272
if (auto Label = tryGetAnnotationAs<MCSymbol *>(Inst, MCAnnotation::kLabel))
273273
return *Label;
274-
return std::nullopt;
274+
return nullptr;
275275
}
276276

277277
bool MCPlusBuilder::setLabel(MCInst &Inst, MCSymbol *Label,

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,8 @@ void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
610610
if (BF.requiresAddressTranslation() && BC.MIB->getOffset(*II))
611611
PreservedOffsetAnnotations.emplace_back(&(*II),
612612
*BC.MIB->getOffset(*II));
613-
if (auto Label = BC.MIB->getLabel(*II))
614-
PreservedLabelAnnotations.emplace_back(&*II, *Label);
613+
if (MCSymbol *Label = BC.MIB->getLabel(*II))
614+
PreservedLabelAnnotations.emplace_back(&*II, Label);
615615
BC.MIB->stripAnnotations(*II);
616616
}
617617
}
@@ -620,8 +620,8 @@ void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
620620
for (BinaryFunction *BF : BC.getInjectedBinaryFunctions())
621621
for (BinaryBasicBlock &BB : *BF)
622622
for (MCInst &Instruction : BB) {
623-
if (auto Label = BC.MIB->getLabel(Instruction))
624-
PreservedLabelAnnotations.emplace_back(&Instruction, *Label);
623+
if (MCSymbol *Label = BC.MIB->getLabel(Instruction))
624+
PreservedLabelAnnotations.emplace_back(&Instruction, Label);
625625
BC.MIB->stripAnnotations(Instruction);
626626
}
627627

0 commit comments

Comments
 (0)