[llvm] 9f66ebe - MC: Eliminate redundant fragment relaxation
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 5 18:54:48 PDT 2025
Author: Fangrui Song
Date: 2025-07-05T18:54:43-07:00
New Revision: 9f66ebe427158a75a6392a94a66a0c50d21552bf
URL: https://github.com/llvm/llvm-project/commit/9f66ebe427158a75a6392a94a66a0c50d21552bf
DIFF: https://github.com/llvm/llvm-project/commit/9f66ebe427158a75a6392a94a66a0c50d21552bf.diff
LOG: MC: Eliminate redundant fragment relaxation
The relaxOnce function now returns the index of the last modified section,
allowing subsequent calls to skip already stable sections.
This optimization can often save redundant iteration for trailing
.debug_ sections, leading to minor instructions:u decrease.
https://llvm-compile-time-tracker.com/compare.php?from=aec88832df5e8c1dcbe259a6cb3d82d44b89ff23&to=8012fb16eff93cba48e5f08166762c5333bd1d42&stat=instructions:u
Added:
Modified:
llvm/include/llvm/MC/MCAssembler.h
llvm/lib/MC/MCAssembler.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index bfd6375ec5bcc..8261fd41a522b 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -113,9 +113,9 @@ class MCAssembler {
bool fragmentNeedsRelaxation(const MCRelaxableFragment &) const;
void layoutSection(MCSection &Sec);
- /// Perform one layout iteration and return true if any offsets
- /// were adjusted.
- bool relaxOnce();
+ /// Perform one layout iteration and return the index of the first stable
+ /// section for subsequent optimization.
+ unsigned relaxOnce(unsigned FirstStable);
/// Perform relaxation on a single fragment.
bool relaxFragment(MCFragment &F);
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 1dda4d8c1975e..ee82383afcb3d 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -795,7 +795,8 @@ void MCAssembler::layout() {
this->HasLayout = true;
for (MCSection &Sec : *this)
layoutSection(Sec);
- while (relaxOnce())
+ unsigned FirstStable = Sections.size();
+ while ((FirstStable = relaxOnce(FirstStable)) > 0)
if (getContext().hadError())
return;
@@ -1127,17 +1128,15 @@ void MCAssembler::layoutSection(MCSection &Sec) {
}
}
-bool MCAssembler::relaxOnce() {
+unsigned MCAssembler::relaxOnce(unsigned FirstStable) {
++stats::RelaxationSteps;
PendingErrors.clear();
- // Size of fragments in one section can depend on the size of fragments in
- // another. If any fragment has changed size, we have to re-layout (and
- // as a result possibly further relax) all sections.
- bool ChangedAny = false;
- for (MCSection &Sec : *this) {
+ unsigned Res = 0;
+ for (unsigned I = 0; I != FirstStable; ++I) {
// Assume each iteration finalizes at least one extra fragment. If the
// layout does not converge after N+1 iterations, bail out.
+ auto &Sec = *Sections[I];
auto MaxIter = Sec.curFragList()->Tail->getLayoutOrder() + 1;
for (;;) {
bool Changed = false;
@@ -1145,13 +1144,20 @@ bool MCAssembler::relaxOnce() {
if (relaxFragment(F))
Changed = true;
- ChangedAny |= Changed;
- if (!Changed || --MaxIter == 0)
+ if (!Changed)
+ break;
+ // If any fragment changed size, it might impact the layout of subsequent
+ // sections. Therefore, we must re-evaluate all sections.
+ FirstStable = Sections.size();
+ Res = I;
+ if (--MaxIter == 0)
break;
layoutSection(Sec);
}
}
- return ChangedAny;
+ // The subsequent relaxOnce call only needs to visit Sections [0,Res) if no
+ // change occurred.
+ return Res;
}
void MCAssembler::reportError(SMLoc L, const Twine &Msg) const {
More information about the llvm-commits
mailing list