Skip to content

Commit 134f8a5

Browse files
MaskRayAlexisPerry
authored andcommitted
[MC] Remove pending labels
This commit removes the complexity introduced by pending labels in https://reviews.llvm.org/D5915 by using a simpler approach. D5915 aimed to ensure padding placement before `.Ltmp0` for the following code, but at the cost of expensive per-instruction `flushPendingLabels`. ``` // similar to llvm/test/MC/X86/AlignedBundling/labeloffset.s .bundle_lock align_to_end calll .L0$pb .bundle_unlock .L0$pb: popl %eax .Ltmp0: //// padding should be inserted before this label instead of after addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax ``` (D5915 was adjusted by https://reviews.llvm.org/D8072 and https://reviews.llvm.org/D71368) This patch achieves the same goal by setting the offset of the empty MCDataFragment (`Prev`) in `layoutBundle`. This eliminates the need for pending labels and simplifies the code. llvm/test/MC/MachO/pending-labels.s (D71368): relocation symbols are changed, but the result is still supported by linkers.
1 parent a9884a9 commit 134f8a5

File tree

8 files changed

+23
-157
lines changed

8 files changed

+23
-157
lines changed

llvm/include/llvm/MC/MCAsmLayout.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class MCAsmLayout {
4545
/// its bundle padding will be recomputed.
4646
void invalidateFragmentsFrom(MCFragment *F);
4747

48-
void layoutBundle(MCFragment *F);
48+
void layoutBundle(MCFragment *Prev, MCFragment *F);
4949

5050
/// \name Section Access (in layout order)
5151
/// @{

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ class MCObjectStreamer : public MCStreamer {
9191
MCFragment *getCurrentFragment() const;
9292

9393
void insert(MCFragment *F) {
94-
flushPendingLabels(F);
9594
MCSection *CurSection = getCurrentSectionOnly();
9695
CurSection->addFragment(*F);
9796
F->setParent(CurSection);
@@ -106,24 +105,15 @@ class MCObjectStreamer : public MCStreamer {
106105
protected:
107106
bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
108107

109-
/// Assign a label to the current Section and Subsection even though a
110-
/// fragment is not yet present. Use flushPendingLabels(F) to associate
111-
/// a fragment with this label.
112-
void addPendingLabel(MCSymbol* label);
113-
114108
/// If any labels have been emitted but not assigned fragments in the current
115109
/// Section and Subsection, ensure that they get assigned to fragment F.
116110
/// Optionally, one can provide an offset \p FOffset as a symbol offset within
117111
/// the fragment.
118-
void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
112+
void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0) {}
119113

120114
public:
121115
void visitUsedSymbol(const MCSymbol &Sym) override;
122116

123-
/// Create a data fragment for any pending labels across all Sections
124-
/// and Subsections.
125-
void flushPendingLabels();
126-
127117
MCAssembler &getAssembler() { return *Assembler; }
128118
MCAssembler *getAssemblerPtr() override;
129119
/// \name MCStreamer Interface

llvm/include/llvm/MC/MCSection.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,6 @@ class MCSection {
226226
/// Add a pending label for the requested subsection. This label will be
227227
/// associated with a fragment in flushPendingLabels()
228228
void addPendingLabel(MCSymbol* label, unsigned Subsection = 0);
229-
230-
/// Associate all pending labels in a subsection with a fragment.
231-
void flushPendingLabels(MCFragment *F, unsigned Subsection);
232-
233-
/// Associate all pending labels with empty data fragments. One fragment
234-
/// will be created for each subsection as necessary.
235-
void flushPendingLabels();
236229
};
237230

238231
} // end namespace llvm

llvm/lib/MC/MCAssembler.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
403403
llvm_unreachable("invalid fragment kind");
404404
}
405405

406-
void MCAsmLayout::layoutBundle(MCFragment *F) {
406+
void MCAsmLayout::layoutBundle(MCFragment *Prev, MCFragment *F) {
407407
// If bundling is enabled and this fragment has instructions in it, it has to
408408
// obey the bundling restrictions. With padding, we'll have:
409409
//
@@ -439,6 +439,9 @@ void MCAsmLayout::layoutBundle(MCFragment *F) {
439439
report_fatal_error("Padding cannot exceed 255 bytes");
440440
EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
441441
EF->Offset += RequiredBundlePadding;
442+
if (auto *DF = dyn_cast_or_null<MCDataFragment>(Prev))
443+
if (DF->getContents().empty())
444+
DF->Offset = EF->Offset;
442445
}
443446

444447
uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
@@ -451,14 +454,16 @@ void MCAsmLayout::ensureValid(const MCFragment *Frag) const {
451454
if (Sec.hasLayout())
452455
return;
453456
Sec.setHasLayout(true);
457+
MCFragment *Prev = nullptr;
454458
uint64_t Offset = 0;
455459
for (MCFragment &F : Sec) {
456460
F.Offset = Offset;
457461
if (Assembler.isBundlingEnabled() && F.hasInstructions()) {
458-
const_cast<MCAsmLayout *>(this)->layoutBundle(&F);
462+
const_cast<MCAsmLayout *>(this)->layoutBundle(Prev, &F);
459463
Offset = F.Offset;
460464
}
461465
Offset += getAssembler().computeFragmentSize(*this, F);
466+
Prev = &F;
462467
}
463468
}
464469

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 4 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -46,59 +46,6 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() {
4646
return nullptr;
4747
}
4848

49-
void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
50-
MCSection *CurSection = getCurrentSectionOnly();
51-
if (CurSection) {
52-
// Register labels that have not yet been assigned to a Section.
53-
if (!PendingLabels.empty()) {
54-
for (MCSymbol* Sym : PendingLabels)
55-
CurSection->addPendingLabel(Sym);
56-
PendingLabels.clear();
57-
}
58-
59-
// Add this label to the current Section / Subsection.
60-
CurSection->addPendingLabel(S, CurSubsectionIdx);
61-
62-
// Add this Section to the list of PendingLabelSections.
63-
PendingLabelSections.insert(CurSection);
64-
} else
65-
// There is no Section / Subsection for this label yet.
66-
PendingLabels.push_back(S);
67-
}
68-
69-
void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
70-
assert(F);
71-
MCSection *CurSection = getCurrentSectionOnly();
72-
if (!CurSection) {
73-
assert(PendingLabels.empty());
74-
return;
75-
}
76-
// Register labels that have not yet been assigned to a Section.
77-
if (!PendingLabels.empty()) {
78-
for (MCSymbol* Sym : PendingLabels)
79-
CurSection->addPendingLabel(Sym, CurSubsectionIdx);
80-
PendingLabels.clear();
81-
}
82-
83-
// Associate the labels with F.
84-
CurSection->flushPendingLabels(F, CurSubsectionIdx);
85-
}
86-
87-
void MCObjectStreamer::flushPendingLabels() {
88-
// Register labels that have not yet been assigned to a Section.
89-
if (!PendingLabels.empty()) {
90-
MCSection *CurSection = getCurrentSectionOnly();
91-
assert(CurSection);
92-
for (MCSymbol* Sym : PendingLabels)
93-
CurSection->addPendingLabel(Sym, CurSubsectionIdx);
94-
PendingLabels.clear();
95-
}
96-
97-
// Assign an empty data fragment to all remaining pending labels.
98-
for (MCSection* Section : PendingLabelSections)
99-
Section->flushPendingLabels();
100-
}
101-
10249
// When fixup's offset is a forward declared label, e.g.:
10350
//
10451
// .reloc 1f, R_MIPS_JALR, foo
@@ -113,7 +60,6 @@ void MCObjectStreamer::resolvePendingFixups() {
11360
"unresolved relocation offset");
11461
continue;
11562
}
116-
flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
11763
PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() +
11864
PendingFixup.Fixup.getOffset());
11965

@@ -245,7 +191,6 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
245191
SMLoc Loc) {
246192
MCStreamer::emitValueImpl(Value, Size, Loc);
247193
MCDataFragment *DF = getOrCreateDataFragment();
248-
flushPendingLabels(DF, DF->getContents().size());
249194

250195
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
251196

@@ -291,17 +236,9 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
291236
// If there is a current fragment, mark the symbol as pointing into it.
292237
// Otherwise queue the label and set its fragment pointer when we emit the
293238
// next fragment.
294-
auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
295-
if (F) {
296-
Symbol->setFragment(F);
297-
Symbol->setOffset(F->getContents().size());
298-
} else {
299-
// Assign all pending labels to offset 0 within the dummy "pending"
300-
// fragment. (They will all be reassigned to a real fragment in
301-
// flushPendingLabels())
302-
Symbol->setOffset(0);
303-
addPendingLabel(Symbol);
304-
}
239+
MCDataFragment *F = getOrCreateDataFragment();
240+
Symbol->setFragment(F);
241+
Symbol->setOffset(F->getContents().size());
305242

306243
emitPendingAssignments(Symbol);
307244
}
@@ -598,11 +535,9 @@ void MCObjectStreamer::emitCVInlineLinetableDirective(
598535
void MCObjectStreamer::emitCVDefRangeDirective(
599536
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
600537
StringRef FixedSizePortion) {
601-
MCFragment *Frag =
602-
getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
538+
getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
603539
// Attach labels that were pending before we created the defrange fragment to
604540
// the beginning of the new fragment.
605-
flushPendingLabels(Frag, 0);
606541
this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);
607542
}
608543

@@ -620,7 +555,6 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
620555
void MCObjectStreamer::emitBytes(StringRef Data) {
621556
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
622557
MCDataFragment *DF = getOrCreateDataFragment();
623-
flushPendingLabels(DF, DF->getContents().size());
624558
DF->getContents().append(Data.begin(), Data.end());
625559
}
626560

@@ -653,8 +587,6 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
653587
// Associate DTPRel32 fixup with data and resize data area
654588
void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
655589
MCDataFragment *DF = getOrCreateDataFragment();
656-
flushPendingLabels(DF, DF->getContents().size());
657-
658590
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
659591
Value, FK_DTPRel_4));
660592
DF->getContents().resize(DF->getContents().size() + 4, 0);
@@ -663,8 +595,6 @@ void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
663595
// Associate DTPRel64 fixup with data and resize data area
664596
void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
665597
MCDataFragment *DF = getOrCreateDataFragment();
666-
flushPendingLabels(DF, DF->getContents().size());
667-
668598
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
669599
Value, FK_DTPRel_8));
670600
DF->getContents().resize(DF->getContents().size() + 8, 0);
@@ -673,8 +603,6 @@ void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
673603
// Associate TPRel32 fixup with data and resize data area
674604
void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
675605
MCDataFragment *DF = getOrCreateDataFragment();
676-
flushPendingLabels(DF, DF->getContents().size());
677-
678606
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
679607
Value, FK_TPRel_4));
680608
DF->getContents().resize(DF->getContents().size() + 4, 0);
@@ -683,8 +611,6 @@ void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
683611
// Associate TPRel64 fixup with data and resize data area
684612
void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
685613
MCDataFragment *DF = getOrCreateDataFragment();
686-
flushPendingLabels(DF, DF->getContents().size());
687-
688614
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
689615
Value, FK_TPRel_8));
690616
DF->getContents().resize(DF->getContents().size() + 8, 0);
@@ -693,8 +619,6 @@ void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
693619
// Associate GPRel32 fixup with data and resize data area
694620
void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
695621
MCDataFragment *DF = getOrCreateDataFragment();
696-
flushPendingLabels(DF, DF->getContents().size());
697-
698622
DF->getFixups().push_back(
699623
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
700624
DF->getContents().resize(DF->getContents().size() + 4, 0);
@@ -703,8 +627,6 @@ void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
703627
// Associate GPRel64 fixup with data and resize data area
704628
void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
705629
MCDataFragment *DF = getOrCreateDataFragment();
706-
flushPendingLabels(DF, DF->getContents().size());
707-
708630
DF->getFixups().push_back(
709631
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
710632
DF->getContents().resize(DF->getContents().size() + 8, 0);
@@ -789,8 +711,6 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
789711
MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
790712

791713
MCDataFragment *DF = getOrCreateDataFragment(&STI);
792-
flushPendingLabels(DF, DF->getContents().size());
793-
794714
MCValue OffsetVal;
795715
if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
796716
return std::make_pair(false,
@@ -830,9 +750,6 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
830750

831751
void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
832752
SMLoc Loc) {
833-
MCDataFragment *DF = getOrCreateDataFragment();
834-
flushPendingLabels(DF, DF->getContents().size());
835-
836753
assert(getCurrentSectionOnly() && "need a section");
837754
insert(
838755
getContext().allocFragment<MCFillFragment>(FillValue, 1, NumBytes, Loc));
@@ -861,22 +778,14 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
861778
}
862779

863780
// Otherwise emit as fragment.
864-
MCDataFragment *DF = getOrCreateDataFragment();
865-
flushPendingLabels(DF, DF->getContents().size());
866-
867781
assert(getCurrentSectionOnly() && "need a section");
868782
insert(
869783
getContext().allocFragment<MCFillFragment>(Expr, Size, NumValues, Loc));
870784
}
871785

872786
void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
873787
SMLoc Loc, const MCSubtargetInfo &STI) {
874-
// Emit an NOP fragment.
875-
MCDataFragment *DF = getOrCreateDataFragment();
876-
flushPendingLabels(DF, DF->getContents().size());
877-
878788
assert(getCurrentSectionOnly() && "need a section");
879-
880789
insert(getContext().allocFragment<MCNopsFragment>(
881790
NumBytes, ControlledNopLength, Loc, STI));
882791
}
@@ -916,9 +825,6 @@ void MCObjectStreamer::finishImpl() {
916825
// Emit pseudo probes for the current module.
917826
MCPseudoProbeTable::emit(this);
918827

919-
// Update any remaining pending labels with empty data fragments.
920-
flushPendingLabels();
921-
922828
resolvePendingFixups();
923829
getAssembler().Finish();
924830
}

llvm/lib/MC/MCSection.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -80,33 +80,6 @@ void MCSection::switchSubsection(unsigned Subsection) {
8080
StringRef MCSection::getVirtualSectionKind() const { return "virtual"; }
8181

8282
void MCSection::addPendingLabel(MCSymbol *label, unsigned Subsection) {
83-
PendingLabels.push_back(PendingLabel(label, Subsection));
84-
}
85-
86-
void MCSection::flushPendingLabels(MCFragment *F, unsigned Subsection) {
87-
// Set the fragment and fragment offset for all pending symbols in the
88-
// specified Subsection, and remove those symbols from the pending list.
89-
for (auto It = PendingLabels.begin(); It != PendingLabels.end(); ++It) {
90-
PendingLabel& Label = *It;
91-
if (Label.Subsection == Subsection) {
92-
Label.Sym->setFragment(F);
93-
assert(Label.Sym->getOffset() == 0);
94-
PendingLabels.erase(It--);
95-
}
96-
}
97-
}
98-
99-
void MCSection::flushPendingLabels() {
100-
// Make sure all remaining pending labels point to data fragments, by
101-
// creating new empty data fragments for each Subsection with labels pending.
102-
while (!PendingLabels.empty()) {
103-
PendingLabel& Label = PendingLabels[0];
104-
switchSubsection(Label.Subsection);
105-
MCFragment *F = new MCDataFragment();
106-
addFragment(*F);
107-
F->setParent(this);
108-
flushPendingLabels(F, Label.Subsection);
109-
}
11083
}
11184

11285
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

llvm/test/MC/MachO/pending-labels.s

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ __data:
3232
.quad L8-.
3333
// CHECK: 0000000000000038 X86_64_RELOC_SUBTRACTOR _function1-__data
3434
// CHECK: 0000000000000038 X86_64_RELOC_UNSIGNED _function1
35-
// CHECK: 0000000000000030 X86_64_RELOC_SUBTRACTOR _function1-__data
36-
// CHECK: 0000000000000030 X86_64_RELOC_UNSIGNED _function1
35+
// CHECK: 0000000000000030 X86_64_RELOC_SUBTRACTOR __text-__data
36+
// CHECK: 0000000000000030 X86_64_RELOC_UNSIGNED __text
3737
// CHECK: 0000000000000028 X86_64_RELOC_SUBTRACTOR _function2-__data
3838
// CHECK: 0000000000000028 X86_64_RELOC_UNSIGNED _function2
3939
// CHECK: 0000000000000020 X86_64_RELOC_SUBTRACTOR _function2-__data
4040
// CHECK: 0000000000000020 X86_64_RELOC_UNSIGNED _function2
41-
// CHECK: 0000000000000018 X86_64_RELOC_SUBTRACTOR _function2-__data
42-
// CHECK: 0000000000000018 X86_64_RELOC_UNSIGNED _function2
43-
// CHECK: 0000000000000010 X86_64_RELOC_SUBTRACTOR _function1-__data
44-
// CHECK: 0000000000000010 X86_64_RELOC_UNSIGNED _function1
45-
// CHECK: 0000000000000008 X86_64_RELOC_SUBTRACTOR _function2-__data
46-
// CHECK: 0000000000000008 X86_64_RELOC_UNSIGNED _function2
47-
// CHECK: 0000000000000000 X86_64_RELOC_SUBTRACTOR _function1-__data
48-
// CHECK: 0000000000000000 X86_64_RELOC_UNSIGNED _function1
41+
// CHECK: 0000000000000018 X86_64_RELOC_SUBTRACTOR __text_cold-__data
42+
// CHECK: 0000000000000018 X86_64_RELOC_UNSIGNED __text_cold
43+
// CHECK: 0000000000000010 X86_64_RELOC_SUBTRACTOR __text-__data
44+
// CHECK: 0000000000000010 X86_64_RELOC_UNSIGNED __text
45+
// CHECK: 0000000000000008 X86_64_RELOC_SUBTRACTOR __text_cold-__data
46+
// CHECK: 0000000000000008 X86_64_RELOC_UNSIGNED __text_cold
47+
// CHECK: 0000000000000000 X86_64_RELOC_SUBTRACTOR __text-__data
48+
// CHECK: 0000000000000000 X86_64_RELOC_UNSIGNED __text

llvm/tools/dsymutil/MachOUtils.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ bool generateDsymCompanion(
381381
auto &Writer = static_cast<MachObjectWriter &>(MCAsm.getWriter());
382382

383383
// Layout but don't emit.
384-
ObjectStreamer.flushPendingLabels();
385384
MCAsmLayout Layout(MCAsm);
386385
MCAsm.layout(Layout);
387386

0 commit comments

Comments
 (0)